From e64bccab20121beadb2ba862e48db294595d0546 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Mon, 28 Aug 2023 17:05:22 +0200 Subject: [PATCH] BUG/MINOR: stream: protect stream_dump() against incomplete streams If a stream is interrupted during its initialization by a panic signal and tries to dump itself, it may cause a crash during the dump due to scf and/or scb not being fully initialized. This may also happen while releasing an endpoint to attach a new one. The effect is that instead of dying on an abort, the process dies on a segv. This race is ultra- rare but totally possible. E.g: #0 se_fl_test (test=1, se=0x0) at include/haproxy/stconn.h:98 #1 sc_ep_test (test=1, sc=0x7ff8d5cbd560) at include/haproxy/stconn.h:148 #2 sc_conn (sc=0x7ff8d5cbd560) at include/haproxy/stconn.h:223 #3 stream_dump (buf=buf@entry=0x7ff9507e7678, s=0x7ff4c40c8800, pfx=pfx@entry=0x55996c558cb3 ' ' , eol=eol@entry=10 '\n') at src/stream.c:2840 #4 0x000055996c493b42 in ha_task_dump (buf=buf@entry=0x7ff9507e7678, task=, pfx=pfx@entry=0x55996c558cb3 ' ' ) at src/debug.c:328 #5 0x000055996c493edb in ha_thread_dump_one (thr=thr@entry=18, from_signal=from_signal@entry=0) at src/debug.c:227 #6 0x000055996c493ff1 in ha_thread_dump (buf=buf@entry=0x7ff9507e7678, thr=thr@entry=18) at src/debug.c:270 #7 0x000055996c494257 in ha_panic () at src/debug.c:430 #8 ha_panic () at src/debug.c:411 (...) #23 0x000055996c341fe8 in ssl_sock_close (conn=, xprt_ctx=0x7ff8dcae3880) at src/ssl_sock.c:6699 #24 0x000055996c397648 in conn_xprt_close (conn=0x7ff8c297b0c0) at include/haproxy/connection.h:148 #25 conn_full_close (conn=0x7ff8c297b0c0) at include/haproxy/connection.h:192 #26 h1_release (h1c=0x7ff8c297b3c0) at src/mux_h1.c:1074 #27 0x000055996c39c9f0 in h1_detach (sd=) at src/mux_h1.c:3502 #28 0x000055996c474de4 in sc_detach_endp (scp=scp@entry=0x7ff9507e3148) at src/stconn.c:375 #29 0x000055996c4752a5 in sc_reset_endp (sc=, sc@entry=0x7ff8d5cbd560) at src/stconn.c:475 Note that this cannot happen on "show sess" since a stream never leaves process_stream in such an uninitialized state, thus it's really only the crash dump that may cause this. It should be backported to 2.8. --- src/stream.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/stream.c b/src/stream.c index d3d029a5e79a0..e23cebb899ba0 100644 --- a/src/stream.c +++ b/src/stream.c @@ -2831,16 +2831,16 @@ void stream_dump(struct buffer *buf, const struct stream *s, const char *pfx, ch res = &s->res; scf = s->scf; - cof = sc_conn(scf); - acf = sc_appctx(scf); + cof = (scf && scf->sedesc) ? sc_conn(scf) : NULL; + acf = (scf && scf->sedesc) ? sc_appctx(scf) : NULL; if (cof && cof->src && addr_to_str(cof->src, pn, sizeof(pn)) >= 0) src = pn; else if (acf) src = acf->applet->name; scb = s->scb; - cob = sc_conn(scb); - acb = sc_appctx(scb); + cob = (scb && scb->sedesc) ? sc_conn(scb) : NULL; + acb = (scb && scb->sedesc) ? sc_appctx(scb) : NULL; srv = objt_server(s->target); if (srv) dst = srv->id;