From: Matt Caswell Date: Fri, 27 May 2022 10:07:37 +0000 (+0100) Subject: Don't call ossl_provider_free() without first setting refcnt X-Git-Tag: openssl-3.2.0-alpha1~2584 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c4ed6f6f0ee700e0473def049659061dd52fd3fc;p=thirdparty%2Fopenssl.git Don't call ossl_provider_free() without first setting refcnt The function ossl_provider_free() decrements the refcnt of the provider and frees it if it has reached 0. This only works if the refcnt has already been initialised. We must only call ossl_provider_free() after this initialisation - otherwise it will fail to free the provider correctly. Addresses the issue mentioned here: https://github.com/openssl/openssl/pull/18355#issuecomment-1138741857 Reviewed-by: Tomas Mraz Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/18417) --- diff --git a/crypto/provider_core.c b/crypto/provider_core.c index 53f04400a09..cacc2c4a6a3 100644 --- a/crypto/provider_core.c +++ b/crypto/provider_core.c @@ -450,7 +450,15 @@ static OSSL_PROVIDER *provider_new(const char *name, #ifndef HAVE_ATOMICS || (prov->refcnt_lock = CRYPTO_THREAD_lock_new()) == NULL #endif - || (prov->opbits_lock = CRYPTO_THREAD_lock_new()) == NULL + ) { + OPENSSL_free(prov); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + return NULL; + } + + prov->refcnt = 1; /* 1 One reference to be returned */ + + if ((prov->opbits_lock = CRYPTO_THREAD_lock_new()) == NULL || (prov->flag_lock = CRYPTO_THREAD_lock_new()) == NULL || (prov->name = OPENSSL_strdup(name)) == NULL || (prov->parameters = sk_INFOPAIR_deep_copy(parameters, @@ -461,7 +469,6 @@ static OSSL_PROVIDER *provider_new(const char *name, return NULL; } - prov->refcnt = 1; /* 1 One reference to be returned */ prov->init_function = init_function; return prov;