From: Remi Tricot-Le Breton Date: Thu, 6 Aug 2026 07:36:48 +0000 (+0200) Subject: BUG/MINOR: ssl: release the previous client cert reference at depth > 0 X-Git-Tag: v3.5-dev5~25 X-Git-Url: https://git.kaiwu.me/$%7BGITURL%7D/doc/static/gitweb.js?a=commitdiff_plain;h=998c8280d4b55db3895b55a41cd703beb28b7fe6;p=haproxy.git BUG/MINOR: ssl: release the previous client cert reference at depth > 0 The verify callback stores a reference to the client's certificate so that it can still be reported in logs when the verification fails. At depth 0 it correctly releases the reference that may have been stored by an earlier call before replacing it, but the depth > 0 branch, which does the same for chain certificates, overwrote the stored pointer without releasing it first. For deployments using "ca-ignore-err", a client presenting a chain that triggers more than one ignored CA-level error therefore leaks one X509 object per extra error, on every single handshake. Since the client fully controls the chain it presents and the rate at which it connects, memory grows without bound until the process is killed. Let's free the previous reference in that branch too, as the depth 0 branch does. This was introduced in 2.5 by commit 74f6ab6e8 ("MEDIUM: ssl: Keep a reference to the client's certificate for use in logs"). It must be backported to all stable versions. Reported-by: Claude (ANT-2026-6WW7AT7V) --- diff --git a/src/ssl_sock.c b/src/ssl_sock.c index eb6ca6cb9..4fcf0ab67 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -1816,9 +1816,15 @@ int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store) * reference right now. */ certs = X509_STORE_CTX_get1_chain(x_store); if (certs) { + X509 *prev_crt = client_crt; + client_crt = sk_X509_value(certs, 0); if (client_crt) { X509_up_ref(client_crt); + /* release the reference possibly stored by a + * previous call at another depth. + */ + X509_free(prev_crt); SSL_set_ex_data(ssl, ssl_client_crt_ref_index, client_crt); } sk_X509_pop_free(certs, X509_free);