[openssl] master update

Dr. Paul Dale pauli at openssl.org
Thu Jan 13 10:47:41 UTC 2022


The branch master has been updated
       via  3d4d5305c292f5db62b4abf732f6682b2ada6f44 (commit)
       via  8ff861dcee38a41ce93374753e8c462e4b9012e2 (commit)
       via  43f132778b138870120d965f2fb61aa7411b78b2 (commit)
       via  5c41cee225094e6298799b709278b0431643fb1f (commit)
       via  e6b8f359e79cdbe09033d02eaad7ecb4e24adb73 (commit)
       via  d8ed9e4a9079b55a84bdbbc3172d36aa3be8bed7 (commit)
       via  e22cbe5e67461470590e6fb8858c95285fcdea0e (commit)
       via  1fc97807d3a3b5e3065a7df80d1ad3601ccc5e2f (commit)
      from  9c5d1451292566e546d5dd01c7f19950fa34391d (commit)


- Log -----------------------------------------------------------------
commit 3d4d5305c292f5db62b4abf732f6682b2ada6f44
Author: Pauli <pauli at openssl.org>
Date:   Wed Jan 12 14:22:29 2022 +1100

    threadstest: use locking for tsan operations if required
    
    Not all platforms support tsan operations, those that don't need to have an
    alternative locking path.
    
    Fixes #17447
    
    Reviewed-by: Bernd Edlinger <bernd.edlinger at hotmail.de>
    (Merged from https://github.com/openssl/openssl/pull/17479)

commit 8ff861dcee38a41ce93374753e8c462e4b9012e2
Author: Pauli <pauli at openssl.org>
Date:   Wed Jan 12 15:01:17 2022 +1100

    drbg: add handling for cases where TSAN isn't available
    
    Most of the DRGB code is run under lock from the EVP layer.  This is relied
    on to make the majority of TSAN operations safe.  However, it is still necessary
    to enable locking for all DRBGs created.
    
    Reviewed-by: Bernd Edlinger <bernd.edlinger at hotmail.de>
    (Merged from https://github.com/openssl/openssl/pull/17479)

commit 43f132778b138870120d965f2fb61aa7411b78b2
Author: Pauli <pauli at openssl.org>
Date:   Wed Jan 12 14:45:07 2022 +1100

    lhash: use lock when TSAN not available for statistics gathering
    
    Reviewed-by: Bernd Edlinger <bernd.edlinger at hotmail.de>
    (Merged from https://github.com/openssl/openssl/pull/17479)

commit 5c41cee225094e6298799b709278b0431643fb1f
Author: Pauli <pauli at openssl.org>
Date:   Wed Jan 12 14:25:46 2022 +1100

    mem: do not produce usage counts when tsan is unavailable.
    
    Doing the tsan operations under lock would be difficult to arrange here (locks
    require memory allocation).
    
    Reviewed-by: Bernd Edlinger <bernd.edlinger at hotmail.de>
    (Merged from https://github.com/openssl/openssl/pull/17479)

commit e6b8f359e79cdbe09033d02eaad7ecb4e24adb73
Author: Pauli <pauli at openssl.org>
Date:   Wed Jan 12 14:25:35 2022 +1100

    object: use updated tsan lock detection capabilities
    
    Reviewed-by: Bernd Edlinger <bernd.edlinger at hotmail.de>
    (Merged from https://github.com/openssl/openssl/pull/17479)

commit d8ed9e4a9079b55a84bdbbc3172d36aa3be8bed7
Author: Pauli <pauli at openssl.org>
Date:   Wed Jan 12 14:22:23 2022 +1100

    core namemap: use updated tsan lock detection capabilities
    
    Reviewed-by: Bernd Edlinger <bernd.edlinger at hotmail.de>
    (Merged from https://github.com/openssl/openssl/pull/17479)

commit e22cbe5e67461470590e6fb8858c95285fcdea0e
Author: Pauli <pauli at openssl.org>
Date:   Wed Jan 12 13:26:38 2022 +1100

    tsan: make detecting the need for locking when using tsan easier
    
    Reviewed-by: Bernd Edlinger <bernd.edlinger at hotmail.de>
    (Merged from https://github.com/openssl/openssl/pull/17479)

commit 1fc97807d3a3b5e3065a7df80d1ad3601ccc5e2f
Author: Pauli <pauli at openssl.org>
Date:   Wed Jan 12 14:24:49 2022 +1100

    threadstest: add write check to lock checking
    
    Reviewed-by: Bernd Edlinger <bernd.edlinger at hotmail.de>
    (Merged from https://github.com/openssl/openssl/pull/17479)

-----------------------------------------------------------------------

Summary of changes:
 crypto/core_namemap.c                  | 15 ++++------
 crypto/lhash/lh_stats.c                | 25 ++++++++++++----
 crypto/lhash/lhash.c                   | 55 ++++++++++++++++++++++++++--------
 crypto/lhash/lhash_local.h             |  3 ++
 crypto/mem.c                           | 14 ++++++---
 crypto/objects/obj_dat.c               | 20 ++++---------
 include/internal/tsan_assist.h         |  8 ++++-
 providers/implementations/rands/drbg.c |  4 +++
 test/threadstest.c                     | 30 +++++++++++++++++--
 9 files changed, 126 insertions(+), 48 deletions(-)

diff --git a/crypto/core_namemap.c b/crypto/core_namemap.c
index 2bee5ef194..6cb0ec5a06 100644
--- a/crypto/core_namemap.c
+++ b/crypto/core_namemap.c
@@ -37,11 +37,7 @@ struct ossl_namemap_st {
     CRYPTO_RWLOCK *lock;
     LHASH_OF(NAMENUM_ENTRY) *namenum;  /* Name->number mapping */
 
-#ifdef tsan_ld_acq
-    TSAN_QUALIFIER int max_number;     /* Current max number TSAN version */
-#else
-    int max_number;                    /* Current max number plain version */
-#endif
+    TSAN_QUALIFIER int max_number;     /* Current max number */
 };
 
 /* LHASH callbacks */
@@ -99,10 +95,7 @@ static const OSSL_LIB_CTX_METHOD stored_namemap_method = {
 
 int ossl_namemap_empty(OSSL_NAMEMAP *namemap)
 {
-#ifdef tsan_ld_acq
-    /* Have TSAN support */
-    return namemap == NULL || tsan_load(&namemap->max_number) == 0;
-#else
+#ifdef TSAN_REQUIRES_LOCKING
     /* No TSAN support */
     int rv;
 
@@ -114,6 +107,9 @@ int ossl_namemap_empty(OSSL_NAMEMAP *namemap)
     rv = namemap->max_number == 0;
     CRYPTO_THREAD_unlock(namemap->lock);
     return rv;
+#else
+    /* Have TSAN support */
+    return namemap == NULL || tsan_load(&namemap->max_number) == 0;
 #endif
 }
 
@@ -260,6 +256,7 @@ static int namemap_add_name_n(OSSL_NAMEMAP *namemap, int number,
         || (namenum->name = OPENSSL_strndup(name, name_len)) == NULL)
         goto err;
 
+    /* The tsan_counter use here is safe since we're under lock */
     namenum->number =
         number != 0 ? number : 1 + tsan_counter(&namemap->max_number);
     (void)lh_NAMENUM_ENTRY_insert(namemap->namenum, namenum);
diff --git a/crypto/lhash/lh_stats.c b/crypto/lhash/lh_stats.c
index 5e38c42580..0d4bc72608 100644
--- a/crypto/lhash/lh_stats.c
+++ b/crypto/lhash/lh_stats.c
@@ -61,6 +61,14 @@ void OPENSSL_LH_node_usage_stats(const OPENSSL_LHASH *lh, FILE *fp)
 
 void OPENSSL_LH_stats_bio(const OPENSSL_LHASH *lh, BIO *out)
 {
+    int omit_tsan = 0;
+
+#ifdef TSAN_REQUIRES_LOCKING
+    if (!CRYPTO_THREAD_read_lock(lh->tsan_lock)) {
+        BIO_printf(out, "unable to lock table, omitting TSAN counters\n");
+        omit_tsan = 1;
+    }
+#endif
     BIO_printf(out, "num_items             = %lu\n", lh->num_items);
     BIO_printf(out, "num_nodes             = %u\n",  lh->num_nodes);
     BIO_printf(out, "num_alloc_nodes       = %u\n",  lh->num_alloc_nodes);
@@ -68,15 +76,22 @@ void OPENSSL_LH_stats_bio(const OPENSSL_LHASH *lh, BIO *out)
     BIO_printf(out, "num_expand_reallocs   = %lu\n", lh->num_expand_reallocs);
     BIO_printf(out, "num_contracts         = %lu\n", lh->num_contracts);
     BIO_printf(out, "num_contract_reallocs = %lu\n", lh->num_contract_reallocs);
-    BIO_printf(out, "num_hash_calls        = %lu\n", lh->num_hash_calls);
-    BIO_printf(out, "num_comp_calls        = %lu\n", lh->num_comp_calls);
+    if (!omit_tsan) {
+        BIO_printf(out, "num_hash_calls        = %lu\n", lh->num_hash_calls);
+        BIO_printf(out, "num_comp_calls        = %lu\n", lh->num_comp_calls);
+    }
     BIO_printf(out, "num_insert            = %lu\n", lh->num_insert);
     BIO_printf(out, "num_replace           = %lu\n", lh->num_replace);
     BIO_printf(out, "num_delete            = %lu\n", lh->num_delete);
     BIO_printf(out, "num_no_delete         = %lu\n", lh->num_no_delete);
-    BIO_printf(out, "num_retrieve          = %lu\n", lh->num_retrieve);
-    BIO_printf(out, "num_retrieve_miss     = %lu\n", lh->num_retrieve_miss);
-    BIO_printf(out, "num_hash_comps        = %lu\n", lh->num_hash_comps);
+    if (!omit_tsan) {
+        BIO_printf(out, "num_retrieve          = %lu\n", lh->num_retrieve);
+        BIO_printf(out, "num_retrieve_miss     = %lu\n", lh->num_retrieve_miss);
+        BIO_printf(out, "num_hash_comps        = %lu\n", lh->num_hash_comps);
+#ifdef TSAN_REQUIRES_LOCKING
+        CRYPTO_THREAD_unlock(lh->tsan_lock);
+#endif
+    }
 }
 
 void OPENSSL_LH_node_stats_bio(const OPENSSL_LHASH *lh, BIO *out)
diff --git a/crypto/lhash/lhash.c b/crypto/lhash/lhash.c
index b2fa4c518b..62e2be4c18 100644
--- a/crypto/lhash/lhash.c
+++ b/crypto/lhash/lhash.c
@@ -44,6 +44,22 @@ static int expand(OPENSSL_LHASH *lh);
 static void contract(OPENSSL_LHASH *lh);
 static OPENSSL_LH_NODE **getrn(OPENSSL_LHASH *lh, const void *data, unsigned long *rhash);
 
+static ossl_inline int tsan_lock(const OPENSSL_LHASH *lh)
+{
+#ifdef TSAN_REQUIRES_LOCKING
+    if (!CRYPTO_THREAD_write_lock(lh->tsan_lock))
+        return 0;
+#endif
+    return 1;
+}
+
+static ossl_inline void tsan_unlock(const OPENSSL_LHASH *lh)
+{
+#ifdef TSAN_REQUIRES_LOCKING
+    CRYPTO_THREAD_unlock(lh->tsan_lock);
+#endif
+}
+
 OPENSSL_LHASH *OPENSSL_LH_new(OPENSSL_LH_HASHFUNC h, OPENSSL_LH_COMPFUNC c)
 {
     OPENSSL_LHASH *ret;
@@ -58,6 +74,10 @@ OPENSSL_LHASH *OPENSSL_LH_new(OPENSSL_LH_HASHFUNC h, OPENSSL_LH_COMPFUNC c)
     }
     if ((ret->b = OPENSSL_zalloc(sizeof(*ret->b) * MIN_NODES)) == NULL)
         goto err;
+#ifdef TSAN_REQUIRES_LOCKING
+    if ((ret->tsan_lock = CRYPTO_THREAD_lock_new()) == NULL)
+        goto err;
+#endif
     ret->comp = ((c == NULL) ? (OPENSSL_LH_COMPFUNC)strcmp : c);
     ret->hash = ((h == NULL) ? (OPENSSL_LH_HASHFUNC)OPENSSL_LH_strhash : h);
     ret->num_nodes = MIN_NODES / 2;
@@ -79,6 +99,9 @@ void OPENSSL_LH_free(OPENSSL_LHASH *lh)
         return;
 
     OPENSSL_LH_flush(lh);
+#ifdef TSAN_REQUIRES_LOCKING
+    CRYPTO_THREAD_lock_free(lh->tsan_lock);
+#endif
     OPENSSL_free(lh->b);
     OPENSSL_free(lh);
 }
@@ -166,21 +189,20 @@ void *OPENSSL_LH_retrieve(OPENSSL_LHASH *lh, const void *data)
 {
     unsigned long hash;
     OPENSSL_LH_NODE **rn;
-    void *ret;
 
+    /*-
+     * This should be atomic without tsan.
+     * It's not clear why it was done this way and not elsewhere.
+     */
     tsan_store((TSAN_QUALIFIER int *)&lh->error, 0);
 
     rn = getrn(lh, data, &hash);
 
-    if (*rn == NULL) {
-        tsan_counter(&lh->num_retrieve_miss);
-        return NULL;
-    } else {
-        ret = (*rn)->data;
-        tsan_counter(&lh->num_retrieve);
+    if (tsan_lock(lh)) {
+        tsan_counter(*rn == NULL ? &lh->num_retrieve_miss : &lh->num_retrieve);
+        tsan_unlock(lh);
     }
-
-    return ret;
+    return *rn == NULL ? NULL : (*rn)->data;
 }
 
 static void doall_util_fn(OPENSSL_LHASH *lh, int use_arg,
@@ -307,9 +329,14 @@ static OPENSSL_LH_NODE **getrn(OPENSSL_LHASH *lh,
     OPENSSL_LH_NODE **ret, *n1;
     unsigned long hash, nn;
     OPENSSL_LH_COMPFUNC cf;
+    int do_tsan = 1;
 
+#ifdef TSAN_REQUIRES_LOCKING
+    do_tsan = tsan_lock(lh);
+#endif
     hash = (*(lh->hash)) (data);
-    tsan_counter(&lh->num_hash_calls);
+    if (do_tsan)
+        tsan_counter(&lh->num_hash_calls);
     *rhash = hash;
 
     nn = hash % lh->pmax;
@@ -319,16 +346,20 @@ static OPENSSL_LH_NODE **getrn(OPENSSL_LHASH *lh,
     cf = lh->comp;
     ret = &(lh->b[(int)nn]);
     for (n1 = *ret; n1 != NULL; n1 = n1->next) {
-        tsan_counter(&lh->num_hash_comps);
+        if (do_tsan)
+            tsan_counter(&lh->num_hash_comps);
         if (n1->hash != hash) {
             ret = &(n1->next);
             continue;
         }
-        tsan_counter(&lh->num_comp_calls);
+        if (do_tsan)
+            tsan_counter(&lh->num_comp_calls);
         if (cf(n1->data, data) == 0)
             break;
         ret = &(n1->next);
     }
+    if (do_tsan)
+        tsan_unlock(lh);
     return ret;
 }
 
diff --git a/crypto/lhash/lhash_local.h b/crypto/lhash/lhash_local.h
index ad9dd4d346..35c0c5b49c 100644
--- a/crypto/lhash/lhash_local.h
+++ b/crypto/lhash/lhash_local.h
@@ -41,4 +41,7 @@ struct lhash_st {
     TSAN_QUALIFIER unsigned long num_retrieve_miss;
     TSAN_QUALIFIER unsigned long num_hash_comps;
     int error;
+#ifdef TSAN_REQUIRES_LOCKING
+    CRYPTO_RWLOCK *tsan_lock;
+#endif
 };
diff --git a/crypto/mem.c b/crypto/mem.c
index d682a3686f..242d88470a 100644
--- a/crypto/mem.c
+++ b/crypto/mem.c
@@ -26,11 +26,17 @@ static CRYPTO_free_fn free_impl = CRYPTO_free;
 #if !defined(OPENSSL_NO_CRYPTO_MDEBUG) && !defined(FIPS_MODULE)
 # include "internal/tsan_assist.h"
 
+# ifdef TSAN_REQUIRES_LOCKING
+#  define INCREMENT(x) /* empty */
+#  define LOAD(x) 0
+# else  /* TSAN_REQUIRES_LOCKING */
 static TSAN_QUALIFIER int malloc_count;
 static TSAN_QUALIFIER int realloc_count;
 static TSAN_QUALIFIER int free_count;
 
-# define INCREMENT(x) tsan_counter(&(x))
+#  define INCREMENT(x) tsan_counter(&(x))
+#  define LOAD(x)      tsan_load(&x)
+# endif /* TSAN_REQUIRES_LOCKING */
 
 static char *md_failstring;
 static long md_count;
@@ -79,11 +85,11 @@ void CRYPTO_get_mem_functions(CRYPTO_malloc_fn *malloc_fn,
 void CRYPTO_get_alloc_counts(int *mcount, int *rcount, int *fcount)
 {
     if (mcount != NULL)
-        *mcount = tsan_load(&malloc_count);
+        *mcount = LOAD(malloc_count);
     if (rcount != NULL)
-        *rcount = tsan_load(&realloc_count);
+        *rcount = LOAD(realloc_count);
     if (fcount != NULL)
-        *fcount = tsan_load(&free_count);
+        *fcount = LOAD(free_count);
 }
 
 /*
diff --git a/crypto/objects/obj_dat.c b/crypto/objects/obj_dat.c
index 26d2508e86..593a316280 100644
--- a/crypto/objects/obj_dat.c
+++ b/crypto/objects/obj_dat.c
@@ -23,14 +23,6 @@
 /* obj_dat.h is generated from objects.h by obj_dat.pl */
 #include "obj_dat.h"
 
-/*
- * If we don't have suitable TSAN support, we'll use a lock for generation of
- * new NIDs.  This will be slower of course.
- */
-#ifndef tsan_ld_acq
-# define OBJ_USE_LOCK_FOR_NEW_NID
-#endif
-
 DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn);
 DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln);
 DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj);
@@ -47,7 +39,7 @@ struct added_obj_st {
 
 static LHASH_OF(ADDED_OBJ) *added = NULL;
 static CRYPTO_RWLOCK *ossl_obj_lock = NULL;
-#ifdef OBJ_USE_LOCK_FOR_NEW_NID
+#ifdef TSAN_REQUIRES_LOCKING
 static CRYPTO_RWLOCK *ossl_obj_nid_lock = NULL;
 #endif
 
@@ -57,7 +49,7 @@ static ossl_inline void objs_free_locks(void)
 {
     CRYPTO_THREAD_lock_free(ossl_obj_lock);
     ossl_obj_lock = NULL;
-#ifdef OBJ_USE_LOCK_FOR_NEW_NID
+#ifdef TSAN_REQUIRES_LOCKING
     CRYPTO_THREAD_lock_free(ossl_obj_nid_lock);
     ossl_obj_nid_lock = NULL;
 #endif
@@ -72,7 +64,7 @@ DEFINE_RUN_ONCE_STATIC(obj_lock_initialise)
     if (ossl_obj_lock == NULL)
         return 0;
 
-#ifdef OBJ_USE_LOCK_FOR_NEW_NID
+#ifdef TSAN_REQUIRES_LOCKING
     ossl_obj_nid_lock = CRYPTO_THREAD_lock_new();
     if (ossl_obj_nid_lock == NULL) {
         objs_free_locks();
@@ -230,8 +222,8 @@ void ossl_obj_cleanup_int(void)
 
 int OBJ_new_nid(int num)
 {
-#ifdef OBJ_USE_LOCK_FOR_NEW_NID
-    static int new_nid = NUM_NID;
+    static TSAN_QUALIFIER int new_nid = NUM_NID;
+#ifdef TSAN_REQUIRES_LOCKING
     int i;
 
     if (!CRYPTO_THREAD_write_lock(ossl_obj_nid_lock)) {
@@ -243,8 +235,6 @@ int OBJ_new_nid(int num)
     CRYPTO_THREAD_unlock(ossl_obj_nid_lock);
     return i;
 #else
-    static TSAN_QUALIFIER int new_nid = NUM_NID;
-
     return tsan_add(&new_nid, num);
 #endif
 }
diff --git a/include/internal/tsan_assist.h b/include/internal/tsan_assist.h
index c67c591e0e..512bfe4be9 100644
--- a/include/internal/tsan_assist.h
+++ b/include/internal/tsan_assist.h
@@ -125,7 +125,13 @@
 
 #ifndef TSAN_QUALIFIER
 
-# define TSAN_QUALIFIER volatile
+# ifdef OPENSSL_THREADS
+#  define TSAN_QUALIFIER volatile
+#  define TSAN_REQUIRES_LOCKING
+# else  /* OPENSSL_THREADS */
+#  define TSAN_QUALIFIER
+# endif /* OPENSSL_THREADS */
+
 # define tsan_load(ptr) (*(ptr))
 # define tsan_store(ptr, val) (*(ptr) = (val))
 # define tsan_add(ptr, n) (*(ptr) += (n))
diff --git a/providers/implementations/rands/drbg.c b/providers/implementations/rands/drbg.c
index 8b899b99b1..16d382dced 100644
--- a/providers/implementations/rands/drbg.c
+++ b/providers/implementations/rands/drbg.c
@@ -837,6 +837,10 @@ PROV_DRBG *ossl_rand_drbg_new
             goto err;
         }
     }
+#ifdef TSAN_REQUIRES_LOCKING
+    if (!ossl_drbg_enable_locking(drbg))
+        goto err;
+#endif
     return drbg;
 
  err:
diff --git a/test/threadstest.c b/test/threadstest.c
index 73cc072af1..b529517723 100644
--- a/test/threadstest.c
+++ b/test/threadstest.c
@@ -44,7 +44,11 @@ static const char *default_provider[] = { "default", NULL };
 static const char *fips_provider[] = { "fips", NULL };
 static const char *fips_and_default_providers[] = { "default", "fips", NULL };
 
-/* Grab a globally unique integer value */
+#ifdef TSAN_REQUIRES_LOCKING
+static CRYPTO_RWLOCK *tsan_lock;
+#endif
+
+/* Grab a globally unique integer value, return 0 on failure */
 static int get_new_uid(void)
 {
     /*
@@ -52,8 +56,19 @@ static int get_new_uid(void)
      * we generate a new OID.
      */
     static TSAN_QUALIFIER int current_uid = 1 << (sizeof(int) * 8 - 2);
+#ifdef TSAN_REQUIRES_LOCKING
+    int r;
+
+    if (!TEST_true(CRYPTO_THREAD_write_lock(tsan_lock)))
+        return 0;
+    r = ++current_uid;
+    if (!TEST_true(CRYPTO_THREAD_unlock(tsan_lock)))
+        return 0;
+    return r;
 
+#else
     return tsan_counter(&current_uid);
+#endif
 }
 
 static int test_lock(void)
@@ -62,6 +77,8 @@ static int test_lock(void)
     int res;
 
     res = TEST_true(CRYPTO_THREAD_read_lock(lock))
+          && TEST_true(CRYPTO_THREAD_unlock(lock))
+          && TEST_true(CRYPTO_THREAD_write_lock(lock))
           && TEST_true(CRYPTO_THREAD_unlock(lock));
 
     CRYPTO_THREAD_lock_free(lock);
@@ -624,7 +641,8 @@ static void test_obj_create_one(void)
     BIO_snprintf(oid, sizeof(oid), "1.3.6.1.4.1.16604.%s", tids);
     BIO_snprintf(sn, sizeof(sn), "short-name-%s", tids);
     BIO_snprintf(ln, sizeof(ln), "long-name-%s", tids);
-    if (!TEST_true(id = OBJ_create(oid, sn, ln))
+    if (!TEST_int_ne(id, 0)
+            || !TEST_true(id = OBJ_create(oid, sn, ln))
             || !TEST_true(OBJ_add_sigid(id, NID_sha3_256, NID_rsa)))
         multi_success = 0;
 }
@@ -682,6 +700,11 @@ int setup_tests(void)
     if (!TEST_ptr(privkey))
         return 0;
 
+#ifdef TSAN_REQUIRES_LOCKING
+    if (!TEST_ptr(tsan_lock = CRYPTO_THREAD_lock_new()))
+        return 0;
+#endif
+
     /* Keep first to validate auto creation of default library context */
     ADD_TEST(test_multi_default);
 
@@ -705,4 +728,7 @@ int setup_tests(void)
 void cleanup_tests(void)
 {
     OPENSSL_free(privkey);
+#ifdef TSAN_REQUIRES_LOCKING
+    CRYPTO_THREAD_lock_free(tsan_lock);
+#endif
 }


More information about the openssl-commits mailing list