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.