[openssl] master update

Dr. Paul Dale pauli at openssl.org
Thu Mar 11 23:14:43 UTC 2021


The branch master has been updated
       via  8f08957674c2015fad72ea240bbff4564b83d518 (commit)
       via  3c5ce1ce81bfcf84a64c93c74eb40c90a2a49c54 (commit)
       via  7bbfbc8239b1d9edd36830e08c30f9681baba4c7 (commit)
      from  3d0b56785aeefd2b5a08a0da99d6a09ae6a494b9 (commit)


- Log -----------------------------------------------------------------
commit 8f08957674c2015fad72ea240bbff4564b83d518
Author: Pauli <ppzgs1 at gmail.com>
Date:   Wed Mar 10 19:37:02 2021 +1000

    rename ossl_provider_forall_loaded to ossl_provider_doall_activated
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/14489)

commit 3c5ce1ce81bfcf84a64c93c74eb40c90a2a49c54
Author: Pauli <ppzgs1 at gmail.com>
Date:   Wed Mar 10 11:46:00 2021 +1000

    doc: describe the return from ossl_provider_forall_loaded()
    
    Also correct an incorrect statement about non-activated providers.
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/14489)

commit 7bbfbc8239b1d9edd36830e08c30f9681baba4c7
Author: Pauli <ppzgs1 at gmail.com>
Date:   Wed Mar 10 11:39:59 2021 +1000

    core: modify ossl_provider_forall_loaded() to avoid locking for the callbacks
    
    To avoid recursive lock issues, a copy is taken of the provider list and
    the callbacks are made without holding the store lock.
    
    Fixes #14251
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/14489)

-----------------------------------------------------------------------

Summary of changes:
 crypto/core_algorithm.c                 |  2 +-
 crypto/provider.c                       |  2 +-
 crypto/provider_core.c                  | 85 ++++++++++++++++-----------------
 doc/internal/man3/ossl_provider_new.pod | 18 ++++---
 include/internal/provider.h             |  8 ++--
 5 files changed, 59 insertions(+), 56 deletions(-)

diff --git a/crypto/core_algorithm.c b/crypto/core_algorithm.c
index 6222c5364d..3fcb2226c7 100644
--- a/crypto/core_algorithm.c
+++ b/crypto/core_algorithm.c
@@ -107,7 +107,7 @@ void ossl_algorithm_do_all(OSSL_LIB_CTX *libctx, int operation_id,
     cbdata.data = data;
 
     if (provider == NULL)
-        ossl_provider_forall_loaded(libctx, algorithm_do_this, &cbdata);
+        ossl_provider_doall_activated(libctx, algorithm_do_this, &cbdata);
     else
         algorithm_do_this(provider, &cbdata);
 }
diff --git a/crypto/provider.c b/crypto/provider.c
index 9c94e4e377..bdff44afb9 100644
--- a/crypto/provider.c
+++ b/crypto/provider.c
@@ -134,5 +134,5 @@ int OSSL_PROVIDER_do_all(OSSL_LIB_CTX *ctx,
                                    void *cbdata),
                          void *cbdata)
 {
-    return ossl_provider_forall_loaded(ctx, cb, cbdata);
+    return ossl_provider_doall_activated(ctx, cb, cbdata);
 }
diff --git a/crypto/provider_core.c b/crypto/provider_core.c
index 9536cb65d1..47eda52224 100644
--- a/crypto/provider_core.c
+++ b/crypto/provider_core.c
@@ -726,36 +726,6 @@ void *ossl_provider_ctx(const OSSL_PROVIDER *prov)
     return prov->provctx;
 }
 
-
-static int provider_forall_loaded(struct provider_store_st *store,
-                                  int *found_activated,
-                                  int (*cb)(OSSL_PROVIDER *provider,
-                                            void *cbdata),
-                                  void *cbdata)
-{
-    int i;
-    int ret = 1;
-    int num_provs;
-
-    num_provs = sk_OSSL_PROVIDER_num(store->providers);
-
-    if (found_activated != NULL)
-        *found_activated = 0;
-    for (i = 0; i < num_provs; i++) {
-        OSSL_PROVIDER *prov =
-            sk_OSSL_PROVIDER_value(store->providers, i);
-
-        if (prov->flag_activated) {
-            if (found_activated != NULL)
-                *found_activated = 1;
-            if (!(ret = cb(prov, cbdata)))
-                break;
-        }
-    }
-
-    return ret;
-}
-
 /*
  * This function only does something once when store->use_fallbacks == 1,
  * and then sets store->use_fallbacks = 0, so the second call and so on is
@@ -809,13 +779,14 @@ static void provider_activate_fallbacks(struct provider_store_st *store)
     CRYPTO_THREAD_unlock(store->lock);
 }
 
-int ossl_provider_forall_loaded(OSSL_LIB_CTX *ctx,
-                                int (*cb)(OSSL_PROVIDER *provider,
-                                          void *cbdata),
-                                void *cbdata)
+int ossl_provider_doall_activated(OSSL_LIB_CTX *ctx,
+                                  int (*cb)(OSSL_PROVIDER *provider,
+                                            void *cbdata),
+                                  void *cbdata)
 {
-    int ret = 1;
+    int ret = 0, i, j;
     struct provider_store_st *store = get_provider_store(ctx);
+    STACK_OF(OSSL_PROVIDER) *provs = NULL;
 
 #ifndef FIPS_MODULE
     /*
@@ -825,18 +796,46 @@ int ossl_provider_forall_loaded(OSSL_LIB_CTX *ctx,
     OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL);
 #endif
 
-    if (store != NULL) {
-        provider_activate_fallbacks(store);
-
-        CRYPTO_THREAD_read_lock(store->lock);
-        /*
-         * Now, we sweep through all providers
-         */
-        ret = provider_forall_loaded(store, NULL, cb, cbdata);
+    if (store == NULL)
+        return 1;
+    provider_activate_fallbacks(store);
 
