Commit 79cd5c9bdc for openssl.org
commit 79cd5c9bdc9a898c468bc3a9d5efa8fdb1549e35
Author: Neil Horman <nhorman@openssl.org>
Date: Tue Apr 28 17:08:43 2026 -0400
remove read lock from method store cache lookup
Reviewed-by: Saša NedvÄ›dický <sashan@openssl.org>
Reviewed-by: Bob Beck <beck@openssl.org>
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
MergeDate: Tue Jun 9 18:17:12 2026
(Merged from https://github.com/openssl/openssl/pull/31018)
diff --git a/crypto/property/property.c b/crypto/property/property.c
index dbc27c4f9b..34736da529 100644
--- a/crypto/property/property.c
+++ b/crypto/property/property.c
@@ -18,6 +18,7 @@
#include "internal/hashtable.h"
#include "internal/hashfunc.h"
#include "internal/tsan_assist.h"
+#include "internal/threads_common.h"
#include "internal/list.h"
#include "internal/time.h"
#include <openssl/lhash.h>
@@ -935,17 +936,12 @@ static ossl_inline int ossl_method_store_cache_get_locked(OSSL_METHOD_STORE *sto
int nid, const char *prop_query, size_t keylen, STORED_ALGORITHMS *sa, QUERY **post_insert,
void **method)
{
- ALGORITHM *alg;
uint64_t prop_hash;
QUERY *r = NULL;
int res = 0;
*post_insert = NULL;
- alg = ossl_method_store_retrieve(sa, nid);
- if (alg == NULL)
- goto err;
-
prop_hash = ossl_fnv1a_hash((uint8_t *)prop_query, strlen(prop_query));
r = ossl_method_store_atomic_find_in_list(sa, nid, prov, prop_hash);
@@ -954,7 +950,7 @@ static ossl_inline int ossl_method_store_cache_get_locked(OSSL_METHOD_STORE *sto
*method = r->method.method;
res = 1;
}
-err:
+
return res;
}
@@ -974,8 +970,6 @@ int ossl_method_store_cache_get(OSSL_METHOD_STORE *store, OSSL_PROVIDER *prov,
return 0;
sa = stored_algs_shard(store, nid);
- if (!ossl_property_read_lock(sa))
- return 0;
/*
* Note: We've bifurcated this function into a locked and unlocked variant
@@ -988,8 +982,6 @@ int ossl_method_store_cache_get(OSSL_METHOD_STORE *store, OSSL_PROVIDER *prov,
ret = ossl_method_store_cache_get_locked(store, prov, nid, prop_query, keylen, sa,
&post_insert, method);
- ossl_property_unlock(sa);
-
return ret;
}
@@ -1075,7 +1067,7 @@ static ossl_inline int ossl_method_store_cache_set_locked(OSSL_METHOD_STORE *sto
int (*method_up_ref)(void *),
void (*method_destruct)(void *))
{
- QUERY *old = NULL, *p = NULL;
+ QUERY *p = NULL;
ALGORITHM *alg;
uint64_t prop_hash = ossl_fnv1a_hash((uint8_t *)prop_query, strlen(prop_query));
int res = 1;
@@ -1100,6 +1092,7 @@ static ossl_inline int ossl_method_store_cache_set_locked(OSSL_METHOD_STORE *sto
}
p = OPENSSL_malloc(sizeof(*p));
if (p != NULL) {
+ TSAN_BENIGN(p, "Unpublished value is safe on subsequent read");
p->saptr = sa;
p->nid = nid;
p->prov = prov;
@@ -1119,10 +1112,10 @@ static ossl_inline int ossl_method_store_cache_set_locked(OSSL_METHOD_STORE *sto
* from nid and property query. This lets us match in the event someone does a lookup
* against a NULL provider (i.e. the "any provided alg will do" match
*/
- old = p;
p = OPENSSL_memdup(p, sizeof(*p));
if (p == NULL)
goto err;
+ TSAN_BENIGN(p, "Unpublished value is safe on subsequent read");
p->prov = NULL;
ossl_list_lru_entry_init_elem(p);
if (!ossl_method_up_ref(&p->method))
diff --git a/include/internal/threads_common.h b/include/internal/threads_common.h
index 1f54eadf82..b6dea47ab9 100644
--- a/include/internal/threads_common.h
+++ b/include/internal/threads_common.h
@@ -23,7 +23,7 @@
extern void AnnotateBenignRaceSized(const char *f, int l,
const volatile void *mem, unsigned int size, const char *desc);
#define TSAN_BENIGN(x, desc) \
- AnnotateBenignRaceSized(__FILE__, __LINE__, &(x), sizeof(x), desc);
+ AnnotateBenignRaceSized(__FILE__, __LINE__, (x), sizeof(*(x)), desc);
#else
#define TSAN_BENIGN(x, desc)
#endif
diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c
index fe8507f179..3292dce334 100644
--- a/providers/fips/fipsprov.c
+++ b/providers/fips/fipsprov.c
@@ -1414,7 +1414,7 @@ int ossl_deferred_self_test(OSSL_LIB_CTX *libctx, self_test_id_t id)
* and then it will recheck this value and immediately exit.
*/
- TSAN_BENIGN(st_all_tests[id].state, "Fails safe, avoids contention")
+ TSAN_BENIGN(&st_all_tests[id].state, "Fails safe, avoids contention")
if (st_all_tests[id].state == SELF_TEST_STATE_PASSED)
return 1;