]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Only free the read buffers if we're not using them
authorWatson Ladd <watsonbladd@gmail.com>
Wed, 24 Apr 2024 10:26:56 +0000 (11:26 +0100)
committerMatt Caswell <matt@openssl.org>
Tue, 28 May 2024 12:52:00 +0000 (13:52 +0100)
If we're part way through processing a record, or the application has
not released all the records then we should not free our buffer because
they are still needed.

CVE-2024-4741

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24395)

ssl/record/rec_layer_s3.c
ssl/record/record.h
ssl/ssl_lib.c

index 4bcffcc41e3649fe030aef5be75c0afbf5cbdba3..1569997bea2d31277f50189f52465eae028a7260 100644 (file)
@@ -81,6 +81,15 @@ int RECORD_LAYER_read_pending(const RECORD_LAYER *rl)
     return SSL3_BUFFER_get_left(&rl->rbuf) != 0;
 }
 
+int RECORD_LAYER_data_present(const RECORD_LAYER *rl)
+{
+    if (rl->rstate == SSL_ST_READ_BODY)
+        return 1;
+    if (RECORD_LAYER_processed_read_pending(rl))
+        return 1;
+    return 0;
+}
+
 /* Checks if we have decrypted unread record data pending */
 int RECORD_LAYER_processed_read_pending(const RECORD_LAYER *rl)
 {
index 234656bf9394212dce1fa0ce5819ae5035be34c6..b60f71c8cb23b49e813fd2ec4a4c2906767e4fb7 100644 (file)
@@ -205,6 +205,7 @@ void RECORD_LAYER_release(RECORD_LAYER *rl);
 int RECORD_LAYER_read_pending(const RECORD_LAYER *rl);
 int RECORD_LAYER_processed_read_pending(const RECORD_LAYER *rl);
 int RECORD_LAYER_write_pending(const RECORD_LAYER *rl);
+int RECORD_LAYER_data_present(const RECORD_LAYER *rl);
 void RECORD_LAYER_reset_read_sequence(RECORD_LAYER *rl);
 void RECORD_LAYER_reset_write_sequence(RECORD_LAYER *rl);
 int RECORD_LAYER_is_sslv2_record(RECORD_LAYER *rl);
index e747b7f90aa7176f166ffb555ea2ab09a7f98063..9088223b9f6bbd2439a3fc65caf7acfe9fd1a178 100644 (file)
@@ -5493,6 +5493,9 @@ int SSL_free_buffers(SSL *ssl)
     if (RECORD_LAYER_read_pending(rl) || RECORD_LAYER_write_pending(rl))
         return 0;
 
+    if (RECORD_LAYER_data_present(rl))
+        return 0;
+
     RECORD_LAYER_release(rl);
     return 1;
 }