Commit 41eecc7c7c for openssl.org

commit 41eecc7c7cd4069b1b29bca49b9d97825c6bf648
Author: Ryan Hooper <ryanh@openssl.foundation>
Date:   Tue Oct 6 09:54:11 2026 -0400

    DTLS Listener: Guard against a NULL read BIO when retrying DTLS reads

    A connection accepted via SSL_accept_connection() from a DTLS listener
    has no read BIO of its own: dtls_listener_create_conn_ssl() calls
    SSL_set0_rbio(ssl, NULL), since such connections receive through the
    listener's shared demux queue instead. Two retry paths in
    dtls1_read_bytes() set sc->rwstate to SSL_READING and then
    unconditionally call BIO_clear_retry_flags()/BIO_set_retry_read() on
    SSL_get_rbio(s), which NULL-dereferences for a listener-accepted
    connection.

    SSL_get_error() already reports SSL_ERROR_WANT_READ for SSL_READING
    without needing a BIO at all, so skip the BIO calls when there is none.

    Assisted-by: Claude:claude-sonnet-5
    Reviewed-by: Matt Caswell <matt@openssl.foundation>
    Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
    Merge-date: Wed Oct  7 15:50:27 2026
    Merged-from: https://github.com/openssl/openssl/pull/33122

diff --git a/ssl/record/rec_layer_d1.c b/ssl/record/rec_layer_d1.c
index 52a12a8a13..8e0fc46181 100644
--- a/ssl/record/rec_layer_d1.c
+++ b/ssl/record/rec_layer_d1.c
@@ -630,8 +630,17 @@ start:

                     sc->rwstate = SSL_READING;
                     bio = SSL_get_rbio(s);
-                    BIO_clear_retry_flags(bio);
-                    BIO_set_retry_read(bio);
+                    /*
+                     * A connection accepted by a DTLS listener has no read
+                     * BIO of its own (see dtls_listener_create_conn_ssl());
+                     * SSL_get_error() already reports SSL_ERROR_WANT_READ
+                     * for SSL_READING on such a connection without needing
+                     * one.
+                     */
+                    if (bio != NULL) {
+                        BIO_clear_retry_flags(bio);
+                        BIO_set_retry_read(bio);
+                    }
                     return -1;
                 }
             }
@@ -679,8 +688,16 @@ start:
                  */
                 sc->rwstate = SSL_READING;
                 bio = SSL_get_rbio(s);
-                BIO_clear_retry_flags(bio);
-                BIO_set_retry_read(bio);
+                /*
+                 * A connection accepted by a DTLS listener has no read BIO
+                 * of its own (see dtls_listener_create_conn_ssl());
+                 * SSL_get_error() already reports SSL_ERROR_WANT_READ for
+                 * SSL_READING on such a connection without needing one.
+                 */
+                if (bio != NULL) {
+                    BIO_clear_retry_flags(bio);
+                    BIO_set_retry_read(bio);
+                }
                 return -1;
             }
         }