From b791dc66cec538dd64cb6ec88e26814ecff18d45 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Sun, 31 Jan 2021 00:06:51 +0100 Subject: [PATCH] Fix mutex leak in HMAC_DRBG mbedtls_hmac_drbg_free() left a mutex in the initialized state. This caused a resource leak on platforms where mbedtls_mutex_init() allocates resources. To fix this, mbedtls_hmac_drbg_free() no longer reinitializes the mutex. To preserve the property that mbedtls_hmac_drbg_free() leaves the object in an initialized state, which is generally true throughout the library except regarding mutex objects on some platforms, no longer initialize the mutex in mbedtls_hmac_drbg_init(). Since the mutex is only used after seeding, and seeding is only permitted once, call mbedtls_mutex_init() as part of the seeding process. Signed-off-by: Gilles Peskine --- library/hmac_drbg.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/library/hmac_drbg.c b/library/hmac_drbg.c index 25a022583..d322b657d 100644 --- a/library/hmac_drbg.c +++ b/library/hmac_drbg.c @@ -54,10 +54,6 @@ void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx ) memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) ); ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL; - -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_init( &ctx->mutex ); -#endif } /* @@ -129,6 +125,10 @@ int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx, if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 ) return( ret ); +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_init( &ctx->mutex ); +#endif + /* * Set initial working state. * Use the V memory location, which is currently all 0, to initialize the @@ -254,6 +254,10 @@ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx, if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 ) return( ret ); +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_init( &ctx->mutex ); +#endif + md_size = mbedtls_md_get_size( md_info ); /* @@ -421,14 +425,12 @@ void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx ) return; #if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_free( &ctx->mutex ); + if( ctx->md_ctx.md_info != NULL ) + mbedtls_mutex_free( &ctx->mutex ); #endif mbedtls_md_free( &ctx->md_ctx ); mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) ); ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL; -#if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_init( &ctx->mutex ); -#endif } #if defined(MBEDTLS_FS_IO)