]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: stream: protect stream_dump() against incomplete streams
authorWilly Tarreau <w@1wt.eu>
Mon, 28 Aug 2023 15:05:22 +0000 (17:05 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 29 Aug 2023 09:11:50 +0000 (11:11 +0200)
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 ' ' <repeats 13 times>, eol=eol@entry=10 '\n') at src/stream.c:2840
  #4  0x000055996c493b42 in ha_task_dump (buf=buf@entry=0x7ff9507e7678, task=<optimized out>, pfx=pfx@entry=0x55996c558cb3 ' ' <repeats 13 times>) 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=<optimized out>, 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=<optimized out>) 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=<optimized out>, 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

index d3d029a5e79a0f01b1d4e4e28a6a69ec20eb4823..e23cebb899ba00c706bbb46e64ef5976802bcf3f 100644 (file)
@@ -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;