mirror of
https://github.com/openssl/openssl.git
synced 2026-01-18 17:11:31 +01:00
Prevent freeing of parent listener in SSL_listen_ex
Its been reported that, when using SSL_listen_ex to obtain a new connection from a listener, that, if the listener is freed prior to the obtained connection, we get use-after-free conditions when freeing said obtained connections. This occurs because SSL_listen_ex fails to take a reference on the parent listener SSL object (in the same way that SSL_new_from_listener does). If the listener is freed first, then several listener resources are freed, which the obtained connection still makes use of, hence the use-after-free. The fix is to do what SSL_new_from_listener does, namely: 1) Increase the reference count on the listener SSL object. 2) Ensure that the connection qc->listener points to the listener object so that, when the connection is freed, we call SSL_free on the listener object, dropping the reference count we take in SSL_listen_ex. While we're at it, this PR also modifies the quicapi test for testing the SSL_listen_ex call, freeing the listener first to ensure that the increased refcount holds the SSL object data stable until the connection is freed. Thanks to Stanislav Fort at Asile Research for pointing out this issue. fixes openssl/project#1766 Reviewed-by: Saša Nedvědický <sashan@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/29398)
This commit is contained in:
@@ -4670,9 +4670,21 @@ int ossl_quic_peeloff_conn(SSL *listener, SSL *new_conn)
|
||||
|
||||
qc = cctx.qc;
|
||||
ql = lctx.ql;
|
||||
/*
|
||||
* Need to ensure that we take a reference on our new listener
|
||||
* so that we don't free it before this connection
|
||||
*/
|
||||
if (!SSL_up_ref(&ql->obj.ssl))
|
||||
goto out;
|
||||
|
||||
ossl_quic_channel_free(qc->ch);
|
||||
ossl_quic_port_free(qc->port);
|
||||
ossl_quic_engine_free(qc->engine);
|
||||
/*
|
||||
* Ensure that we point to our listener so we can drop
|
||||
* the above refcount when this SSL object is freed
|
||||
*/
|
||||
qc->listener = ql;
|
||||
qc->obj.engine = ql->engine;
|
||||
qc->engine = ql->engine;
|
||||
qc->port = ql->port;
|
||||
|
||||
@@ -2910,9 +2910,9 @@ static int test_ssl_listen_ex(void)
|
||||
testresult = 1;
|
||||
|
||||
err:
|
||||
SSL_free(qlistener);
|
||||
SSL_free(serverssl);
|
||||
SSL_free(clientssl);
|
||||
SSL_free(qlistener);
|
||||
SSL_CTX_free(sctx);
|
||||
SSL_CTX_free(cctx);
|
||||
SSL_CTX_free(qmctx);
|
||||
|
||||
Reference in New Issue
Block a user