exp_replace() returns int and returns -1 when the back-reference
expansion overflows the output buffer (regex.c:51). output->data is
size_t, so -1 becomes SIZE_MAX. There was no error check.

The subsequent comparisons interpret SIZE_MAX as a huge length:
"output->data > b_room(trash)" tries to grow trash, then
"max > output->data" is false so max stays at trash->size, and
memcpy(trash, output->area, trash->size) copies the full chunk.
output->area is a pool_alloc()'d chunk that is NOT zeroed; the
bytes after the partial exp_replace output are stale data from a
prior pool user (request headers, response bodies from the same
worker thread).

Trigger with a backreference whose expansion exceeds bufsize:

    http-request set-header X %[req.hdr(In),regsub('(.+)','\1\1')]

and a request with In: of ~9000 bytes. The X header sent to the
backend then contains ~9KB of stale heap data.

With tune.bufsize.large set, get_larger_trash_chunk() upgrades trash
and the memcpy reads up to ~50KB past the (smaller) output->area
allocation.

http_ana.c:2728 and http_act.c:551 already check exp_replace() for
-1; this call site was missed when backreferences were added.
---
 src/sample.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/src/sample.c b/src/sample.c
index 42f211ad4af6..28a039584f9c 100644
--- a/src/sample.c
+++ b/src/sample.c
@@ -3300,7 +3300,12 @@ static int sample_conv_regsub(const struct arg *arg_p, 
struct sample *smp, void
                if (!output)
                        break;
 
-               output->data = exp_replace(output->area, output->size, start, 
arg_p[1].data.str.area, pmatch);
+               max = exp_replace(output->area, output->size, start, 
arg_p[1].data.str.area, pmatch);
+               if ((int)max < 0) {
+                       free_trash_chunk(output);
+                       break;
+               }
+               output->data = max;
 
                /* If too many data to copy try to get a larger chunk */
                if (output->data > b_room(trash)) {
-- 
2.53.0



Reply via email to