git: 8ab790d4be21 - main - security/openssl31: Security update for CVE-2024-2511

From: Bernard Spil <brnrd_at_FreeBSD.org>
Date: Sun, 14 Apr 2024 19:22:50 UTC
The branch main has been updated by brnrd:

URL: https://cgit.FreeBSD.org/ports/commit/?id=8ab790d4be21a270c42ff57b4764f6f346be61ad

commit 8ab790d4be21a270c42ff57b4764f6f346be61ad
Author:     Bernard Spil <brnrd@FreeBSD.org>
AuthorDate: 2024-04-14 19:21:03 +0000
Commit:     Bernard Spil <brnrd@FreeBSD.org>
CommitDate: 2024-04-14 19:21:03 +0000

    security/openssl31: Security update for CVE-2024-2511
    
    Security:       7c217849-f7d7-11ee-a490-84a93843eb75
    MFH:            2024Q2
---
 security/openssl31/Makefile                  |   2 +-
 security/openssl31/files/patch-CVE-2024-2511 | 116 +++++++++++++++++++++++++++
 2 files changed, 117 insertions(+), 1 deletion(-)

diff --git a/security/openssl31/Makefile b/security/openssl31/Makefile
index 30cfce427510..7e91b88065a6 100644
--- a/security/openssl31/Makefile
+++ b/security/openssl31/Makefile
@@ -1,6 +1,6 @@
 PORTNAME=	openssl
 PORTVERSION=	3.1.5
-PORTREVISION=	2
+PORTREVISION=	3
 CATEGORIES=	security devel
 MASTER_SITES=	https://www.openssl.org/source/ \
 		ftp://ftp.cert.dfn.de/pub/tools/net/openssl/source/
diff --git a/security/openssl31/files/patch-CVE-2024-2511 b/security/openssl31/files/patch-CVE-2024-2511
new file mode 100644
index 000000000000..ac88f50f791c
--- /dev/null
+++ b/security/openssl31/files/patch-CVE-2024-2511
@@ -0,0 +1,116 @@
+From 7e4d731b1c07201ad9374c1cd9ac5263bdf35bce Mon Sep 17 00:00:00 2001
+From: Matt Caswell <matt@openssl.org>
+Date: Tue, 5 Mar 2024 15:43:53 +0000
+Subject: [PATCH] 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)
+---
+ ssl/ssl_lib.c            |  5 +++--
+ ssl/ssl_sess.c           | 28 ++++++++++++++++++++++------
+ ssl/statem/statem_srvr.c |  5 ++---
+ 3 files changed, 27 insertions(+), 11 deletions(-)
+
+diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
+index b5cc4af2f0302..e747b7f90aa71 100644
+--- ssl/ssl_lib.c.orig
++++ ssl/ssl_lib.c
+@@ -3737,9 +3737,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 bf84e792251b8..241cf43c46296 100644
+--- ssl/ssl_sess.c.orig
++++ ssl/ssl_sess.c
+@@ -154,16 +154,11 @@ SSL_SESSION *SSL_SESSION_new(void)
+     return ss;
+ }
+ 
+-SSL_SESSION *SSL_SESSION_dup(const 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(const SSL_SESSION *src, int ticket)
++static SSL_SESSION *ssl_session_dup_intern(const SSL_SESSION *src, int ticket)
+ {
+     SSL_SESSION *dest;
+ 
+@@ -287,6 +282,27 @@ SSL_SESSION *ssl_session_dup(const SSL_SESSION *src, int ticket)
+     return NULL;
+ }
+ 
++SSL_SESSION *SSL_SESSION_dup(const 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(const 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/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c
+index 5d59d53563ed8..8e493176f658e 100644
+--- ssl/statem/statem_srvr.c.orig
++++ ssl/statem/statem_srvr.c
+@@ -2338,9 +2338,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) {