When an outgoing rhttp connection to an rhttp gateway fails, h2_wake()
releases the connection but returns continues to return ret >= 0, making
its caller (sock_conn_iocb() here or the SSL handshake code) continue to
dereference the connection to read conn->flags for example. This is
visible when running with -dMuaf that instantly causes a use-after-free
on a small config like this one:
frontend fe
bind "rhttp@be-outgoing/gateway"
backend be-outgoing
server gateway 127.0.0.1:1 proto h2
Starting this config is sufficient to make the frontend trigger pre-
connectionns on the backend and cause a crash:
(gdb) bt
#0 sock_conn_iocb (fd=<optimized out>) at src/sock.c:1168
#1 0x0000000000836265 in fd_update_events (fd=<optimized out>, evts=<optimized out>) at src/fd.c:793
#2 0x000000000051c564 in _do_poll (p=<optimized out>, exp=<optimized out>, wake=<optimized out>) at src/ev_epoll.c:345
#3 0x0000000000784c3f in run_poll_loop () at src/haproxy.c:3148
#4 0x000000000078537f in run_thread_poll_loop (data=<optimized out>) at src/haproxy.c:3296
#5 0x00000000004b5a75 in main (argc=<optimized out>, argv=0x7ffe5682d7a8) at src/haproxy.c:4112
This was introduced in 2.9 by commit
5053e8914 ("MEDIUM: h2: prevent
stream opening before connection reverse completed") so the fix must
be backported to 3.0. Note that this is an experimental feature.