mirror of
https://github.com/openssl/openssl.git
synced 2026-05-07 20:12:39 +00:00
Fix record layer leak when swapping chained transport BIO
tls_set1_bio() freed only the top BIO (BIO_free). Use BIO_free_all so a pushed transport chain is released when the record layer replaces its BIO. Add test_ssl_set_wbio_chain_no_leak in sslapitest (stacked BIO chain via SSL_set0_wbio) per reviewer feedback on GH openssl#30483. Drop the Perl s_client reconnect recipe and CHANGES entry (internal leak only). Fixes #30458 Reviewed-by: Simo Sorce <simo@redhat.com> Reviewed-by: Matt Caswell <matt@openssl.foundation> MergeDate: Tue Apr 28 06:39:25 2026 (Merged from https://github.com/openssl/openssl/pull/30483)
This commit is contained in:
committed by
Nikola Pajkovsky
parent
31286c0351
commit
435feadaf4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -1944,7 +1944,7 @@ int tls_set1_bio(OSSL_RECORD_LAYER *rl, BIO *bio)
|
||||
{
|
||||
if (bio != NULL && !BIO_up_ref(bio))
|
||||
return 0;
|
||||
BIO_free(rl->bio);
|
||||
BIO_free_all(rl->bio);
|
||||
rl->bio = bio;
|
||||
|
||||
return 1;
|
||||
|
||||
@@ -3604,6 +3604,52 @@ static int test_ssl_bio_change_wbio(void)
|
||||
return execute_test_ssl_bio(0, CHANGE_WBIO);
|
||||
}
|
||||
|
||||
/*
|
||||
* Regression for GH #30458: tls_set1_bio() must BIO_free_all the old chain
|
||||
* when the write BIO is replaced, not only the top BIO.
|
||||
*/
|
||||
static int test_ssl_set_wbio_chain_no_leak(void)
|
||||
{
|
||||
SSL_CTX *ctx = NULL;
|
||||
SSL *ssl = NULL;
|
||||
BIO *bio = NULL, *filter = NULL, *chain1 = NULL;
|
||||
int testresult = 0;
|
||||
|
||||
if (!TEST_ptr(ctx = SSL_CTX_new_ex(libctx, NULL, TLS_method())))
|
||||
goto end;
|
||||
if (!TEST_ptr(ssl = SSL_new(ctx)))
|
||||
goto end;
|
||||
|
||||
if (!TEST_ptr(filter = BIO_new(BIO_f_nbio_test())))
|
||||
goto end;
|
||||
if (!TEST_ptr(bio = BIO_new(BIO_s_mem()))) {
|
||||
BIO_free(filter);
|
||||
filter = NULL;
|
||||
goto end;
|
||||
}
|
||||
if (!TEST_ptr(chain1 = BIO_push(filter, bio))) {
|
||||
BIO_free_all(filter);
|
||||
filter = bio = NULL;
|
||||
goto end;
|
||||
}
|
||||
filter = bio = NULL;
|
||||
|
||||
SSL_set0_wbio(ssl, chain1);
|
||||
chain1 = NULL;
|
||||
SSL_set0_wbio(ssl, NULL);
|
||||
|
||||
testresult = 1;
|
||||
|
||||
end:
|
||||
BIO_free(filter);
|
||||
BIO_free(bio);
|
||||
BIO_free(chain1);
|
||||
SSL_free(ssl);
|
||||
SSL_CTX_free(ctx);
|
||||
|
||||
return testresult;
|
||||
}
|
||||
|
||||
#if !defined(OPENSSL_NO_TLS1_2) || defined(OSSL_NO_USABLE_TLS1_3)
|
||||
typedef struct {
|
||||
/* The list of sig algs */
|
||||
@@ -14835,6 +14881,7 @@ int setup_tests(void)
|
||||
ADD_TEST(test_ssl_bio_pop_ssl_bio);
|
||||
ADD_TEST(test_ssl_bio_change_rbio);
|
||||
ADD_TEST(test_ssl_bio_change_wbio);
|
||||
ADD_TEST(test_ssl_set_wbio_chain_no_leak);
|
||||
#if !defined(OPENSSL_NO_TLS1_2) || defined(OSSL_NO_USABLE_TLS1_3)
|
||||
ADD_ALL_TESTS(test_set_sigalgs, OSSL_NELEM(testsigalgs) * 2);
|
||||
ADD_TEST(test_keylog);
|
||||
|
||||
Reference in New Issue
Block a user