From: Amaury Denoyelle Date: Wed, 28 Jan 2026 08:53:40 +0000 (+0100) Subject: BUG/MEDIUM: ssl: fix msg callbacks on QUIC connections X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=869a997a68a23ef235aaea16bc80dfb1801ec7ef;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: ssl: fix msg callbacks on QUIC connections With QUIC backend implementation, SSL code has been adjusted in several place when accessing connection instance. Indeed, with QUIC usage, SSL context is tied up to quic_conn, and code may be executed prior/after connection instantiation. For example, on frontend side, connection is only created after QUIC handshake completion. The following patch tried to fix unsafe accesses to connection. In particular, msg callbacks are not called anymore if connection is NULL. fab7da0fd0a67a9e7286839efca95ecdbf3a059e BUG/MEDIUM: quic-be/ssl_sock: TLS callback called without connection However, most msg callbacks do not need to use the connection instance. The only occurence where it is accessed is for heartbeat message parsing, which is the only case of crash solved. The above fix is too restrictive as it completely prevents execution of these callbacks when connection is unset. This breaks several features with QUIC, such as SSL key logging or samples based on ClientHello capture. The current patch reverts the above one. Thus, this restores invokation of msg callbacks for QUIC during the whole low-level connection lifetime. This requires a small adjustment in heartbeat parsing callback to prevent access on a NULL connection. The issue on ClientHello capture was mentionned in github issue #2495. This must be backported up to 3.3. --- diff --git a/src/ssl_sock.c b/src/ssl_sock.c index 27218e4a8..413f07a5e 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -1806,11 +1806,15 @@ static void ssl_sock_parse_heartbeat(struct connection *conn, int write_p, int v /* test heartbeat received (write_p is set to 0 for a received record) */ if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) { - struct ssl_sock_ctx *ctx = __conn_get_ssl_sock_ctx(conn); + struct ssl_sock_ctx *ctx = NULL; const unsigned char *p = buf; unsigned int payload; - ctx->xprt_st |= SSL_SOCK_RECV_HEARTBEAT; + /* may be NULL in QUIC context */ + if (conn) { + ctx = __conn_get_ssl_sock_ctx(conn); + ctx->xprt_st |= SSL_SOCK_RECV_HEARTBEAT; + } /* Check if this is a CVE-2014-0160 exploitation attempt. */ if (*p != TLS1_HB_REQUEST) @@ -2161,12 +2165,6 @@ static __maybe_unused void ssl_sock_msgcbk(int write_p, int version, int content struct connection *conn = ssl_sock_get_conn(ssl, NULL); struct ssl_sock_msg_callback *cbk; - /* The connection be NULL only for QUIC which does not free its SSL object - * as this done for TCP. - */ - if (!conn) - return; - /* Try to call all callback functions that were registered by using * ssl_sock_register_msg_callback(). */