summaryrefslogtreecommitdiffstats
path: root/crypto/conf
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2022-06-02 13:54:45 +0100
committerTomas Mraz <tomas@openssl.org>2022-06-06 08:53:38 +0200
commit697d0b5ba146c232f5b2aa87f4e847a5495c1735 (patch)
treef6782bdce79a385114ff431de7a6f1d231ca054a /crypto/conf
parent1a01e5c29dfaf09af3960b4c8e6ec0f8171eda80 (diff)
CONF_modules_unload should fail if CONF_modules_finish fails
The module_list_lock is used by CONF_modules_unload(). That function relies on the RUN_ONCE in CONF_modules_finish() to initialise that lock. However if the RUN_ONCE fails that failure is not propagated to CONF_modules_unload() and so it erroneously tries to use the lock anyway. Found due to: https://github.com/openssl/openssl/pull/18355#issuecomment-1144734604 Reviewed-by: Todd Short <todd.short@me.com> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/18460)
Diffstat (limited to 'crypto/conf')
-rw-r--r--crypto/conf/conf_mod.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/crypto/conf/conf_mod.c b/crypto/conf/conf_mod.c
index 6286282108..c6b8696388 100644
--- a/crypto/conf/conf_mod.c
+++ b/crypto/conf/conf_mod.c
@@ -82,6 +82,8 @@ static int module_init(CONF_MODULE *pmod, const char *name, const char *value,
static CONF_MODULE *module_load_dso(const CONF *cnf, const char *name,
const char *value);
+static int conf_modules_finish_int(void);
+
static void module_lists_free(void)
{
CRYPTO_THREAD_lock_free(module_list_lock);
@@ -477,7 +479,8 @@ void CONF_modules_unload(int all)
int i;
CONF_MODULE *md;
- CONF_modules_finish(); /* also inits module list lock */
+ if (!conf_modules_finish_int()) /* also inits module list lock */
+ return;
if (!CRYPTO_THREAD_write_lock(module_list_lock))
return;
@@ -511,15 +514,15 @@ static void module_free(CONF_MODULE *md)
/* finish and free up all modules instances */
-void CONF_modules_finish(void)
+static int conf_modules_finish_int(void)
{
CONF_IMODULE *imod;
if (!RUN_ONCE(&init_module_list_lock, do_init_module_list_lock))
- return;
+ return 0;
if (!CRYPTO_THREAD_write_lock(module_list_lock))
- return;
+ return 0;
while (sk_CONF_IMODULE_num(initialized_modules) > 0) {
imod = sk_CONF_IMODULE_pop(initialized_modules);
@@ -529,6 +532,13 @@ void CONF_modules_finish(void)
initialized_modules = NULL;
CRYPTO_THREAD_unlock(module_list_lock);
+
+ return 1;
+}
+
+void CONF_modules_finish(void)
+{
+ conf_modules_finish_int();
}
/* finish a module instance */