summaryrefslogtreecommitdiffstats
path: root/crypto/core_fetch.c
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2021-01-12 16:50:17 +0000
committerMatt Caswell <matt@openssl.org>2021-01-14 17:30:46 +0000
commitb11ba50fd9bd3c33e1627ca5c64f08b403e88173 (patch)
tree36ad101a7314dd26aa660ac045851cc6ae0c3d3e /crypto/core_fetch.c
parent7dd2cb569358591bb832af66fdabd6a6c580c1d4 (diff)
Fix a failure where fetches can return NULL in multi-threaded code
When a fetch is attempted simultaneously from multiple threads then both threads can attempt to construct the method. However only one of those will get added to the global evp method store. The one that "lost" the race to add the method to the global evp method store ended up with the fetch call returning NULL, instead of returning the method that was already available. Fixes #13682 Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org> (Merged from https://github.com/openssl/openssl/pull/13660)
Diffstat (limited to 'crypto/core_fetch.c')
-rw-r--r--crypto/core_fetch.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/crypto/core_fetch.c b/crypto/core_fetch.c
index 4fb432754b..12d52a03d0 100644
--- a/crypto/core_fetch.c
+++ b/crypto/core_fetch.c
@@ -128,6 +128,16 @@ void *ossl_method_construct(OSSL_LIB_CTX *libctx, int operation_id,
&cbdata);
method = mcm->get(libctx, cbdata.store, mcm_data);
+ if (method == NULL) {
+ /*
+ * If we get here then we did not construct the method that we
+ * attempted to construct. It's possible that another thread got
+ * there first and so we skipped construction (pre-condition
+ * failed). We check the global store again to see if it has
+ * appeared by now.
+ */
+ method = mcm->get(libctx, NULL, mcm_data);
+ }
mcm->dealloc_tmp_store(cbdata.store);
}