+    /*
+     * Under lock, grab a copy of the provider list and up_ref each
+     * provider so that they don't disappear underneath us.
+     */
+    CRYPTO_THREAD_read_lock(store->lock);
+    provs = sk_OSSL_PROVIDER_dup(store->providers);
+    if (provs == NULL) {
         CRYPTO_THREAD_unlock(store->lock);
+        return 0;
     }
+    j = sk_OSSL_PROVIDER_num(provs);
+    for (i = 0; i < j; i++)
+        if (!ossl_provider_up_ref(sk_OSSL_PROVIDER_value(provs, i)))
+            goto err_unlock;
+    CRYPTO_THREAD_unlock(store->lock);
+
+    /*
+     * Now, we sweep through all providers not under lock
+     */
+    for (j = 0; j < i; j++) {
+        OSSL_PROVIDER *prov = sk_OSSL_PROVIDER_value(provs, j);
 
+        if (prov->flag_activated && !cb(prov, cbdata))
+            goto finish;
+    }
+
+    ret = 1;
+    goto finish;
+
+ err_unlock:
+    CRYPTO_THREAD_unlock(store->lock);
+ finish:
+    /* The pop_free call doesn't do what we want on an error condition */
+    for (j = 0; j < i; j++)
+        ossl_provider_free(sk_OSSL_PROVIDER_value(provs, j));
+    sk_OSSL_PROVIDER_free(provs);
     return ret;
 }
 
diff --git a/doc/internal/man3/ossl_provider_new.pod b/doc/internal/man3/ossl_provider_new.pod
index dbf1e7cc5a..8506839dee 100644
--- a/doc/internal/man3/ossl_provider_new.pod
+++ b/doc/internal/man3/ossl_provider_new.pod
@@ -8,7 +8,7 @@ ossl_provider_set_fallback, ossl_provider_set_module_path,
 ossl_provider_add_parameter,
 ossl_provider_activate, ossl_provider_deactivate, ossl_provider_available,
 ossl_provider_ctx,
-ossl_provider_forall_loaded,
+ossl_provider_doall_activated,
 ossl_provider_name, ossl_provider_dso,
 ossl_provider_module_name, ossl_provider_module_path,
 ossl_provider_libctx,
@@ -50,10 +50,10 @@ ossl_provider_get_capabilities
  void *ossl_provider_ctx(const OSSL_PROVIDER *prov);
 
  /* Iterate over all loaded providers */
- int ossl_provider_forall_loaded(OSSL_LIB_CTX *,
-                                 int (*cb)(OSSL_PROVIDER *provider,
-                                           void *cbdata),
-                                 void *cbdata);
+ int ossl_provider_doall_activated(OSSL_LIB_CTX *,
+                                   int (*cb)(OSSL_PROVIDER *provider,
+                                             void *cbdata),
+                                   void *cbdata);
 
  /* Getters for other library functions */
  const char *ossl_provider_name(OSSL_PROVIDER *prov);
@@ -197,10 +197,10 @@ ossl_provider_ctx() returns a context created by the provider.
 Outside of the provider, it's completely opaque, but it needs to be
 passed back to some of the provider functions.
 
-ossl_provider_forall_loaded() iterates over all the currently
+ossl_provider_doall_activated() iterates over all the currently
 "activated" providers, and calls I<cb> for each of them.
 If no providers have been "activated" yet, it tries to activate all
-available fallback providers and tries another iteration.
+available fallback providers before iterating over them.
 
 ossl_provider_name() returns the name that was given with
 ossl_provider_new().
@@ -287,6 +287,10 @@ it has been incremented.
 
 ossl_provider_free() doesn't return any value.
 
+ossl_provider_doall_activated() returns 1 if the callback was called for all
+activated providers.  A return value of 0 means that the callback was not
+called for any activated providers.
+
 ossl_provider_set_module_path(), ossl_provider_set_fallback(),
 ossl_provider_activate(), ossl_provider_activate_leave_fallbacks() and
 ossl_provider_deactivate() return 1 on success, or 0 on error.
diff --git a/include/internal/provider.h b/include/internal/provider.h
index 7441bf26f0..b755f17325 100644
--- a/include/internal/provider.h
+++ b/include/internal/provider.h
@@ -58,10 +58,10 @@ int ossl_provider_available(OSSL_PROVIDER *prov);
 void *ossl_provider_ctx(const OSSL_PROVIDER *prov);
 
 /* Iterate over all loaded providers */
-int ossl_provider_forall_loaded(OSSL_LIB_CTX *,
-                                int (*cb)(OSSL_PROVIDER *provider,
-                                          void *cbdata),
-                                void *cbdata);
+int ossl_provider_doall_activated(OSSL_LIB_CTX *,
+                                  int (*cb)(OSSL_PROVIDER *provider,
+                                            void *cbdata),
+                                  void *cbdata);
 
 /* Getters for other library functions */
 const char *ossl_provider_name(const OSSL_PROVIDER *prov);


More information about the openssl-commits mailing list