From 1b15a89274716fbdc007460f7690c9ea39f8ddbe Mon Sep 17 00:00:00 2001 From: Ivan Koveshnikov Date: Tue, 31 Dec 2019 09:33:40 +0500 Subject: [PATCH] Update saver pointer ht after tfw_http_msg_grow_hdr_tbl() calls When tfw_http_msg_grow_hdr_tbl() is called it relocates the hm->ht, but all code around the call still uses the previous pointer. Thus changes are written to previous table, not current. --- tempesta_fw/http.c | 15 ++++++++++++--- tempesta_fw/http_msg.c | 8 ++++++-- tempesta_fw/t/unit/test_http_match.c | 9 +++------ 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/tempesta_fw/http.c b/tempesta_fw/http.c index 980e621d1..6e8a8c95a 100644 --- a/tempesta_fw/http.c +++ b/tempesta_fw/http.c @@ -2866,9 +2866,11 @@ __h2_req_hdrs(TfwHttpReq *req, const TfwStr *hdr, unsigned int hid, bool append) * to delete. */ return 0; - if (unlikely(hid == ht->size)) + if (unlikely(hid == ht->size)) { if (tfw_http_msg_grow_hdr_tbl(hm)) return -ENOMEM; + ht = hm->h_tbl; + } if (hid == ht->off) { /* * The raw header not found, but we have the new @@ -2971,7 +2973,7 @@ tfw_h2_adjust_req(TfwHttpReq *req) TfwHttpHdrTbl *ht = req->h_tbl; bool auth = !TFW_STR_EMPTY(&ht->tbl[TFW_HTTP_HDR_H2_AUTHORITY]); bool host = !TFW_STR_EMPTY(&ht->tbl[TFW_HTTP_HDR_HOST]); - size_t pseudo_num = auth ? 4 : 3; + size_t pseudo_num; TfwStr meth = {}, host_val = {}, *field, *end; struct sk_buff *new_head = NULL, *old_head = NULL; TfwMsgIter it; @@ -3038,7 +3040,14 @@ tfw_h2_adjust_req(TfwHttpReq *req) */ if ((r = tfw_h2_req_set_loc_hdrs(req))) return r; - + /* + * tfw_h2_req_set_loc_hdrs() may realloc header table and user may + * defined headers modifications, even headers we rely on, recheck them. + */ + ht = req->h_tbl; + auth = !TFW_STR_EMPTY(&ht->tbl[TFW_HTTP_HDR_H2_AUTHORITY]); + host = !TFW_STR_EMPTY(&ht->tbl[TFW_HTTP_HDR_HOST]); + pseudo_num = auth ? 4 : 3; /* * Calculate http1.1 headers size. H2 request contains pseudo headers * that are represented in different way in the http1.1 requests. diff --git a/tempesta_fw/http_msg.c b/tempesta_fw/http_msg.c index 748ecf7ce..44f8a4431 100644 --- a/tempesta_fw/http_msg.c +++ b/tempesta_fw/http_msg.c @@ -862,9 +862,11 @@ tfw_http_msg_hdr_xfrm_str(TfwHttpMsg *hm, const TfwStr *hdr, unsigned int hid, if (hid == ht->off && !s_val) /* Not found, nothing to delete. */ return 0; - if (hid == ht->size) + if (hid == ht->size) { if (tfw_http_msg_grow_hdr_tbl(hm)) return -ENOMEM; + ht = hm->h_tbl; + } if (hid == ht->off) ++ht->off; else @@ -1097,9 +1099,11 @@ tfw_http_msg_hdr_add(TfwHttpMsg *hm, const TfwStr *hdr) ht = hm->h_tbl; hid = ht->off; - if (hid == ht->size) + if (hid == ht->size) { if (tfw_http_msg_grow_hdr_tbl(hm)) return -ENOMEM; + ht = hm->h_tbl; + } ++ht->off; return __hdr_add(hm, hdr, hid); diff --git a/tempesta_fw/t/unit/test_http_match.c b/tempesta_fw/t/unit/test_http_match.c index d03820743..cf5bd6863 100644 --- a/tempesta_fw/t/unit/test_http_match.c +++ b/tempesta_fw/t/unit/test_http_match.c @@ -165,16 +165,13 @@ set_tfw_str(TfwStr *str, const char *cstr) static void set_raw_hdr(const char *cstr) { - unsigned int hid; - TfwHttpHdrTbl *h_tbl = test_req->h_tbl; + unsigned int hid = test_req->h_tbl->off; - hid = h_tbl->off; - - if (hid == h_tbl->size && + if (hid == test_req->h_tbl->size && tfw_http_msg_grow_hdr_tbl((TfwHttpMsg *)test_req)) return; - ++h_tbl->off; + ++test_req->h_tbl->off; set_tfw_str(&test_req->h_tbl->tbl[hid], cstr); }