From b65ce23cf15cd0e818a3b2e85745d07b54367f37 Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Sun, 30 Aug 2026 16:56:08 +0200 Subject: [PATCH] Possible use-after-free via aliased pointer in ticket-key HMAC Motivation: current_session_key/find_session_key copies tcn_ssl_ticket_key_t by value, but mac_params[0].data still points into the original heap array, not the copy. If setSessionTicketKeys0 frees/replaces the array concurrently after the read-lock is released but before EVP_MAC_CTX_set_params dereferences it, that's a use-after-free (not a plain NULL deref, but same crash class under concurrency). Modifications: Repoint to copy Result: No more use-after-free possible --- openssl-dynamic/src/main/c/sslcontext.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/openssl-dynamic/src/main/c/sslcontext.c b/openssl-dynamic/src/main/c/sslcontext.c index 9de4ad304..d49af7945 100644 --- a/openssl-dynamic/src/main/c/sslcontext.c +++ b/openssl-dynamic/src/main/c/sslcontext.c @@ -1308,6 +1308,11 @@ static int current_session_key(tcn_ssl_ctxt_t *c, tcn_ssl_ticket_key_t *key) { apr_thread_rwlock_rdlock(c->mutex); if (c->ticket_keys_len > 0) { *key = c->ticket_keys[0]; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + // mac_params[0].data still points into the original ticket_keys array; repoint it at + // this copy's own hmac_key so it stays valid after the array is freed/replaced. + key->mac_params[0].data = key->hmac_key; +#endif result = JNI_TRUE; } apr_thread_rwlock_unlock(c->mutex); @@ -1323,6 +1328,11 @@ static int find_session_key(tcn_ssl_ctxt_t *c, unsigned char key_name[16], tcn_s // Check if we have a match for tickets. if (memcmp(c->ticket_keys[i].key_name, key_name, 16) == 0) { *key = c->ticket_keys[i]; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + // mac_params[0].data still points into the original ticket_keys array; repoint it at + // this copy's own hmac_key so it stays valid after the array is freed/replaced. + key->mac_params[0].data = key->hmac_key; +#endif result = JNI_TRUE; *is_current_key = (i == 0); break;