openssl: check SSL_get_ex_data to prevent potential NULL dereference

Closes #8268
This commit is contained in:
xkernel 2022-01-12 21:06:00 +08:00 коммит произвёл Daniel Stenberg
Родитель f0fb903cbc
Коммит a97eb81d94
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 5CC908FDB71E12C2
2 изменённых файлов: 27 добавлений и 15 удалений

Просмотреть файл

@ -266,7 +266,7 @@ struct ssl_backend_data {
#endif #endif
}; };
static void ossl_associate_connection(struct Curl_easy *data, static bool ossl_associate_connection(struct Curl_easy *data,
struct connectdata *conn, struct connectdata *conn,
int sockindex); int sockindex);
@ -2523,13 +2523,12 @@ static int ossl_new_session_cb(SSL *ssl, SSL_SESSION *ssl_sessionid)
return 0; return 0;
conn = (struct connectdata*) SSL_get_ex_data(ssl, connectdata_idx); 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); data = (struct Curl_easy *) SSL_get_ex_data(ssl, data_idx);
/* The sockindex has been stored as a pointer to an array element */ /* The sockindex has been stored as a pointer to an array element */
sockindex_ptr = (curl_socket_t*) SSL_get_ex_data(ssl, sockindex_idx); 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); sockindex = (int)(sockindex_ptr - conn->sock);
isproxy = SSL_get_ex_data(ssl, proxy_idx) ? TRUE : FALSE; isproxy = SSL_get_ex_data(ssl, proxy_idx) ? TRUE : FALSE;
@ -3261,7 +3260,13 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
} }
#endif #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); Curl_ssl_sessionid_lock(data);
if(!Curl_ssl_getsessionid(data, conn, SSL_IS_PROXY() ? TRUE : FALSE, 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; (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, struct connectdata *conn,
int sockindex) 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 we don't have SSL context, do nothing. */
if(!backend->handle) if(!backend->handle)
return; return FALSE;
if(SSL_SET_OPTION(primary.sessionid)) { if(SSL_SET_OPTION(primary.sessionid)) {
int data_idx = ossl_get_ssl_data_index(); 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 && if(data_idx >= 0 && connectdata_idx >= 0 && sockindex_idx >= 0 &&
proxy_idx >= 0) { proxy_idx >= 0) {
int data_status, conn_status, sockindex_status, proxy_status;
/* Store the data needed for the "new session" callback. /* Store the data needed for the "new session" callback.
* The sockindex is stored as a pointer to an array element. */ * The sockindex is stored as a pointer to an array element. */
SSL_set_ex_data(backend->handle, data_idx, data); data_status = SSL_set_ex_data(backend->handle, data_idx, data);
SSL_set_ex_data(backend->handle, connectdata_idx, conn); conn_status = SSL_set_ex_data(backend->handle, connectdata_idx, conn);
SSL_set_ex_data(backend->handle, sockindex_idx, conn->sock + sockindex); sockindex_status = SSL_set_ex_data(backend->handle, sockindex_idx,
conn->sock + sockindex);
#ifndef CURL_DISABLE_PROXY #ifndef CURL_DISABLE_PROXY
SSL_set_ex_data(backend->handle, proxy_idx, SSL_IS_PROXY() ? (void *) 1: proxy_status = SSL_set_ex_data(backend->handle, proxy_idx,
NULL); SSL_IS_PROXY() ? (void *) 1 : NULL);
#else #else
SSL_set_ex_data(backend->handle, proxy_idx, NULL); proxy_status = SSL_set_ex_data(backend->handle, proxy_idx, NULL);
#endif #endif
if(data_status && conn_status && sockindex_status && proxy_status)
return TRUE;
} }
return FALSE;
} }
return TRUE;
} }
/* /*

Просмотреть файл

@ -85,7 +85,7 @@ struct Curl_ssl {
CURLcode (*sha256sum)(const unsigned char *input, size_t inputlen, CURLcode (*sha256sum)(const unsigned char *input, size_t inputlen,
unsigned char *sha256sum, size_t sha256sumlen); unsigned char *sha256sum, size_t sha256sumlen);
void (*associate_connection)(struct Curl_easy *data, bool (*associate_connection)(struct Curl_easy *data,
struct connectdata *conn, struct connectdata *conn,
int sockindex); int sockindex);
void (*disassociate_connection)(struct Curl_easy *data, int sockindex); void (*disassociate_connection)(struct Curl_easy *data, int sockindex);