mbedtls: properly cleanup the thread-shared entropy

- Store the state of the thread-shared entropy for global init/cleanup.

- Use curl's thread support of mbedtls for all Windows builds instead of
  just when the threaded resolver is used via USE_THREADS_WIN32.

Prior to this change on global cleanup curl builds that have curl thread
support for mbedtls freed the entropy (8b1d2298) but failed to mark that
it had been freed, which caused problems on subsequent init + transfer.

Bug: https://github.com/curl/curl/discussions/11919#discussioncomment-8687105
Reported-by: awesomekosm@users.noreply.github.com

Closes https://github.com/curl/curl/pull/13071
This commit is contained in:
Jay Satiro 2024-03-06 19:18:46 -05:00
parent 3ccce37790
commit 942896fdd1
3 changed files with 28 additions and 16 deletions

View File

@ -110,7 +110,8 @@ struct mbed_ssl_backend_data {
};
/* apply threading? */
#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
#if (defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)) || \
defined(_WIN32)
#define THREADING_SUPPORT
#endif
@ -123,7 +124,6 @@ static mbedtls_entropy_context ts_entropy;
static int entropy_init_initialized = 0;
/* start of entropy_init_mutex() */
static void entropy_init_mutex(mbedtls_entropy_context *ctx)
{
/* lock 0 = entropy_init_mutex() */
@ -134,9 +134,18 @@ static void entropy_init_mutex(mbedtls_entropy_context *ctx)
}
Curl_mbedtlsthreadlock_unlock_function(0);
}
/* end of entropy_init_mutex() */
/* start of entropy_func_mutex() */
static void entropy_cleanup_mutex(mbedtls_entropy_context *ctx)
{
/* lock 0 = use same lock as init */
Curl_mbedtlsthreadlock_lock_function(0);
if(entropy_init_initialized == 1) {
mbedtls_entropy_free(ctx);
entropy_init_initialized = 0;
}
Curl_mbedtlsthreadlock_unlock_function(0);
}
static int entropy_func_mutex(void *data, unsigned char *output, size_t len)
{
int ret;
@ -147,7 +156,6 @@ static int entropy_func_mutex(void *data, unsigned char *output, size_t len)
return ret;
}
/* end of entropy_func_mutex() */
#endif /* THREADING_SUPPORT */
@ -377,7 +385,6 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
}
#ifdef THREADING_SUPPORT
entropy_init_mutex(&ts_entropy);
mbedtls_ctr_drbg_init(&backend->ctr_drbg);
ret = mbedtls_ctr_drbg_seed(&backend->ctr_drbg, entropy_func_mutex,
@ -1246,14 +1253,19 @@ static CURLcode mbedtls_connect(struct Curl_cfilter *cf,
*/
static int mbedtls_init(void)
{
return Curl_mbedtlsthreadlock_thread_setup();
if(!Curl_mbedtlsthreadlock_thread_setup())
return 0;
#ifdef THREADING_SUPPORT
entropy_init_mutex(&ts_entropy);
#endif
return 1;
}
static void mbedtls_cleanup(void)
{
#ifdef THREADING_SUPPORT
mbedtls_entropy_free(&ts_entropy);
#endif /* THREADING_SUPPORT */
entropy_cleanup_mutex(&ts_entropy);
#endif
(void)Curl_mbedtlsthreadlock_thread_cleanup();
}

View File

@ -26,12 +26,12 @@
#if defined(USE_MBEDTLS) && \
((defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)) || \
defined(USE_THREADS_WIN32))
defined(_WIN32))
#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
# include <pthread.h>
# define MBEDTLS_MUTEX_T pthread_mutex_t
#elif defined(USE_THREADS_WIN32)
#elif defined(_WIN32)
# define MBEDTLS_MUTEX_T HANDLE
#endif
@ -59,7 +59,7 @@ int Curl_mbedtlsthreadlock_thread_setup(void)
#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
if(pthread_mutex_init(&mutex_buf[i], NULL))
return 0; /* pthread_mutex_init failed */
#elif defined(USE_THREADS_WIN32)
#elif defined(_WIN32)
mutex_buf[i] = CreateMutex(0, FALSE, 0);
if(mutex_buf[i] == 0)
return 0; /* CreateMutex failed */
@ -80,7 +80,7 @@ int Curl_mbedtlsthreadlock_thread_cleanup(void)
#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
if(pthread_mutex_destroy(&mutex_buf[i]))
return 0; /* pthread_mutex_destroy failed */
#elif defined(USE_THREADS_WIN32)
#elif defined(_WIN32)
if(!CloseHandle(mutex_buf[i]))
return 0; /* CloseHandle failed */
#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */
@ -100,7 +100,7 @@ int Curl_mbedtlsthreadlock_lock_function(int n)
"Error: mbedtlsthreadlock_lock_function failed\n"));
return 0; /* pthread_mutex_lock failed */
}
#elif defined(USE_THREADS_WIN32)
#elif defined(_WIN32)
if(WaitForSingleObject(mutex_buf[n], INFINITE) == WAIT_FAILED) {
DEBUGF(fprintf(stderr,
"Error: mbedtlsthreadlock_lock_function failed\n"));
@ -120,7 +120,7 @@ int Curl_mbedtlsthreadlock_unlock_function(int n)
"Error: mbedtlsthreadlock_unlock_function failed\n"));
return 0; /* pthread_mutex_unlock failed */
}
#elif defined(USE_THREADS_WIN32)
#elif defined(_WIN32)
if(!ReleaseMutex(mutex_buf[n])) {
DEBUGF(fprintf(stderr,
"Error: mbedtlsthreadlock_unlock_function failed\n"));

View File

@ -29,7 +29,7 @@
#ifdef USE_MBEDTLS
#if (defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)) || \
defined(USE_THREADS_WIN32)
defined(_WIN32)
int Curl_mbedtlsthreadlock_thread_setup(void);
int Curl_mbedtlsthreadlock_thread_cleanup(void);