Ensure we deregister thread handlers even after a failed init
authorMatt Caswell <matt@openssl.org>
Tue, 16 Mar 2021 12:03:08 +0000 (12:03 +0000)
committerMatt Caswell <matt@openssl.org>
Thu, 18 Mar 2021 12:00:42 +0000 (12:00 +0000)
If we attempt to init a provider but that init fails, then we should
still deregister any thread handlers. The provider may have failed after
these were registered.

Fixes #13338

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14576)

crypto/provider_core.c

index 4d77108c3361fdecd28b6278d23de81175132c93..632ea72a5def3c4290159344fb5f0df89109f14b 100644 (file)
@@ -359,9 +359,6 @@ void ossl_provider_free(OSSL_PROVIDER *prov)
          */
         if (ref == 0) {
             if (prov->flag_initialized) {
-#ifndef FIPS_MODULE
-                ossl_init_thread_deregister(prov);
-#endif
                 if (prov->teardown != NULL)
                     prov->teardown(prov->provctx);
 #ifndef OPENSSL_NO_ERR
@@ -380,6 +377,12 @@ void ossl_provider_free(OSSL_PROVIDER *prov)
             }
 
 #ifndef FIPS_MODULE
+            /*
+             * We deregister thread handling whether or not the provider was
+             * initialized. If init was attempted but was not successful then
+             * the provider may still have registered a thread handler.
+             */
+            ossl_init_thread_deregister(prov);
             DSO_free(prov->module);
 #endif
             OPENSSL_free(prov->name);
@@ -561,10 +564,6 @@ static int provider_init(OSSL_PROVIDER *prov)
                                 &provider_dispatch, &tmp_provctx)) {
         ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_INIT_FAIL,
                        "name=%s", prov->name);
-#ifndef FIPS_MODULE
-        DSO_free(prov->module);
-        prov->module = NULL;
-#endif
         goto end;
     }
     prov->provctx = tmp_provctx;