mirror of
https://github.com/QuasarApp/openssl.git
synced 2025-04-28 18:54:36 +00:00
Fix an issue in provider_activate_fallbacks()
The above function was running while holding the store lock with a read lock. Unfortunately it actually modifies the store, so a write lock is required instead. Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org> (Merged from https://github.com/openssl/openssl/pull/13660)
This commit is contained in:
parent
b457c8f514
commit
7dd2cb5693
@ -729,34 +729,50 @@ static int provider_forall_loaded(struct provider_store_st *store,
|
||||
*/
|
||||
static void provider_activate_fallbacks(struct provider_store_st *store)
|
||||
{
|
||||
if (store->use_fallbacks) {
|
||||
int num_provs = sk_OSSL_PROVIDER_num(store->providers);
|
||||
int activated_fallback_count = 0;
|
||||
int i;
|
||||
int use_fallbacks;
|
||||
int num_provs;
|
||||
int activated_fallback_count = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_provs; i++) {
|
||||
OSSL_PROVIDER *prov = sk_OSSL_PROVIDER_value(store->providers, i);
|
||||
CRYPTO_THREAD_read_lock(store->lock);
|
||||
use_fallbacks = store->use_fallbacks;
|
||||
CRYPTO_THREAD_unlock(store->lock);
|
||||
if (!use_fallbacks)
|
||||
return;
|
||||
|
||||
if (ossl_provider_up_ref(prov)) {
|
||||
if (prov->flag_fallback) {
|
||||
if (provider_activate(prov)) {
|
||||
prov->flag_activated_as_fallback = 1;
|
||||
activated_fallback_count++;
|
||||
}
|
||||
}
|
||||
ossl_provider_free(prov);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We assume that all fallbacks have been added to the store before
|
||||
* any fallback is activated.
|
||||
* TODO: We may have to reconsider this, IF we find ourselves adding
|
||||
* fallbacks after any previous fallback has been activated.
|
||||
*/
|
||||
if (activated_fallback_count > 0)
|
||||
store->use_fallbacks = 0;
|
||||
CRYPTO_THREAD_write_lock(store->lock);
|
||||
/* Check again, just in case another thread changed it */
|
||||
use_fallbacks = store->use_fallbacks;
|
||||
if (!use_fallbacks) {
|
||||
CRYPTO_THREAD_unlock(store->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
num_provs = sk_OSSL_PROVIDER_num(store->providers);
|
||||
for (i = 0; i < num_provs; i++) {
|
||||
OSSL_PROVIDER *prov = sk_OSSL_PROVIDER_value(store->providers, i);
|
||||
|
||||
if (ossl_provider_up_ref(prov)) {
|
||||
if (prov->flag_fallback) {
|
||||
if (provider_activate(prov)) {
|
||||
prov->flag_activated_as_fallback = 1;
|
||||
activated_fallback_count++;
|
||||
}
|
||||
}
|
||||
ossl_provider_free(prov);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We assume that all fallbacks have been added to the store before
|
||||
* any fallback is activated.
|
||||
* TODO: We may have to reconsider this, IF we find ourselves adding
|
||||
* fallbacks after any previous fallback has been activated.
|
||||
*/
|
||||
if (activated_fallback_count > 0)
|
||||
store->use_fallbacks = 0;
|
||||
|
||||
CRYPTO_THREAD_unlock(store->lock);
|
||||
}
|
||||
|
||||
int ossl_provider_forall_loaded(OSSL_LIB_CTX *ctx,
|
||||
@ -776,10 +792,9 @@ int ossl_provider_forall_loaded(OSSL_LIB_CTX *ctx,
|
||||
#endif
|
||||
|
||||
if (store != NULL) {
|
||||
CRYPTO_THREAD_read_lock(store->lock);
|
||||
|
||||
provider_activate_fallbacks(store);
|
||||
|
||||
CRYPTO_THREAD_read_lock(store->lock);
|
||||
/*
|
||||
* Now, we sweep through all providers
|
||||
*/
|
||||
@ -794,9 +809,7 @@ int ossl_provider_forall_loaded(OSSL_LIB_CTX *ctx,
|
||||
int ossl_provider_available(OSSL_PROVIDER *prov)
|
||||
{
|
||||
if (prov != NULL) {
|
||||
CRYPTO_THREAD_read_lock(prov->store->lock);
|
||||
provider_activate_fallbacks(prov->store);
|
||||
CRYPTO_THREAD_unlock(prov->store->lock);
|
||||
|
||||
return prov->flag_activated;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user