]> git.kaiwu.me - haproxy.git/commit
BUG/MINOR: http-act: fix a double free of the regex on a rule parsing error
authorWilly Tarreau <w@1wt.eu>
Mon, 27 Jul 2026 09:40:52 +0000 (11:40 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 27 Jul 2026 13:30:43 +0000 (15:30 +0200)
commit6a8b544178b927a456472c9b772fe8b3220bf42a
tree2d9e709f37350e4e688a33b59577ac351e30f8a8
parent975961d5ca26df931dcc2816b7e5ec56abd655ad
BUG/MINOR: http-act: fix a double free of the regex on a rule parsing error

parse_replace_uri() and parse_http_replace_header() compile their regex into
<rule->arg.http.re>, and when the log-format argument that follows fails to
parse they release it before reporting the error:

if (!parse_logformat_string(args[cur_arg + 1], px, &rule->arg.http.fmt, ...)) {
regex_free(rule->arg.http.re);
return ACT_RET_PRS_ERR;
}

The pointer is left dangling in the rule while <rule->release_ptr> has already
been set to release_http_action(), which does exactly the same:

if (rule->arg.http.re)
regex_free(rule->arg.http.re);

On ACT_RET_PRS_ERR the caller (parse_http_req_cond() & friends) calls
free_act_rule(), which invokes release_ptr, so regex_free() runs twice on the
same object. It ends up calling regfree()/pcre*_free() on freed memory and
free() on an already freed pointer.

It is easily reproduced with:

http-request replace-uri     ^/foo   /bar%[nosuchfetch]
http-request replace-header  X-Foo ^a b%[nosuchfetch]

Both abort under MALLOC_CHECK_=3, and the second one even segfaults with the
libc regex backend, so "haproxy -c" dies instead of reporting the configuration
error (and the remaining errors of the file are never reported).

This only happens on an invalid configuration during parsing, so it has no
security impact, but a configuration checker must not crash.

Let's reset the pointer after releasing it, as done for <arg.http_reply> in
release_act_http_reply().

This should be backported to all supported versions.
src/http_act.c