Commit 2ffad846c7 for openssl.org
commit 2ffad846c789bdf71e6b554db0596825bf2d7d92
Author: Frederik Wedel-Heinen <frederik.wedel-heinen@dencrypt.dk>
Date: Mon Dec 22 15:36:24 2025 +0100
Correctly handle the cases where SSL_dup fails.
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
MergeDate: Thu Jan 8 10:06:48 2026
(Merged from https://github.com/openssl/openssl/pull/29485)
diff --git a/ssl/bio_ssl.c b/ssl/bio_ssl.c
index fdf79a98a4..6e7b27546b 100644
--- a/ssl/bio_ssl.c
+++ b/ssl/bio_ssl.c
@@ -226,7 +226,7 @@ static int ssl_write(BIO *b, const char *buf, size_t size, size_t *written)
static long ssl_ctrl(BIO *b, int cmd, long num, void *ptr)
{
- SSL **sslp, *ssl;
+ SSL **sslp, *ssl, *dupssl;
BIO_SSL *bs, *dbs;
BIO *dbio, *bio;
long ret = 1;
@@ -382,14 +382,19 @@ static long ssl_ctrl(BIO *b, int cmd, long num, void *ptr)
case BIO_CTRL_DUP:
dbio = (BIO *)ptr;
dbs = BIO_get_data(dbio);
+ dupssl = SSL_dup(ssl);
+ if (dupssl == NULL) {
+ ret = 0;
+ break;
+ }
SSL_free(dbs->ssl);
- dbs->ssl = SSL_dup(ssl);
+ dbs->ssl = dupssl;
dbs->num_renegotiates = bs->num_renegotiates;
dbs->renegotiate_count = bs->renegotiate_count;
dbs->byte_count = bs->byte_count;
dbs->renegotiate_timeout = bs->renegotiate_timeout;
dbs->last_time = bs->last_time;
- ret = (dbs->ssl != NULL);
+ ret = 1;
break;
case BIO_C_GET_FD:
ret = BIO_ctrl(SSL_get_rbio(ssl), cmd, num, ptr);
diff --git a/test/sslapitest.c b/test/sslapitest.c
index a758ae263a..6c13b8e226 100644
--- a/test/sslapitest.c
+++ b/test/sslapitest.c
@@ -10908,7 +10908,8 @@ static int test_ssl_dup(void)
client2ssl = SSL_dup(clientssl);
rbio = SSL_get_rbio(clientssl);
if (!TEST_ptr(rbio)
- || !TEST_true(BIO_up_ref(rbio)))
+ || !TEST_true(BIO_up_ref(rbio))
+ || !TEST_ptr(client2ssl))
goto end;
SSL_set0_rbio(client2ssl, rbio);
rbio = NULL;