From a97eb81d9480d345f894a82f7147be0238c15998 Mon Sep 17 00:00:00 2001 From: xkernel Date: Wed, 12 Jan 2022 21:06:00 +0800 Subject: [PATCH] openssl: check SSL_get_ex_data to prevent potential NULL dereference Closes #8268 --- lib/vtls/openssl.c | 40 ++++++++++++++++++++++++++-------------- lib/vtls/vtls.h | 2 +- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c index 67843bcd3..9796c1ff9 100644 --- a/lib/vtls/openssl.c +++ b/lib/vtls/openssl.c @@ -266,7 +266,7 @@ struct ssl_backend_data { #endif }; -static void ossl_associate_connection(struct Curl_easy *data, +static bool ossl_associate_connection(struct Curl_easy *data, struct connectdata *conn, int sockindex); @@ -2523,13 +2523,12 @@ static int ossl_new_session_cb(SSL *ssl, SSL_SESSION *ssl_sessionid) return 0; conn = (struct connectdata*) SSL_get_ex_data(ssl, connectdata_idx); - if(!conn) - return 0; - data = (struct Curl_easy *) SSL_get_ex_data(ssl, data_idx); - /* The sockindex has been stored as a pointer to an array element */ sockindex_ptr = (curl_socket_t*) SSL_get_ex_data(ssl, sockindex_idx); + if(!conn || !data || !sockindex_ptr) + return 0; + sockindex = (int)(sockindex_ptr - conn->sock); isproxy = SSL_get_ex_data(ssl, proxy_idx) ? TRUE : FALSE; @@ -3261,7 +3260,13 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, } #endif - ossl_associate_connection(data, conn, sockindex); + if(!ossl_associate_connection(data, conn, sockindex)) { + /* Maybe the internal errors of SSL_get_ex_new_index or SSL_set_ex_data */ + failf(data, "SSL: ossl_associate_connection failed: %s", + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer))); + return CURLE_SSL_CONNECT_ERROR; + } Curl_ssl_sessionid_lock(data); if(!Curl_ssl_getsessionid(data, conn, SSL_IS_PROXY() ? TRUE : FALSE, @@ -4548,7 +4553,7 @@ static void *ossl_get_internals(struct ssl_connect_data *connssl, (void *)backend->ctx : (void *)backend->handle; } -static void ossl_associate_connection(struct Curl_easy *data, +static bool ossl_associate_connection(struct Curl_easy *data, struct connectdata *conn, int sockindex) { @@ -4557,7 +4562,7 @@ static void ossl_associate_connection(struct Curl_easy *data, /* If we don't have SSL context, do nothing. */ if(!backend->handle) - return; + return FALSE; if(SSL_SET_OPTION(primary.sessionid)) { int data_idx = ossl_get_ssl_data_index(); @@ -4567,19 +4572,26 @@ static void ossl_associate_connection(struct Curl_easy *data, if(data_idx >= 0 && connectdata_idx >= 0 && sockindex_idx >= 0 && proxy_idx >= 0) { + int data_status, conn_status, sockindex_status, proxy_status; + /* Store the data needed for the "new session" callback. * The sockindex is stored as a pointer to an array element. */ - SSL_set_ex_data(backend->handle, data_idx, data); - SSL_set_ex_data(backend->handle, connectdata_idx, conn); - SSL_set_ex_data(backend->handle, sockindex_idx, conn->sock + sockindex); + data_status = SSL_set_ex_data(backend->handle, data_idx, data); + conn_status = SSL_set_ex_data(backend->handle, connectdata_idx, conn); + sockindex_status = SSL_set_ex_data(backend->handle, sockindex_idx, + conn->sock + sockindex); #ifndef CURL_DISABLE_PROXY - SSL_set_ex_data(backend->handle, proxy_idx, SSL_IS_PROXY() ? (void *) 1: - NULL); + proxy_status = SSL_set_ex_data(backend->handle, proxy_idx, + SSL_IS_PROXY() ? (void *) 1 : NULL); #else - SSL_set_ex_data(backend->handle, proxy_idx, NULL); + proxy_status = SSL_set_ex_data(backend->handle, proxy_idx, NULL); #endif + if(data_status && conn_status && sockindex_status && proxy_status) + return TRUE; } + return FALSE; } + return TRUE; } /* diff --git a/lib/vtls/vtls.h b/lib/vtls/vtls.h index 32cb811ae..fe5fc20e3 100644 --- a/lib/vtls/vtls.h +++ b/lib/vtls/vtls.h @@ -85,7 +85,7 @@ struct Curl_ssl { CURLcode (*sha256sum)(const unsigned char *input, size_t inputlen, unsigned char *sha256sum, size_t sha256sumlen); - void (*associate_connection)(struct Curl_easy *data, + bool (*associate_connection)(struct Curl_easy *data, struct connectdata *conn, int sockindex); void (*disassociate_connection)(struct Curl_easy *data, int sockindex);