From: Christopher Faulet Date: Wed, 7 Oct 2026 09:37:59 +0000 (+0200) Subject: BUG/MEDIUM: mux-h1: don't swap buffers when transferring data with a reserved offset X-Git-Tag: v3.5-dev10~143 X-Git-Url: https://git.kaiwu.me/$%7BISSUES%7D/static/gitweb.js?a=commitdiff_plain;h=53536fd53db064ba3e4107fa45d28aa3bd109143;p=haproxy.git BUG/MEDIUM: mux-h1: don't swap buffers when transferring data with a reserved offset In h1_nego_ff(), when the output is chunked, some room may be reserved to emit the chunk size later, in h1_done_ff(). However, when the producer's buffer is not empty, a first copy may be performed via the b_xfer() function. At this stage the buffers may be swapped while it is not expected. The reserved space may be moved and the head position lost. In practice, it is pretty hard to hit the bug. Now the data are always copied when room is reserved, using b_force_xfer(). b_xfer() is still used when no room is reserved. This was introduced by commit e8cc8a60b in 3.1 (backported to 3.0). It must be backported as far as 3.0. --- diff --git a/src/mux_h1.c b/src/mux_h1.c index dc50929e7..12eb43d89 100644 --- a/src/mux_h1.c +++ b/src/mux_h1.c @@ -5211,9 +5211,14 @@ static size_t h1_nego_ff(struct stconn *sc, struct buffer *input, size_t count, if (xfer > b_data(input)) xfer = b_data(input); - h1c->obuf.head += offset; - h1s->sd->iobuf.data = b_xfer(&h1c->obuf, input, xfer); - h1c->obuf.head -= offset; + if (offset) { + /* Room is reserved the chunk size, force the xfer to avoid any buffer swap */ + h1c->obuf.head += offset; + h1s->sd->iobuf.data = b_force_xfer(&h1c->obuf, input, xfer); + h1c->obuf.head -= offset; + } + else + h1s->sd->iobuf.data = b_xfer(&h1c->obuf, input, xfer); /* Cannot forward more data, wait for room */ if (b_data(input))