lhash/lhash.c: switch to Thread-Sanitizer-friendly primitives.
[oweals/openssl.git] / crypto / lhash / lhash.c
index 1b0f26d0298b7962e7bb1ff28342b11ed5dbd771..f7ac9d02f58b1017e4e1c3d7ef2f7368fdd6de08 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -12,6 +12,7 @@
 #include <stdlib.h>
 #include <openssl/crypto.h>
 #include <openssl/lhash.h>
+#include <openssl/err.h>
 #include "lhash_lcl.h"
 
 /*
@@ -20,7 +21,7 @@
  * https://en.wikipedia.org/wiki/Linear_hashing
  *
  * Litwin, Witold (1980), "Linear hashing: A new tool for file and table
- * addressing", Proc. 6th Conference on Very Large Databases: 212223
+ * addressing", Proc. 6th Conference on Very Large Databases: 212-223
  * http://hackthology.com/pdfs/Litwin-1980-Linear_Hashing.pdf
  *
  * From the wikipedia article "Linear hashing is used in the BDB Berkeley
@@ -45,8 +46,14 @@ OPENSSL_LHASH *OPENSSL_LH_new(OPENSSL_LH_HASHFUNC h, OPENSSL_LH_COMPFUNC c)
 {
     OPENSSL_LHASH *ret;
 
-    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL)
+    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) {
+        /*
+         * Do not set the error code, because the ERR code uses LHASH
+         * and we want to avoid possible endless error loop.
+         * CRYPTOerr(CRYPTO_F_OPENSSL_LH_NEW, ERR_R_MALLOC_FAILURE);
+         */
         return NULL;
+    }
     if ((ret->b = OPENSSL_zalloc(sizeof(*ret->b) * MIN_NODES)) == NULL)
         goto err;
     ret->comp = ((c == NULL) ? (OPENSSL_LH_COMPFUNC)strcmp : c);
@@ -150,16 +157,18 @@ void *OPENSSL_LH_retrieve(OPENSSL_LHASH *lh, const void *data)
     OPENSSL_LH_NODE **rn;
     void *ret;
 
-    lh->error = 0;
+    tsan_store((TSAN_QUALIFIER int *)&lh->error, 0);
+
     rn = getrn(lh, data, &hash);
 
     if (*rn == NULL) {
-        lh->num_retrieve_miss++;
+        tsan_counter(&lh->num_retrieve_miss);
         return NULL;
     } else {
         ret = (*rn)->data;
-        lh->num_retrieve++;
+        tsan_counter(&lh->num_retrieve);
     }
+
     return ret;
 }
 
@@ -289,7 +298,7 @@ static OPENSSL_LH_NODE **getrn(OPENSSL_LHASH *lh,
     OPENSSL_LH_COMPFUNC cf;
 
     hash = (*(lh->hash)) (data);
-    lh->num_hash_calls++;
+    tsan_counter(&lh->num_hash_calls);
     *rhash = hash;
 
     nn = hash % lh->pmax;
@@ -299,12 +308,12 @@ static OPENSSL_LH_NODE **getrn(OPENSSL_LHASH *lh,
     cf = lh->comp;
     ret = &(lh->b[(int)nn]);
     for (n1 = *ret; n1 != NULL; n1 = n1->next) {
-        lh->num_hash_comps++;
+        tsan_counter(&lh->num_hash_comps);
         if (n1->hash != hash) {
             ret = &(n1->next);
             continue;
         }
-        lh->num_comp_calls++;
+        tsan_counter(&lh->num_comp_calls);
         if (cf(n1->data, data) == 0)
             break;
         ret = &(n1->next);