summaryrefslogtreecommitdiff
path: root/crypto/encode_decode
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:28:17 +0100
commite1eafe8c87612a94552e9ad5df56c489cb6f0ff2 (patch)
tree1f5bc3b2087f9280313f3b59a43509a897d62508 /crypto/encode_decode
parentd768f853bb05b5a49a2aeb5b5702776834e68d06 (diff)
downloadopenssl-new-e1eafe8c87612a94552e9ad5df56c489cb6f0ff2.tar.gz
"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)
Diffstat (limited to 'crypto/encode_decode')
-rw-r--r--crypto/encode_decode/decoder_meth.c24
-rw-r--r--crypto/encode_decode/encoder_meth.c24
2 files changed, 48 insertions, 0 deletions
diff --git a/crypto/encode_decode/decoder_meth.c b/crypto/encode_decode/decoder_meth.c
index 11e94dbcc4..74c86a8fe8 100644
--- a/crypto/encode_decode/decoder_meth.c
+++ b/crypto/encode_decode/decoder_meth.c
@@ -105,6 +105,28 @@ static OSSL_METHOD_STORE *get_decoder_store(OSSL_LIB_CTX *libctx)
return ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_DECODER_STORE_INDEX);
}
+static int reserve_decoder_store(void *store, void *data)
+{
+ struct decoder_data_st *methdata = data;
+
+ if (store == NULL
+ && (store = get_decoder_store(methdata->libctx)) == NULL)
+ return 0;
+
+ return ossl_method_lock_store(store);
+}
+
+static int unreserve_decoder_store(void *store, void *data)
+{
+ struct decoder_data_st *methdata = data;
+
+ if (store == NULL
+ && (store = get_decoder_store(methdata->libctx)) == NULL)
+ return 0;
+
+ return ossl_method_unlock_store(store);
+}
+
/* Get decoder methods from a store, or put one in */
static void *get_decoder_from_store(void *store, const OSSL_PROVIDER **prov,
void *data)
@@ -344,6 +366,8 @@ inner_ossl_decoder_fetch(struct decoder_data_st *methdata,
|| !ossl_method_store_cache_get(store, NULL, id, propq, &method)) {
OSSL_METHOD_CONSTRUCT_METHOD mcm = {
get_tmp_decoder_store,
+ reserve_decoder_store,
+ unreserve_decoder_store,
get_decoder_from_store,
put_decoder_in_store,
construct_decoder,
diff --git a/crypto/encode_decode/encoder_meth.c b/crypto/encode_decode/encoder_meth.c
index 7a28894b2c..7092ba7ef8 100644
--- a/crypto/encode_decode/encoder_meth.c
+++ b/crypto/encode_decode/encoder_meth.c
@@ -105,6 +105,28 @@ static OSSL_METHOD_STORE *get_encoder_store(OSSL_LIB_CTX *libctx)
return ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_ENCODER_STORE_INDEX);
}
+static int reserve_encoder_store(void *store, void *data)
+{
+ struct encoder_data_st *methdata = data;
+
+ if (store == NULL
+ && (store = get_encoder_store(methdata->libctx)) == NULL)
+ return 0;
+
+ return ossl_method_lock_store(store);
+}
+
+static int unreserve_encoder_store(void *store, void *data)
+{
+ struct encoder_data_st *methdata = data;
+
+ if (store == NULL
+ && (store = get_encoder_store(methdata->libctx)) == NULL)
+ return 0;
+
+ return ossl_method_unlock_store(store);
+}
+
/* Get encoder methods from a store, or put one in */
static void *get_encoder_from_store(void *store, const OSSL_PROVIDER **prov,
void *data)
@@ -354,6 +376,8 @@ inner_ossl_encoder_fetch(struct encoder_data_st *methdata,
|| !ossl_method_store_cache_get(store, NULL, id, propq, &method)) {
OSSL_METHOD_CONSTRUCT_METHOD mcm = {
get_tmp_encoder_store,
+ reserve_encoder_store,
+ unreserve_encoder_store,
get_encoder_from_store,
put_encoder_in_store,
construct_encoder,