From 2fd6c12e85ec7558cbdee08033f822c42ee0f5d4 Mon Sep 17 00:00:00 2001 From: Oleg Bulatov Date: Wed, 10 Apr 2024 00:17:35 +0200 Subject: crypto/provider_core.c: Allocate activatecnt_lock CRYPTO_atomic_add has a lock as a parameter, which is often ignored, but in some cases (for example, when BROKEN_CLANG_ATOMICS is defined) it is required. There is no easy way to determine if the lock is needed or not. The current logic looks like this: if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) && !defined(OPENSSL_SYS_WINDOWS) if defined(__GNUC__) && defined(__ATOMIC_ACQ_REL) && !defined(BROKEN_CLANG_ATOMICS) - It works without the lock, but in general the need for the lock depends on __atomic_is_lock_free results elif defined(__sun) && (defined(__SunOS_5_10) || defined(__SunOS_5_11)) - The lock is not needed (unless ret is NULL, which should never happen?) else - The lock is required endif else - The lock is not needed endif Adding such conditions outside of crypto.h is error-prone, so it is better to always allocate the lock, otherwise CRYPTO_atomic_add may silently fail. Fixes #23376. CLA: trivial Fixes: fc570b2605 ("Avoid taking a write lock in ossl_provider_doall_activated()") Signed-off-by: Oleg Bulatov Reviewed-by: Tim Hudson Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/24081) --- crypto/provider_core.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/crypto/provider_core.c b/crypto/provider_core.c index 57dacd76f7..8046b0b48c 100644 --- a/crypto/provider_core.c +++ b/crypto/provider_core.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -446,13 +446,11 @@ static OSSL_PROVIDER *provider_new(const char *name, OPENSSL_free(prov); return NULL; } -#ifndef HAVE_ATOMICS if ((prov->activatecnt_lock = CRYPTO_THREAD_lock_new()) == NULL) { ossl_provider_free(prov); ERR_raise(ERR_LIB_CRYPTO, ERR_R_CRYPTO_LIB); return NULL; } -#endif if ((prov->opbits_lock = CRYPTO_THREAD_lock_new()) == NULL || (prov->flag_lock = CRYPTO_THREAD_lock_new()) == NULL @@ -742,9 +740,7 @@ void ossl_provider_free(OSSL_PROVIDER *prov) sk_INFOPAIR_pop_free(prov->parameters, infopair_free); CRYPTO_THREAD_lock_free(prov->opbits_lock); CRYPTO_THREAD_lock_free(prov->flag_lock); -#ifndef HAVE_ATOMICS CRYPTO_THREAD_lock_free(prov->activatecnt_lock); -#endif CRYPTO_FREE_REF(&prov->refcnt); OPENSSL_free(prov); } -- cgit v1.2.3