summaryrefslogtreecommitdiffstats
path: root/crypto/core_namemap.c
diff options
context:
space:
mode:
authorPauli <paul.dale@oracle.com>2020-06-18 11:01:08 +1000
committerPauli <paul.dale@oracle.com>2020-06-21 16:49:51 +1000
commitc720fc35f4aa90cdc7cdc424b976c5322fb0098e (patch)
tree9f07933602da736bf81631410a40ead69c979592 /crypto/core_namemap.c
parent7cc5e0d283800c757e46d1476273d271120aa38d (diff)
namemap: change ossl_namemap_empty() to do what the documentation says.
The function is documented as returning 1 when passed a NULL argument. Instead it core dumps. Added a unit test for this. Additionally, a performance improvement is incorporated. The namemap max_number field is only ever compared against zero and incremented. The zero comparison grabs a lock specifically for this check. This change uses TSAN operations instead if they are available. Reviewed-by: Richard Levitte <levitte@openssl.org> (Merged from https://github.com/openssl/openssl/pull/12181)
Diffstat (limited to 'crypto/core_namemap.c')
-rw-r--r--crypto/core_namemap.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/crypto/core_namemap.c b/crypto/core_namemap.c
index 94c80de091..e17b3ac0e2 100644
--- a/crypto/core_namemap.c
+++ b/crypto/core_namemap.c
@@ -11,6 +11,7 @@
#include "internal/namemap.h"
#include <openssl/lhash.h>
#include "crypto/lhash.h" /* openssl_lh_strcasehash */
+#include "internal/tsan_assist.h"
/*-
* The namenum entry
@@ -34,7 +35,12 @@ struct ossl_namemap_st {
CRYPTO_RWLOCK *lock;
LHASH_OF(NAMENUM_ENTRY) *namenum; /* Name->number mapping */
- int max_number; /* Current max number */
+
+#ifdef tsan_ld_acq
+ TSAN_QUALIFIER int max_number; /* Current max number TSAN version */
+#else
+ int max_number; /* Current max number plain version */
+#endif
};
/* LHASH callbacks */
@@ -91,14 +97,21 @@ static const OPENSSL_CTX_METHOD stored_namemap_method = {
int ossl_namemap_empty(OSSL_NAMEMAP *namemap)
{
- int rv = 0;
+#ifdef tsan_ld_acq
+ /* Have TSAN support */
+ return namemap == NULL || tsan_load(&namemap->max_number) == 0;
+#else
+ /* No TSAN support */
+ int rv;
+
+ if (namemap == NULL)
+ return 1;
CRYPTO_THREAD_read_lock(namemap->lock);
- if (namemap->max_number == 0)
- rv = 1;
+ rv = namemap->max_number == 0;
CRYPTO_THREAD_unlock(namemap->lock);
-
return rv;
+#endif
}
typedef struct doall_names_data_st {
@@ -216,7 +229,7 @@ int ossl_namemap_add_name_n(OSSL_NAMEMAP *namemap, int number,
goto err;
namenum->number = tmp_number =
- number != 0 ? number : ++namemap->max_number;
+ number != 0 ? number : 1 + tsan_counter(&namemap->max_number);
(void)lh_NAMENUM_ENTRY_insert(namemap->namenum, namenum);
if (lh_NAMENUM_ENTRY_error(namemap->namenum))