Skip to content

Commit addbd7c

Browse files
committed
Hold the flag_lock when calling child callbacks
Not holding the flag lock when creating/removing child providers can confuse the activation counts if the parent provider is loaded/unloaded at the same time. Reviewed-by: Tomas Mraz <[email protected]> (Merged from openssl#16980)
1 parent 4aced11 commit addbd7c

File tree

1 file changed

+11
-14
lines changed

1 file changed

+11
-14
lines changed

crypto/provider_core.c

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,8 @@
107107
* some other function while holding a lock make sure you know whether it
108108
* will make any upcalls or not. For example ossl_provider_up_ref() can call
109109
* ossl_provider_up_ref_parent() which can call the c_prov_up_ref() upcall.
110-
* - It is permissible to hold the store lock when calling child provider
111-
* callbacks. No other locks may be held during such callbacks.
110+
* - It is permissible to hold the store and flag locks when calling child
111+
* provider callbacks. No other locks may be held during such callbacks.
112112
*/
113113

114114
static OSSL_PROVIDER *provider_new(const char *name,
@@ -1058,9 +1058,6 @@ static int provider_deactivate(OSSL_PROVIDER *prov, int upcalls,
10581058
removechildren = 0;
10591059
#endif
10601060

1061-
if (lock)
1062-
CRYPTO_THREAD_unlock(prov->flag_lock);
1063-
10641061
#ifndef FIPS_MODULE
10651062
if (removechildren && store != NULL) {
10661063
int i, max = sk_OSSL_PROVIDER_CHILD_CB_num(store->child_cbs);
@@ -1072,8 +1069,10 @@ static int provider_deactivate(OSSL_PROVIDER *prov, int upcalls,
10721069
}
10731070
}
10741071
#endif
1075-
if (lock)
1072+
if (lock) {
1073+
CRYPTO_THREAD_unlock(prov->flag_lock);
10761074
CRYPTO_THREAD_unlock(store->lock);
1075+
}
10771076
#ifndef FIPS_MODULE
10781077
if (freeparent)
10791078
ossl_provider_free_parent(prov, 1);
@@ -1091,7 +1090,7 @@ static int provider_activate(OSSL_PROVIDER *prov, int lock, int upcalls)
10911090
{
10921091
int count = -1;
10931092
struct provider_store_st *store;
1094-
int ret = 1, createchildren = 0;
1093+
int ret = 1;
10951094

10961095
store = prov->store;
10971096
/*
@@ -1129,15 +1128,13 @@ static int provider_activate(OSSL_PROVIDER *prov, int lock, int upcalls)
11291128
count = ++prov->activatecnt;
11301129
prov->flag_activated = 1;
11311130

1132-
if (prov->activatecnt == 1 && store != NULL)
1133-
createchildren = 1;
1134-
1135-
if (lock)
1136-
CRYPTO_THREAD_unlock(prov->flag_lock);
1137-
if (createchildren)
1131+
if (prov->activatecnt == 1 && store != NULL) {
11381132
ret = create_provider_children(prov);
1139-
if (lock)
1133+
}
1134+
if (lock) {
1135+
CRYPTO_THREAD_unlock(prov->flag_lock);
11401136
CRYPTO_THREAD_unlock(store->lock);
1137+
}
11411138

11421139
if (!ret)
11431140
return -1;

0 commit comments

Comments
 (0)