]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
crypto/provider_core.c: Allocate activatecnt_lock
authorOleg Bulatov <oleg@bulatov.me>
Tue, 9 Apr 2024 22:17:35 +0000 (00:17 +0200)
committerTomas Mraz <tomas@openssl.org>
Thu, 11 Apr 2024 08:07:28 +0000 (10:07 +0200)
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 <oleg@bulatov.me>
Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24081)

crypto/provider_core.c

index 57dacd76f7869f523e3e87766e9aacbc432fae2f..8046b0b48c5f5c5c6b138319f257657048137909 100644 (file)
@@ -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);
         }