From 624979cf3bc3b30a8d0e2d959863345d9b8d2145 Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Fri, 4 Aug 2023 16:51:11 +0200 Subject: [PATCH] BUG/MAJOR: http-ana: Get a fresh trash buffer for each header value replacement When a "replace-header" action is used, we loop on all headers in the message to change value of all headers matching a name. The new value is placed in a trash. However, there is a race here because if the message must be defragmented, another trash is used. If several defragmentation are performed because several headers must be updated at same time, the first trash, used to store the new value, may be crushed. Indeed, there are only 2 pre-allocated trash used in rotation. and the trash to store the new value is never renewed. As consequece, random data may be inserted into the header value. Here, to fix the issue, we must take care to refresh the trash buffer when we evaluated a new header. This way, a trash used for the new value, and eventually another way for the htx defragmentation. But that's all. Thanks to Christian Ruppert for his detailed report. This patch must be to all stable versions. On the 2.0, the patch must be applied on src/proto_htx.c and the function is named htx_transform_header_str(). --- src/http_ana.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/http_ana.c b/src/http_ana.c index beee63c6c..6b2d7f0f3 100644 --- a/src/http_ana.c +++ b/src/http_ana.c @@ -2522,10 +2522,11 @@ int http_replace_hdrs(struct stream* s, struct htx *htx, struct ist name, const char *str, struct my_regex *re, int full) { struct http_hdr_ctx ctx; - struct buffer *output = get_trash_chunk(); ctx.blk = NULL; while (http_find_header(htx, name, &ctx, full)) { + struct buffer *output = get_trash_chunk(); + if (!regex_exec_match2(re, ctx.value.ptr, ctx.value.len, MAX_MATCH, pmatch, 0)) continue;