]> git.kaiwu.me - haproxy.git/commit
BUG/MEDIUM: mux-h1: don't pass an upgraded connection to traces in h1s_destroy()
authorWilly Tarreau <w@1wt.eu>
Wed, 7 Oct 2026 03:43:46 +0000 (05:43 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 12 Oct 2026 12:31:04 +0000 (14:31 +0200)
commit8b70bf8a9b85647906f6b4d24c081bb937a614bf
treeac49655ad2d104ec7d2976c465bbfa4cc3d3b735
parent263ffb9aacb52913c1b3dee455acdaeee1c1ff02
BUG/MEDIUM: mux-h1: don't pass an upgraded connection to traces in h1s_destroy()

When an HTTP/1 frontend connection receives the HTTP/2 preface in two
parts, the first one (shorter than a full request) creates an h1s, then
the second one completes the preface and the connection is upgraded to
H2: h1_release() calls conn_upgrade_mux_fe(), h2_init() sets conn->ctx to
the new h2c, then h1_destroy() calls h1s_destroy(), which emits traces
with h1c->conn. h1_trace() and h1_trace_fill_ctx() then derive the h1c
from conn->ctx, which is now the h2c, and dereference it as an h1c,
crashing the worker. h1_release() already takes care of not using the
connection once it doesn't belong to the mux anymore, but h1s_destroy()
does not.

This only happens when h1 traces are enabled (level "state" or above),
and was reproduced with "-dt h1:state:minimal" and a client sending the
H2 preface in two segments split anywhere several ms apart. The process
then crashes in h1_trace().

The fix consists in only passing the connection to the traces in
h1s_destroy() when it still belongs to this h1c. The upgrade with an
existing h1s was made possible in 2.4 by commit 0f9395d81 ("BUG/MAJOR:
mux-h1: Properly handle TCP to H1 upgrades"), while the trace there comes
from commit 6b81df727 ("MINOR: mux-h1/trace: register a new trace source
with its events") in 2.1. This must be backported to all supported
versions.
src/mux_h1.c