From: Greg Kroah-Hartman Date: Tue, 7 Apr 2026 07:48:11 +0000 (+0200) Subject: BUG/MEDIUM: chunk: fix infinite loop in get_larger_trash_chunk() X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=782a1b5888beba64f9532152acebc9a1e56e92ca;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: chunk: fix infinite loop in get_larger_trash_chunk() When the input chunk is already the large buffer (chk->size == large_trash_size), the <= comparison still matched and returned another large buffer of the same size. Callers that retry on a non-NULL return value (sample.c:4567 in json_query) loop forever. The json_query infinite loop is trivially triggered: mjson_unescape() returns -1 not only when the output buffer is too small but also for any \uXXYY escape where XX != "00" (mjson.c:305) and for invalid escapes like \q. The retry loop assumes -1 always means "grow the buffer", so a 14-byte JSON body of {"k":"\u0100"} hangs the worker thread permanently. Send N such requests to exhaust all worker threads. Use < instead of <= so a chunk that is already large yields NULL. This also fixes the json converter overflow at sample.c:2869 where no recheck happens after the "growth" returned a same-size buffer. Introduced in commit ce912271db4e ("MEDIUM: chunk: Add support for large chunks"). No backport needed. --- diff --git a/src/chunk.c b/src/chunk.c index e6d9a44a7..8d83409ad 100644 --- a/src/chunk.c +++ b/src/chunk.c @@ -170,7 +170,7 @@ struct buffer *get_larger_trash_chunk(struct buffer *chk) /* no chunk or a small one, use a regular buffer */ chunk = get_trash_chunk(); } - else if (large_trash_size && chk->size <= large_trash_size) { + else if (large_trash_size && chk->size < large_trash_size) { /* a regular byffer, use a large buffer if possible */ chunk = get_large_trash_chunk(); }