fix CVE-2024-2511

Signed-off-by: ShenYage <shenyage1@huawei.com>
This commit is contained in:
ShenYage 2024-04-15 22:04:19 +08:00
parent 7f28dc628e
commit 9aaafd9bf8
6 changed files with 703 additions and 1 deletions

View File

@ -0,0 +1,173 @@
From 6891715994ab7f5df8f5a2a10d743a24265d0c53 Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Tue, 5 Mar 2024 15:43:53 +0000
Subject: [PATCH 1/5] Fix unconstrained session cache growth in TLSv1.3
In TLSv1.3 we create a new session object for each ticket that we send.
We do this by duplicating the original session. If SSL_OP_NO_TICKET is in
use then the new session will be added to the session cache. However, if
early data is not in use (and therefore anti-replay protection is being
used), then multiple threads could be resuming from the same session
simultaneously. If this happens and a problem occurs on one of the threads,
then the original session object could be marked as not_resumable. When we
duplicate the session object this not_resumable status gets copied into the
new session object. The new session object is then added to the session
cache even though it is not_resumable.
Subsequently, another bug means that the session_id_length is set to 0 for
sessions that are marked as not_resumable - even though that session is
still in the cache. Once this happens the session can never be removed from
the cache. When that object gets to be the session cache tail object the
cache never shrinks again and grows indefinitely.
CVE-2024-2511
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24044)
(cherry picked from commit 7e4d731b1c07201ad9374c1cd9ac5263bdf35bce)
Signed-off-by: Liu-Ermeng <liuermeng2@huawei.com>
---
.../openssl/include/openssl/sslerr.h | 4 +--
.../Library/OpensslLib/openssl/ssl/ssl_err.c | 5 ++--
.../Library/OpensslLib/openssl/ssl/ssl_lib.c | 5 ++--
.../Library/OpensslLib/openssl/ssl/ssl_sess.c | 30 ++++++++++++++-----
.../openssl/ssl/statem/statem_srvr.c | 5 ++--
5 files changed, 33 insertions(+), 16 deletions(-)
diff --git a/CryptoPkg/Library/OpensslLib/openssl/include/openssl/sslerr.h b/CryptoPkg/Library/OpensslLib/openssl/include/openssl/sslerr.h
index 82983d3..a3a6f03 100644
--- a/CryptoPkg/Library/OpensslLib/openssl/include/openssl/sslerr.h
+++ b/CryptoPkg/Library/OpensslLib/openssl/include/openssl/sslerr.h
@@ -1,6 +1,6 @@
/*
* Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -219,7 +219,7 @@ int ERR_load_SSL_strings(void);
# define SSL_F_SSL_RENEGOTIATE_ABBREVIATED 546
# define SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT 320
# define SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT 321
-# define SSL_F_SSL_SESSION_DUP 348
+# define SSL_F_SSL_SESSION_DUP_INTERN 668
# define SSL_F_SSL_SESSION_NEW 189
# define SSL_F_SSL_SESSION_PRINT_FP 190
# define SSL_F_SSL_SESSION_SET1_ID 423
diff --git a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_err.c b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_err.c
index 4b12ed1..31435d6 100644
--- a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_err.c
+++ b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_err.c
@@ -1,6 +1,6 @@
/*
* Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -312,7 +312,8 @@ static const ERR_STRING_DATA SSL_str_functs[] = {
"SSL_renegotiate_abbreviated"},
{ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT, 0), ""},
{ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT, 0), ""},
- {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SESSION_DUP, 0), "ssl_session_dup"},
+ {ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SESSION_DUP_INTERN, 0),
+ "ssl_session_dup_intern"},
{ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SESSION_NEW, 0), "SSL_SESSION_new"},
{ERR_PACK(ERR_LIB_SSL, SSL_F_SSL_SESSION_PRINT_FP, 0),
"SSL_SESSION_print_fp"},
diff --git a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_lib.c b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_lib.c
index 7c7e597..ae33d18 100644
--- a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_lib.c
+++ b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_lib.c
@@ -3445,9 +3445,10 @@ void ssl_update_cache(SSL *s, int mode)
/*
* If the session_id_length is 0, we are not supposed to cache it, and it
- * would be rather hard to do anyway :-)
+ * would be rather hard to do anyway :-). Also if the session has already
+ * been marked as not_resumable we should not cache it for later reuse.
*/
- if (s->session->session_id_length == 0)
+ if (s->session->session_id_length == 0 || s->session->not_resumable)
return;
/*
diff --git a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c
index 40c157b..4e87220 100644
--- a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c
+++ b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c
@@ -94,16 +94,11 @@ SSL_SESSION *SSL_SESSION_new(void)
return ss;
}
-SSL_SESSION *SSL_SESSION_dup(SSL_SESSION *src)
-{
- return ssl_session_dup(src, 1);
-}
-
/*
* Create a new SSL_SESSION and duplicate the contents of |src| into it. If
* ticket == 0 then no ticket information is duplicated, otherwise it is.
*/
-SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket)
+static SSL_SESSION *ssl_session_dup_intern(SSL_SESSION *src, int ticket)
{
SSL_SESSION *dest;
@@ -218,11 +213,32 @@ SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket)
return dest;
err:
- SSLerr(SSL_F_SSL_SESSION_DUP, ERR_R_MALLOC_FAILURE);
+ SSLerr(SSL_F_SSL_SESSION_DUP_INTERN, ERR_R_MALLOC_FAILURE);
SSL_SESSION_free(dest);
return NULL;
}
+SSL_SESSION *SSL_SESSION_dup(SSL_SESSION *src)
+{
+ return ssl_session_dup_intern(src, 1);
+}
+
+/*
+ * Used internally when duplicating a session which might be already shared.
+ * We will have resumed the original session. Subsequently we might have marked
+ * it as non-resumable (e.g. in another thread) - but this copy should be ok to
+ * resume from.
+ */
+SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket)
+{
+ SSL_SESSION *sess = ssl_session_dup_intern(src, ticket);
+
+ if (sess != NULL)
+ sess->not_resumable = 0;
+
+ return sess;
+}
+
const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len)
{
if (len)
diff --git a/CryptoPkg/Library/OpensslLib/openssl/ssl/statem/statem_srvr.c b/CryptoPkg/Library/OpensslLib/openssl/ssl/statem/statem_srvr.c
index 14cb27e..679855a 100644
--- a/CryptoPkg/Library/OpensslLib/openssl/ssl/statem/statem_srvr.c
+++ b/CryptoPkg/Library/OpensslLib/openssl/ssl/statem/statem_srvr.c
@@ -2402,9 +2402,8 @@ int tls_construct_server_hello(SSL *s, WPACKET *pkt)
* so the following won't overwrite an ID that we're supposed
* to send back.
*/
- if (s->session->not_resumable ||
- (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER)
- && !s->hit))
+ if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER)
+ && !s->hit)
s->session->session_id_length = 0;
if (usetls13) {
--
2.33.0

View File

@ -0,0 +1,133 @@
From 2977116cff409b22ded747f532f7d72b2684da81 Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Mon, 4 Mar 2024 13:45:23 +0000
Subject: [PATCH 2/5] Add a test for session cache handling
Repeatedly create sessions to be added to the cache and ensure we never
exceed the expected size.
Related to CVE-2024-2511
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24044)
(cherry picked from commit 5f5b9e1ca1fad0215f623b8bd4955a2e8101f306)
Signed-off-by: Liu-Ermeng <liuermeng2@huawei.com>
---
.../OpensslLib/openssl/test/sslapitest.c | 92 +++++++++++++++++++
1 file changed, 92 insertions(+)
diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c b/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c
index 5c11810..89f718f 100644
--- a/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c
+++ b/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c
@@ -6471,6 +6471,97 @@ static int test_servername(int tst)
return testresult;
}
+/*
+ * Test multiple resumptions and cache size handling
+ * Test 0: TLSv1.3 (max_early_data set)
+ * Test 1: TLSv1.3 (SSL_OP_NO_TICKET set)
+ * Test 2: TLSv1.3 (max_early_data and SSL_OP_NO_TICKET set)
+ * Test 3: TLSv1.2
+ */
+static int test_multi_resume(int idx)
+{
+ SSL_CTX *sctx = NULL, *cctx = NULL;
+ SSL *serverssl = NULL, *clientssl = NULL;
+ SSL_SESSION *sess = NULL;
+ int max_version = TLS1_3_VERSION;
+ int i, testresult = 0;
+
+ if (idx == 3)
+ max_version = TLS1_2_VERSION;
+
+ if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(),
+ TLS_client_method(), TLS1_VERSION,
+ max_version, &sctx, &cctx, cert,
+ privkey)))
+ goto end;
+
+ /*
+ * TLSv1.3 only uses a session cache if either max_early_data > 0 (used for
+ * replay protection), or if SSL_OP_NO_TICKET is in use
+ */
+ if (idx == 0 || idx == 2) {
+ if (!TEST_true(SSL_CTX_set_max_early_data(sctx, 1024)))
+ goto end;
+ }
+ if (idx == 1 || idx == 2)
+ SSL_CTX_set_options(sctx, SSL_OP_NO_TICKET);
+
+ SSL_CTX_sess_set_cache_size(sctx, 5);
+
+ for (i = 0; i < 30; i++) {
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
+ NULL, NULL))
+ || !TEST_true(SSL_set_session(clientssl, sess)))
+ goto end;
+
+ /*
+ * Recreate a bug where dynamically changing the max_early_data value
+ * can cause sessions in the session cache which cannot be deleted.
+ */
+ if ((idx == 0 || idx == 2) && (i % 3) == 2)
+ SSL_set_max_early_data(serverssl, 0);
+
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
+ goto end;
+
+ if (sess == NULL || (idx == 0 && (i % 3) == 2)) {
+ if (!TEST_false(SSL_session_reused(clientssl)))
+ goto end;
+ } else {
+ if (!TEST_true(SSL_session_reused(clientssl)))
+ goto end;
+ }
+ SSL_SESSION_free(sess);
+
+ /* Do a full handshake, followed by two resumptions */
+ if ((i % 3) == 2) {
+ sess = NULL;
+ } else {
+ if (!TEST_ptr((sess = SSL_get1_session(clientssl))))
+ goto end;
+ }
+
+ SSL_shutdown(clientssl);
+ SSL_shutdown(serverssl);
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ serverssl = clientssl = NULL;
+ }
+
+ /* We should never exceed the session cache size limit */
+ if (!TEST_long_le(SSL_CTX_sess_number(sctx), 5))
+ goto end;
+
+ testresult = 1;
+ end:
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ SSL_CTX_free(sctx);
+ SSL_CTX_free(cctx);
+ SSL_SESSION_free(sess);
+ return testresult;
+}
+
int setup_tests(void)
{
if (!TEST_ptr(certsdir = test_get_argument(0))
@@ -6590,6 +6681,7 @@ int setup_tests(void)
ADD_ALL_TESTS(test_client_cert_cb, 2);
ADD_ALL_TESTS(test_ca_names, 3);
ADD_ALL_TESTS(test_servername, 10);
+ ADD_ALL_TESTS(test_multi_resume, 4);
return 1;
}
--
2.33.0

View File

@ -0,0 +1,161 @@
From 987232cacc779a7df4cf0ddb77b71814c96af16b Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Tue, 5 Mar 2024 15:35:51 +0000
Subject: [PATCH 3/5] Extend the multi_resume test for simultaneous resumptions
Test what happens if the same session gets resumed multiple times at the
same time - and one of them gets marked as not_resumable.
Related to CVE-2024-2511
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24044)
(cherry picked from commit 031b11a4054c972a5e2f07dfa81ce1842453253e)
Signed-off-by: Liu-Ermeng <liuermeng2@huawei.com>
---
.../OpensslLib/openssl/test/sslapitest.c | 89 ++++++++++++++++++-
1 file changed, 85 insertions(+), 4 deletions(-)
diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c b/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c
index 89f718f..86f746c 100644
--- a/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c
+++ b/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c
@@ -6471,12 +6471,63 @@ static int test_servername(int tst)
return testresult;
}
+struct resume_servername_cb_data {
+ int i;
+ SSL_CTX *cctx;
+ SSL_CTX *sctx;
+ SSL_SESSION *sess;
+ int recurse;
+};
+
+/*
+ * Servername callback. We use it here to run another complete handshake using
+ * the same session - and mark the session as not_resuamble at the end
+ */
+static int resume_servername_cb(SSL *s, int *ad, void *arg)
+{
+ struct resume_servername_cb_data *cbdata = arg;
+ SSL *serverssl = NULL, *clientssl = NULL;
+ int ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+
+ if (cbdata->recurse)
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
+
+ if ((cbdata->i % 3) != 1)
+ return SSL_TLSEXT_ERR_OK;
+
+ cbdata->recurse = 1;
+
+ if (!TEST_true(create_ssl_objects(cbdata->sctx, cbdata->cctx, &serverssl,
+ &clientssl, NULL, NULL))
+ || !TEST_true(SSL_set_session(clientssl, cbdata->sess)))
+ goto end;
+
+ ERR_set_mark();
+ /*
+ * We expect this to fail - because the servername cb will fail. This will
+ * mark the session as not_resumable.
+ */
+ if (!TEST_false(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) {
+ ERR_clear_last_mark();
+ goto end;
+ }
+ ERR_pop_to_mark();
+
+ ret = SSL_TLSEXT_ERR_OK;
+ end:
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ cbdata->recurse = 0;
+ return ret;
+}
+
/*
* Test multiple resumptions and cache size handling
* Test 0: TLSv1.3 (max_early_data set)
* Test 1: TLSv1.3 (SSL_OP_NO_TICKET set)
* Test 2: TLSv1.3 (max_early_data and SSL_OP_NO_TICKET set)
- * Test 3: TLSv1.2
+ * Test 3: TLSv1.3 (SSL_OP_NO_TICKET, simultaneous resumes)
+ * Test 4: TLSv1.2
*/
static int test_multi_resume(int idx)
{
@@ -6485,9 +6536,19 @@ static int test_multi_resume(int idx)
SSL_SESSION *sess = NULL;
int max_version = TLS1_3_VERSION;
int i, testresult = 0;
+ struct resume_servername_cb_data cbdata;
- if (idx == 3)
+#if defined(OPENSSL_NO_TLS1_2)
+ if (idx == 4)
+ return TEST_skip("TLSv1.2 is disabled in this build");
+#else
+ if (idx == 4)
max_version = TLS1_2_VERSION;
+#endif
+#if defined(OSSL_NO_USABLE_TLS1_3)
+ if (idx != 4)
+ return TEST_skip("No usable TLSv1.3 in this build");
+#endif
if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(),
TLS_client_method(), TLS1_VERSION,
@@ -6503,17 +6564,37 @@ static int test_multi_resume(int idx)
if (!TEST_true(SSL_CTX_set_max_early_data(sctx, 1024)))
goto end;
}
- if (idx == 1 || idx == 2)
+ if (idx == 1 || idx == 2 || idx == 3)
SSL_CTX_set_options(sctx, SSL_OP_NO_TICKET);
SSL_CTX_sess_set_cache_size(sctx, 5);
+ if (idx == 3) {
+ SSL_CTX_set_tlsext_servername_callback(sctx, resume_servername_cb);
+ SSL_CTX_set_tlsext_servername_arg(sctx, &cbdata);
+ cbdata.cctx = cctx;
+ cbdata.sctx = sctx;
+ cbdata.recurse = 0;
+ }
+
for (i = 0; i < 30; i++) {
if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
NULL, NULL))
|| !TEST_true(SSL_set_session(clientssl, sess)))
goto end;
+ /*
+ * Check simultaneous resumes. We pause the connection part way through
+ * the handshake by (mis)using the servername_cb. The pause occurs after
+ * session resumption has already occurred, but before any session
+ * tickets have been issued. While paused we run another complete
+ * handshake resuming the same session.
+ */
+ if (idx == 3) {
+ cbdata.i = i;
+ cbdata.sess = sess;
+ }
+
/*
* Recreate a bug where dynamically changing the max_early_data value
* can cause sessions in the session cache which cannot be deleted.
@@ -6681,7 +6762,7 @@ int setup_tests(void)
ADD_ALL_TESTS(test_client_cert_cb, 2);
ADD_ALL_TESTS(test_ca_names, 3);
ADD_ALL_TESTS(test_servername, 10);
- ADD_ALL_TESTS(test_multi_resume, 4);
+ ADD_ALL_TESTS(test_multi_resume, 5);
return 1;
}
--
2.33.0

View File

@ -0,0 +1,39 @@
From 161ea825e861895c27499ae3d8f05cbd15b0926a Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Fri, 15 Mar 2024 17:58:42 +0000
Subject: [PATCH 4/5] Hardening around not_resumable sessions
Make sure we can't inadvertently use a not_resumable session
Related to CVE-2024-2511
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24044)
(cherry picked from commit c342f4b8bd2d0b375b0e22337057c2eab47d9b96)
Signed-off-by: Liu-Ermeng <liuermeng2@huawei.com>
---
CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c
index 4e87220..9a5b0b8 100644
--- a/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c
+++ b/CryptoPkg/Library/OpensslLib/openssl/ssl/ssl_sess.c
@@ -465,6 +465,12 @@ SSL_SESSION *lookup_sess_in_cache(SSL *s, const unsigned char *sess_id,
ret = s->session_ctx->get_session_cb(s, sess_id, sess_id_len, &copy);
if (ret != NULL) {
+ if (ret->not_resumable) {
+ /* If its not resumable then ignore this session */
+ if (!copy)
+ SSL_SESSION_free(ret);
+ return NULL;
+ }
tsan_counter(&s->session_ctx->stats.sess_cb_hit);
/*
--
2.33.0

View File

@ -0,0 +1,186 @@
From 472c8dbecb85705f39ad87fa07178c2cbb346ec3 Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Fri, 15 Jul 2022 13:26:33 +0100
Subject: [PATCH 5/5] Add a test for session cache overflow
Test sessions behave as we expect even in the case that an overflow
occurs when adding a new session into the session cache.
Related to CVE-2024-2511
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24044)
(cherry picked from commit ddead0935d77ba9b771d632ace61b145d7153f18)
Signed-off-by: Liu-Ermeng <liuermeng2@huawei.com>
---
.../OpensslLib/openssl/test/sslapitest.c | 133 +++++++++++++++++-
1 file changed, 130 insertions(+), 3 deletions(-)
diff --git a/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c b/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c
index 86f746c..74bc0af 100644
--- a/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c
+++ b/CryptoPkg/Library/OpensslLib/openssl/test/sslapitest.c
@@ -6317,6 +6317,128 @@ static int test_ca_names(int tst)
return testresult;
}
+/*
+ * Test that a session cache overflow works as expected
+ * Test 0: TLSv1.3, timeout on new session later than old session
+ * Test 1: TLSv1.2, timeout on new session later than old session
+ * Test 2: TLSv1.3, timeout on new session earlier than old session
+ * Test 3: TLSv1.2, timeout on new session earlier than old session
+ */
+#if !defined(OPENSSL_NO_TLS1_3) || !defined(OPENSSL_NO_TLS1_2)
+static int test_session_cache_overflow(int idx)
+{
+ SSL_CTX *sctx = NULL, *cctx = NULL;
+ SSL *serverssl = NULL, *clientssl = NULL;
+ int testresult = 0;
+ SSL_SESSION *sess = NULL;
+
+#ifdef OPENSSL_NO_TLS1_3
+ /* If no TLSv1.3 available then do nothing in this case */
+ if (idx % 2 == 0)
+ TEST_info("No TLSv1.3 available");
+ return 1;
+#endif
+#ifdef OPENSSL_NO_TLS1_2
+ /* If no TLSv1.2 available then do nothing in this case */
+ if (idx % 2 == 1)
+ TEST_info("No TLSv1.2 available");
+ return 1;
+#endif
+
+ if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(),
+ TLS_client_method(), TLS1_VERSION,
+ (idx % 2 == 0) ? TLS1_3_VERSION
+ : TLS1_2_VERSION,
+ &sctx, &cctx, cert, privkey))
+ || !TEST_true(SSL_CTX_set_options(sctx, SSL_OP_NO_TICKET)))
+ goto end;
+
+ SSL_CTX_sess_set_get_cb(sctx, get_session_cb);
+ get_sess_val = NULL;
+
+ SSL_CTX_sess_set_cache_size(sctx, 1);
+
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
+ NULL, NULL)))
+ goto end;
+
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
+ goto end;
+
+ if (idx > 1) {
+ sess = SSL_get_session(serverssl);
+ if (!TEST_ptr(sess))
+ goto end;
+
+ /*
+ * Cause this session to have a longer timeout than the next session to
+ * be added.
+ */
+ if (!TEST_true(SSL_SESSION_set_timeout(sess, LONG_MAX / 2))) {
+ sess = NULL;
+ goto end;
+ }
+ sess = NULL;
+ }
+
+ SSL_shutdown(serverssl);
+ SSL_shutdown(clientssl);
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ serverssl = clientssl = NULL;
+
+ /*
+ * Session cache size is 1 and we already populated the cache with a session
+ * so the next connection should cause an overflow.
+ */
+
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
+ NULL, NULL)))
+ goto end;
+
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
+ goto end;
+
+ /*
+ * The session we just negotiated may have been already removed from the
+ * internal cache - but we will return it anyway from our external cache.
+ */
+ get_sess_val = SSL_get_session(serverssl);
+ if (!TEST_ptr(get_sess_val))
+ goto end;
+ sess = SSL_get1_session(clientssl);
+ if (!TEST_ptr(sess))
+ goto end;
+
+ SSL_shutdown(serverssl);
+ SSL_shutdown(clientssl);
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ serverssl = clientssl = NULL;
+
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
+ NULL, NULL)))
+ goto end;
+
+ if (!TEST_true(SSL_set_session(clientssl, sess)))
+ goto end;
+
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
+ goto end;
+
+ testresult = 1;
+
+ end:
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ SSL_CTX_free(sctx);
+ SSL_CTX_free(cctx);
+ SSL_SESSION_free(sess);
+
+ return testresult;
+}
+#endif /* !defined(OPENSSL_NO_TLS1_3) || !defined(OPENSSL_NO_TLS1_2) */
+
/*
* Test 0: Client sets servername and server acknowledges it (TLSv1.2)
* Test 1: Client sets servername and server does not acknowledge it (TLSv1.2)
@@ -6540,14 +6662,16 @@ static int test_multi_resume(int idx)
#if defined(OPENSSL_NO_TLS1_2)
if (idx == 4)
- return TEST_skip("TLSv1.2 is disabled in this build");
+ TEST_info("TLSv1.2 is disabled in this build");
+ return 1;
#else
if (idx == 4)
max_version = TLS1_2_VERSION;
#endif
-#if defined(OSSL_NO_USABLE_TLS1_3)
+#if defined(OPENSSL_NO_TLS1_3)
if (idx != 4)
- return TEST_skip("No usable TLSv1.3 in this build");
+ TEST_info("No usable TLSv1.3 in this build");
+ return 1;
#endif
if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(),
@@ -6752,6 +6876,9 @@ int setup_tests(void)
ADD_ALL_TESTS(test_max_fragment_len_ext, OSSL_NELEM(max_fragment_len_test));
#if !defined(OPENSSL_NO_SRP) && !defined(OPENSSL_NO_TLS1_2)
ADD_ALL_TESTS(test_srp, 6);
+#endif
+#if !defined(OPENSSL_NO_TLS1_2) || !defined(OPENSSL_NO_TLS1_3)
+ ADD_ALL_TESTS(test_session_cache_overflow, 4);
#endif
ADD_ALL_TESTS(test_info_callback, 6);
ADD_ALL_TESTS(test_ssl_pending, 2);
--
2.33.0

View File

@ -5,7 +5,7 @@
Name: edk2
Version: %{stable_date}
Release: 16
Release: 17
Summary: EFI Development Kit II
License: BSD-2-Clause-Patent
URL: https://github.com/tianocore/edk2
@ -101,6 +101,13 @@ Patch0069: 0069-NetworkPkg-Dhcp6Dxe-SECURITY-PATCH-CVE-2023-45229-Re.patch
Patch0070: 0070-NetworkPkg-Dhcp6Dxe-Removes-duplicate-check-and-repl.patch
Patch0071: 0071-NetworkPkg-Dhcp6Dxe-Packet-Length-is-not-updated-bef.patch
# fix CVE-2024-2511
Patch0072: 0072-Fix-unconstrained-session-cache-growth-in-TLSv1.3.patch
Patch0073: 0073-Add-a-test-for-session-cache-handling.patch
Patch0074: 0074-Extend-the-multi_resume-test-for-simultaneous-resump.patch
Patch0075: 0075-Hardening-around-not_resumable-sessions.patch
Patch0076: 0076-Add-a-test-for-session-cache-overflow.patch
BuildRequires: acpica-tools gcc gcc-c++ libuuid-devel python3 bc nasm python3-unversioned-command
%description
@ -301,6 +308,9 @@ chmod +x %{buildroot}%{_bindir}/Rsa2048Sha256GenerateKeys
%endif
%changelog
* Mon Apr 15 2024 shenyage<shenyage1@huawei.com> - 202011-17
- fix CVE-2024-2511
* Thu Mar 7 2024 yexiao<yexiao7@huawei.com> - 202011-16
- fix CVE-2023-45229、CVE-2023-45230、CVE-2023-45231、CVE-2023-45232、CVE-2023-45233、CVE-2023-45234、CVE-2023-45235