Fix an assertion failure in tls_common.c
authorMatt Caswell <matt@openssl.org>
Wed, 10 Jan 2024 16:44:12 +0000 (16:44 +0000)
committerMatt Caswell <matt@openssl.org>
Wed, 31 Jan 2024 10:10:41 +0000 (10:10 +0000)
When we clear the record layer, we better make sure we clear all relevant
fields, otherwise we can get ourselves into an unexpected state.

Fixes #23255

Reviewed-by: Hugo Landau <hlandau@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/23256)

ssl/ssl_lib.c

index 52e1fe448637aa14ac21eb0aaf909de1b538b383..8a834c3527a7fef13a4027cba047814f39a9ed07 100644 (file)
@@ -560,17 +560,35 @@ void OPENSSL_VPROC_FUNC(void) {}
 
 static int clear_record_layer(SSL_CONNECTION *s)
 {
-    int ret;
+    int ret = 1;
 
-    /* We try and reset both record layers even if one fails */
+    /* Clear any buffered records we no longer need */
+    while (s->rlayer.curr_rec < s->rlayer.num_recs)
+        ret &= ssl_release_record(s,
+                                  &(s->rlayer.tlsrecs[s->rlayer.curr_rec ++]),
+                                  0);
+
+    BIO_free(s->rlayer.rrlnext);
+    s->rlayer.rrlnext = NULL;
+
+    /* Reset various fields */
+    s->rlayer.wnum = 0;
+    s->rlayer.handshake_fragment_len = 0;
+    s->rlayer.wpend_tot = 0;
+    s->rlayer.wpend_type = 0;
+    s->rlayer.wpend_buf = NULL;
+    s->rlayer.alert_count = 0;
+    s->rlayer.num_recs = 0;
+    s->rlayer.curr_rec = 0;
 
-    ret = ssl_set_new_record_layer(s,
-                                   SSL_CONNECTION_IS_DTLS(s) ? DTLS_ANY_VERSION
-                                                             : TLS_ANY_VERSION,
-                                   OSSL_RECORD_DIRECTION_READ,
-                                   OSSL_RECORD_PROTECTION_LEVEL_NONE, NULL, 0,
-                                   NULL, 0, NULL, 0, NULL,  0, NULL, 0,
-                                   NID_undef, NULL, NULL, NULL);
+    /* We try and reset both record layers even if one fails */
+    ret &= ssl_set_new_record_layer(s,
+                                    SSL_CONNECTION_IS_DTLS(s) ? DTLS_ANY_VERSION
+                                                              : TLS_ANY_VERSION,
+                                    OSSL_RECORD_DIRECTION_READ,
+                                    OSSL_RECORD_PROTECTION_LEVEL_NONE, NULL, 0,
+                                    NULL, 0, NULL, 0, NULL,  0, NULL, 0,
+                                    NID_undef, NULL, NULL, NULL);
 
     ret &= ssl_set_new_record_layer(s,
                                     SSL_CONNECTION_IS_DTLS(s) ? DTLS_ANY_VERSION