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().
(cherry picked from commit 624979cf3bc3b30a8d0e2d959863345d9b8d2145)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
(cherry picked from commit 80707f7765607083768a8f5a2a0b78e9a2f36af2)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
(cherry picked from commit 0a9d9bbf4ac24fcf97644edd57a0b586fd1ce022)
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
(cherry picked from commit 52301771f69cdaca463ee6f625ccefdc520844c1)
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/src/http_ana.c b/src/http_ana.c
index f265e93..b557da8 100644
--- a/src/http_ana.c
+++ b/src/http_ana.c
@@ -2700,10 +2700,11 @@
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;