]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Fix calling pthread_key_delete on uninitialized data
authorPetr Mikhalicin <mkh199740@mail.ru>
Fri, 21 Apr 2023 09:25:43 +0000 (12:25 +0300)
committerTomas Mraz <tomas@openssl.org>
Mon, 24 Apr 2023 09:31:57 +0000 (11:31 +0200)
default_context_do_init may be never called and CRYPTO_THREAD_init_local
inside it may be never called too. But corresponding
CRYPTO_THREAD_cleanup_local is always called at cleanup stage. This lead
to undefined behavior.

So, add flag to check that default_context_do_init will be called
successfully or not.

Fix: #20697

Reviewed-by: Hugo Landau <hlandau@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/20801)

crypto/context.c

index dcd9a1396b69201a9c5dbfe379bc197023239413..b097b58cd538919c031f06faf46d5554408f2c7c 100644 (file)
@@ -348,17 +348,32 @@ static OSSL_LIB_CTX default_context_int;
 
 static CRYPTO_ONCE default_context_init = CRYPTO_ONCE_STATIC_INIT;
 static CRYPTO_THREAD_LOCAL default_context_thread_local;
+static int default_context_inited = 0;
 
 DEFINE_RUN_ONCE_STATIC(default_context_do_init)
 {
-    return CRYPTO_THREAD_init_local(&default_context_thread_local, NULL)
-        && context_init(&default_context_int);
+    if (!CRYPTO_THREAD_init_local(&default_context_thread_local, NULL))
+        goto err;
+
+    if (!context_init(&default_context_int))
+        goto deinit_thread;
+
+    default_context_inited = 1;
+    return 1;
+
+deinit_thread:
+    CRYPTO_THREAD_cleanup_local(&default_context_thread_local);
+err:
+    return 0;
 }
 
 void ossl_lib_ctx_default_deinit(void)
 {
+    if (!default_context_inited)
+        return;
     context_deinit(&default_context_int);
     CRYPTO_THREAD_cleanup_local(&default_context_thread_local);
+    default_context_inited = 0;
 }
 
 static OSSL_LIB_CTX *get_thread_default_context(void)