From 59a783d05ae379335f70261126d19859ae5a855d Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Tue, 22 Jun 2021 15:39:40 +0100 Subject: Fix a race in ossl_provider_add_to_store() If two threads both attempt to load the same provider at the same time, they will first both check to see if the provider already exists. If it doesn't then they will both then create new provider objects and call the init function. However only one of the threads will be successful in adding the provider to the store. For the "losing" thread we should still return "success", but we should deinitialise and free the no longer required provider object, and return the object that exists in the store. Reviewed-by: Paul Dale Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/15854) --- crypto/provider_conf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'crypto/provider_conf.c') diff --git a/crypto/provider_conf.c b/crypto/provider_conf.c index 14a2d62a7e..1d4e695fb8 100644 --- a/crypto/provider_conf.c +++ b/crypto/provider_conf.c @@ -113,7 +113,7 @@ static int provider_conf_load(OSSL_LIB_CTX *libctx, const char *name, int i; STACK_OF(CONF_VALUE) *ecmds; int soft = 0; - OSSL_PROVIDER *prov = NULL; + OSSL_PROVIDER *prov = NULL, *actual = NULL; const char *path = NULL; long activate = 0; int ok = 0; @@ -173,13 +173,13 @@ static int provider_conf_load(OSSL_LIB_CTX *libctx, const char *name, if (ok) { if (!ossl_provider_activate(prov, 1, 0)) { ok = 0; - } else if (!ossl_provider_add_to_store(prov, 0)) { + } else if (!ossl_provider_add_to_store(prov, &actual, 0)) { ossl_provider_deactivate(prov); ok = 0; } else { if (pcgbl->activated_providers == NULL) pcgbl->activated_providers = sk_OSSL_PROVIDER_new_null(); - sk_OSSL_PROVIDER_push(pcgbl->activated_providers, prov); + sk_OSSL_PROVIDER_push(pcgbl->activated_providers, actual); ok = 1; } } -- cgit v1.2.1