diff --git a/cmake/external_libs/openssl.cmake b/cmake/external_libs/openssl.cmake index e96d5b1c7317a0f12ea57bde27d07dae488e7af1..5aea30896857ac10ba81e46459dcd47e26b84760 100644 --- a/cmake/external_libs/openssl.cmake +++ b/cmake/external_libs/openssl.cmake @@ -46,7 +46,6 @@ if(BUILD_LITE) PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2023-4807.patch PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2023-5678.patch PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2024-0727.patch - PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2024-2511.patch ) elseif(PLATFORM_ARM32 AND ANDROID_NDK_TOOLCHAIN_INCLUDED) set(openssl_USE_STATIC_LIBS OFF) @@ -81,7 +80,6 @@ if(BUILD_LITE) PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2023-4807.patch PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2023-5678.patch PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2024-0727.patch - PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2024-2511.patch ) elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR APPLE) set(openssl_CFLAGS -fvisibility=hidden) @@ -111,7 +109,6 @@ if(BUILD_LITE) PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2023-4807.patch PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2023-5678.patch PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2024-0727.patch - PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2024-2511.patch ) else() MESSAGE(FATAL_ERROR "openssl does not support compilation for the current environment.") @@ -148,7 +145,6 @@ else() PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2023-4807.patch PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2023-5678.patch PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2024-0727.patch - PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2024-2511.patch ) include_directories(${openssl_INC}) add_library(mindspore::ssl ALIAS openssl::ssl) diff --git a/third_party/patch/openssl/CVE-2024-2511.patch b/third_party/patch/openssl/CVE-2024-2511.patch deleted file mode 100644 index 8be177e5ae0da5ebb59bd81db3f66a35575a0c1f..0000000000000000000000000000000000000000 --- a/third_party/patch/openssl/CVE-2024-2511.patch +++ /dev/null @@ -1,487 +0,0 @@ -From fc43b2b1abae58c1b261962299d2bbeee770810a Mon Sep 17 00:00:00 2001 -From: jxlang910 -Date: Thu, 11 Apr 2024 17:24:44 +0800 -Subject: [PATCH] fix CVE-2024-2511 - ---- - include/openssl/sslerr.h | 4 +- - ssl/ssl_err.c | 5 +- - ssl/ssl_lib.c | 5 +- - ssl/ssl_sess.c | 36 ++++- - ssl/statem/statem_srvr.c | 5 +- - test/sslapitest.c | 300 +++++++++++++++++++++++++++++++++++++++ - 6 files changed, 339 insertions(+), 16 deletions(-) - -diff --git a/include/openssl/sslerr.h b/include/openssl/sslerr.h -index aa5f56a482..3e99ffc27f 100644 ---- a/include/openssl/sslerr.h -+++ b/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 -@@ -224,7 +224,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/ssl/ssl_err.c b/ssl/ssl_err.c -index 5a7c42a88c..c4144bb8b4 100644 ---- a/ssl/ssl_err.c -+++ b/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 -@@ -325,7 +325,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/ssl/ssl_lib.c b/ssl/ssl_lib.c -index 618549a2ca..2a44960fac 100644 ---- a/ssl/ssl_lib.c -+++ b/ssl/ssl_lib.c -@@ -3541,9 +3541,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/ssl/ssl_sess.c b/ssl/ssl_sess.c -index 1b4c85b60c..5cc816b0fc 100644 ---- a/ssl/ssl_sess.c -+++ b/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; - -@@ -221,11 +216,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) -@@ -455,6 +471,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, ©); - - 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); - - /* -diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c -index 1b3b8002ee..d242e98024 100644 ---- a/ssl/statem/statem_srvr.c -+++ b/ssl/statem/statem_srvr.c -@@ -2418,9 +2418,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) { -diff --git a/test/sslapitest.c b/test/sslapitest.c -index 5ee982ab06..395b1e5457 100644 ---- a/test/sslapitest.c -+++ b/test/sslapitest.c -@@ -6669,6 +6669,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) -@@ -7288,6 +7410,180 @@ static int test_inherit_verify_param(void) - 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.3 (SSL_OP_NO_TICKET, simultaneous resumes) -+ * Test 4: 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; -+ struct resume_servername_cb_data cbdata; -+ -+#if defined(OPENSSL_NO_TLS1_2) -+ if (idx == 4) -+ TEST_info("TLSv1.2 is disabled in this build"); -+ return 1; -+#else -+ if (idx == 4) -+ max_version = TLS1_2_VERSION; -+#endif -+#if defined(OPENSSL_NO_TLS1_3) -+ if (idx != 4) -+ TEST_info("No usable TLSv1.3 in this build"); -+ return 1; -+#endif -+ -+ 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 || 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. -+ */ -+ 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)) -@@ -7422,6 +7718,10 @@ int setup_tests(void) - #if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_TLS1_3) - ADD_ALL_TESTS(test_serverinfo_custom, 4); - #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_multi_resume, 5); - return 1; - } - --- -2.43.0.windows.1 -