Complete the cleanup of an algorithm in OSSL_METHOD_STORE
authorRichard Levitte <levitte@openssl.org>
Mon, 25 Apr 2022 05:22:27 +0000 (07:22 +0200)
committerRichard Levitte <levitte@openssl.org>
Thu, 5 May 2022 13:06:11 +0000 (15:06 +0200)
The `alg_cleanup` didn't properly clear the OPENSSL_SA leaf that it
had just freed the contents of.  Fortunately, `ossl_sa_ALGORITHM_doall_arg()`
allows us to pass the store pointer itself as an extra argument, which
allows a modified `alg_cleanup` to complete the job.

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/18151)

crypto/property/property.c

index 4303b4b5c3fffa59f22090f65b8c1b591df3c251..d209f2c79dbfdd376c543fe404f3db7503d5bb6e 100644 (file)
@@ -205,14 +205,18 @@ static void impl_cache_flush_alg(ossl_uintmax_t idx, ALGORITHM *alg)
     lh_QUERY_flush(alg->cache);
 }
 
-static void alg_cleanup(ossl_uintmax_t idx, ALGORITHM *a)
+static void alg_cleanup(ossl_uintmax_t idx, ALGORITHM *a, void *arg)
 {
+    OSSL_METHOD_STORE *store = arg;
+
     if (a != NULL) {
         sk_IMPLEMENTATION_pop_free(a->impls, &impl_free);
         lh_QUERY_doall(a->cache, &impl_cache_free);
         lh_QUERY_free(a->cache);
         OPENSSL_free(a);
     }
+    if (store != NULL)
+        ossl_sa_ALGORITHM_set(store->algs, idx, NULL);
 }
 
 /*
@@ -242,7 +246,7 @@ OSSL_METHOD_STORE *ossl_method_store_new(OSSL_LIB_CTX *ctx)
 void ossl_method_store_free(OSSL_METHOD_STORE *store)
 {
     if (store != NULL) {
-        ossl_sa_ALGORITHM_doall(store->algs, &alg_cleanup);
+        ossl_sa_ALGORITHM_doall_arg(store->algs, &alg_cleanup, store);
         ossl_sa_ALGORITHM_free(store->algs);
         CRYPTO_THREAD_lock_free(store->lock);
         OPENSSL_free(store);
@@ -332,7 +336,7 @@ int ossl_method_store_add(OSSL_METHOD_STORE *store, const OSSL_PROVIDER *prov,
 
 err:
     ossl_property_unlock(store);
-    alg_cleanup(0, alg);
+    alg_cleanup(0, alg, NULL);
     impl_free(impl);
     return 0;
 }