summaryrefslogtreecommitdiffstats
path: root/crypto/rand
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2021-01-08 13:48:13 +0000
committerMatt Caswell <matt@openssl.org>2021-01-14 17:30:46 +0000
commitf5a50c2a07e288187c14b784be253b3a2a23483b (patch)
tree71ab229bb6194a7dde63dcf5fa904f5bef005158 /crypto/rand
parent2c40421440d260ddb97a807b064033f61ae3b2b3 (diff)
Enable locking on the primary DRBG when we create it
The primary DRBG may be shared across multiple threads and therefore we must use locking to access it. Previously we were enabling that locking lazily when we attempted to obtain one of the child DRBGs. Part of the process of enabling the lock, is to create the lock. But if we create the lock lazily then it is too late - we may race with other threads where each thread is independently attempting to enable the locking. This results in multiple locks being created - only one of which "sticks" and the rest are leaked. Instead we enable locking on the primary when we first create it. This is already locked and therefore we cannot race. Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org> (Merged from https://github.com/openssl/openssl/pull/13660)
Diffstat (limited to 'crypto/rand')
-rw-r--r--crypto/rand/rand_lib.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c
index f0284aab08..01927401ab 100644
--- a/crypto/rand/rand_lib.c
+++ b/crypto/rand/rand_lib.c
@@ -571,6 +571,17 @@ EVP_RAND_CTX *RAND_get0_primary(OSSL_LIB_CTX *ctx)
dgbl->primary = rand_new_drbg(ctx, dgbl->seed,
PRIMARY_RESEED_INTERVAL,
PRIMARY_RESEED_TIME_INTERVAL);
+ /*
+ * The primary DRBG may be shared between multiple threads so we must
+ * enable locking.
+ */
+ if (dgbl->primary != NULL && !EVP_RAND_enable_locking(dgbl->primary)) {
+ ERR_raise(ERR_LIB_EVP, EVP_R_UNABLE_TO_ENABLE_LOCKING);
+ EVP_RAND_CTX_free(dgbl->primary);
+ dgbl->primary = NULL;
+ CRYPTO_THREAD_lock_free(dgbl->lock);
+ return NULL;
+ }
CRYPTO_THREAD_unlock(dgbl->lock);
}
return dgbl->primary;