]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Fix error handling in SSL_CTX_add_session
authorBernd Edlinger <bernd.edlinger@hotmail.de>
Mon, 22 Sep 2025 14:23:47 +0000 (16:23 +0200)
committerNeil Horman <nhorman@openssl.org>
Thu, 12 Mar 2026 17:53:28 +0000 (13:53 -0400)
An out-of-memory error in lh_SSL_SESSION_insert
could trigger various use-after-free errors.

Fixes #28632

Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org>
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
Reviewed-by: Neil Horman <nhorman@openssl.org>
MergeDate: Thu Mar 12 17:51:38 2026
(Merged from https://github.com/openssl/openssl/pull/28636)

(cherry picked from commit 0a72e6ae74a6d32977ac53cbf314f414c08b327b)

ssl/ssl_sess.c
test/sslapitest.c

index b911d6cffbd8275a477ac26b9d2a7e4799052105..82d5d7435256f6ae4382bf6ef044c009255ec548 100644 (file)
@@ -788,9 +788,9 @@ int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c)
                     ssl_tsan_counter(ctx, &ctx->stats.sess_cache_full);
             }
         }
-    }
 
-    SSL_SESSION_list_add(ctx, c);
+        SSL_SESSION_list_add(ctx, c);
+    }
 
     if (s != NULL) {
         /*
index f708b8a9c46149b68abbd9134a65b3e90b54fded..f93c58ef7ca635017dd1599bb282fc32124874d1 100644 (file)
@@ -10227,6 +10227,7 @@ static int test_session_cache_overflow(int idx)
     SSL *serverssl = NULL, *clientssl = NULL;
     int testresult = 0;
     SSL_SESSION *sess = NULL;
+    int references;
 
 #ifdef OSSL_NO_USABLE_TLS1_3
     /* If no TLSv1.3 available then do nothing in this case */
@@ -10300,6 +10301,15 @@ static int test_session_cache_overflow(int idx)
     get_sess_val = SSL_get_session(serverssl);
     if (!TEST_ptr(get_sess_val))
         goto end;
+    /*
+     * Normally the session is also stored in the cache, thus we have more than
+     * one reference, but due to an out-of-memory error it can happen that this
+     * is the only reference, and in that case the SSL_free(serverssl) below
+     * would free the get_sess_val, causing a use-after-free error.
+     */
+    if (!TEST_true(CRYPTO_GET_REF(&get_sess_val->references, &references))
+            || !TEST_int_ge(references, 2))
+        goto end;
     sess = SSL_get1_session(clientssl);
     if (!TEST_ptr(sess))
         goto end;