NULL the thread_local_inits_st pointer after use
authorMatt Caswell <matt@openssl.org>
Tue, 9 Feb 2016 23:09:44 +0000 (23:09 +0000)
committerMatt Caswell <matt@openssl.org>
Tue, 9 Feb 2016 23:29:31 +0000 (23:29 +0000)
After the final use of the thread_local_inits_st we should ensure it is
set to NULL, just in case OPENSSL_INIT_thread_stop gets called again and
it tries to use garbage.

Reviewed-by: Rich Salz <rsalz@openssl.org>
crypto/include/internal/cryptlib_int.h
crypto/init.c

index 36c0a10e036f3d8aad2031418d7e1455f3a2e4ce..0e457623ff60147be1817f2646dbc484979156fd 100644 (file)
@@ -63,7 +63,7 @@ struct thread_local_inits_st {
     int async;
     int err_state;
 };
-void *ossl_init_get_thread_local(int alloc);
+
 int ossl_init_thread_start(uint64_t opts);
 /*
  * OPENSSL_INIT flags. The primary list of these is in crypto.h. Flags below
index b9cc6a1f76556bb4339be10a81844263fec83bb8..f23227e60a6c97dd998e3e61aad304807539e855 100644 (file)
@@ -95,11 +95,19 @@ static void ossl_init_thread_stop_cleanup(void)
 }
 
 static struct thread_local_inits_st *local = NULL;
-void *ossl_init_get_thread_local(int alloc)
+static struct thread_local_inits_st *ossl_init_get_thread_local(int alloc)
 {
+    static struct thread_local_inits_st *tmp;
+
+    tmp = local;
+
     if (local == NULL && alloc)
-        local = OPENSSL_zalloc(sizeof(*local));
-    return local;
+        tmp = local = OPENSSL_zalloc(sizeof(*local));
+
+    if (!alloc)
+        local = NULL;
+
+    return tmp;
 }
 
 #elif defined(OPENSSL_SYS_WINDOWS)
@@ -182,7 +190,7 @@ static void ossl_init_thread_stop_cleanup(void)
     }
 }
 
-void *ossl_init_get_thread_local(int alloc)
+static struct thread_local_inits_st *ossl_init_get_thread_local(int alloc)
 {
     struct thread_local_inits_st *local = TlsGetValue(threadstopkey);
 
@@ -190,6 +198,9 @@ void *ossl_init_get_thread_local(int alloc)
         local = OPENSSL_zalloc(sizeof *local);
         TlsSetValue(threadstopkey, local);
     }
+    if (!alloc) {
+        TlsSetValue(threadstopkey, NULL);
+    }
 
     return local;
 }
@@ -227,7 +238,7 @@ static void ossl_init_thread_stop_cleanup(void)
 {
 }
 
-void *ossl_init_get_thread_local(int alloc)
+static struct thread_local_inits_st *ossl_init_get_thread_local(int alloc)
 {
     struct thread_local_inits_st *local = pthread_getspecific(threadstopkey);
 
@@ -235,6 +246,9 @@ void *ossl_init_get_thread_local(int alloc)
         local = OPENSSL_zalloc(sizeof *local);
         pthread_setspecific(threadstopkey, local);
     }
+    if (!alloc) {
+        pthread_setspecific(threadstopkey, NULL);
+    }
 
     return local;
 }