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;
}
}