summaryrefslogtreecommitdiffstats
path: root/crypto/evp
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2022-04-14 17:52:12 +0200
committerHugo Landau <hlandau@openssl.org>2022-07-20 07:29:23 +0100
commitddb81a94ac8af145750940c20999ac952165bf10 (patch)
treeae3a45943d31abc5533680c7dd25aacf83f08977 /crypto/evp
parentd3cc10eb0ee31a3950bb310c8201614fb076f759 (diff)
"Reserve" the method store when constructing methods
Introducing the concept of reserving the store where a number of provided operation methods are to be stored. This avoids racing when constructing provided methods, which is especially pertinent when multiple threads are trying to fetch the same method, or even any implementation for the same given operation type. This introduces a |biglock| in OSSL_METHOD_STORE, which is separate from the |lock| which is used for more internal and finer grained locking. Fixes #18152 Reviewed-by: Hugo Landau <hlandau@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/18153) (cherry picked from commit e1eafe8c87612a94552e9ad5df56c489cb6f0ff2)
Diffstat (limited to 'crypto/evp')
-rw-r--r--crypto/evp/evp_fetch.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/crypto/evp/evp_fetch.c b/crypto/evp/evp_fetch.c
index 90d6a4e6d4..aafd927e63 100644
--- a/crypto/evp/evp_fetch.c
+++ b/crypto/evp/evp_fetch.c
@@ -83,6 +83,28 @@ static OSSL_METHOD_STORE *get_evp_method_store(OSSL_LIB_CTX *libctx)
&evp_method_store_method);
}
+static int reserve_evp_method_store(void *store, void *data)
+{
+ struct evp_method_data_st *methdata = data;
+
+ if (store == NULL
+ && (store = get_evp_method_store(methdata->libctx)) == NULL)
+ return 0;
+
+ return ossl_method_lock_store(store);
+}
+
+static int unreserve_evp_method_store(void *store, void *data)
+{
+ struct evp_method_data_st *methdata = data;
+
+ if (store == NULL
+ && (store = get_evp_method_store(methdata->libctx)) == NULL)
+ return 0;
+
+ return ossl_method_unlock_store(store);
+}
+
/*
* To identify the method in the EVP method store, we mix the name identity
* with the operation identity, under the assumption that we don't have more
@@ -303,6 +325,8 @@ inner_evp_generic_fetch(struct evp_method_data_st *methdata,
|| !ossl_method_store_cache_get(store, prov, meth_id, propq, &method)) {
OSSL_METHOD_CONSTRUCT_METHOD mcm = {
get_tmp_evp_method_store,
+ reserve_evp_method_store,
+ unreserve_evp_method_store,
get_evp_method_from_store,
put_evp_method_in_store,
construct_evp_method,