diff options
author | Pauli <paul.dale@oracle.com> | 2017-09-28 10:09:18 +1000 |
---|---|---|
committer | Pauli <paul.dale@oracle.com> | 2017-10-09 07:50:18 +1000 |
commit | 2e8b5d75afaff7c9b75917b750f997dc82336fac (patch) | |
tree | f30b5432cf98015569f3e284993b81c5d72ef976 /crypto/lhash | |
parent | 24b0be11b061f36d30ccccdf9d34edf270be4c2f (diff) |
Document that lhash isn't thread safe under any circumstances and
indicate the level of locking required for various operations.
Remove the lock and atomics from the lhash code. These we're not complete
or adequate.
Refer to #4418 and #4427 for details.
Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Ben Kaduk <kaduk@mit.edu>
Reviewed-by: Andy Polyakov <appro@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/4429)
Diffstat (limited to 'crypto/lhash')
-rw-r--r-- | crypto/lhash/lh_stats.c | 31 | ||||
-rw-r--r-- | crypto/lhash/lhash.c | 34 | ||||
-rw-r--r-- | crypto/lhash/lhash_lcl.h | 19 |
3 files changed, 29 insertions, 55 deletions
diff --git a/crypto/lhash/lh_stats.c b/crypto/lhash/lh_stats.c index 5586afa0d8..65b91e1ef4 100644 --- a/crypto/lhash/lh_stats.c +++ b/crypto/lhash/lh_stats.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2017 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 @@ -61,35 +61,22 @@ void OPENSSL_LH_node_usage_stats(const OPENSSL_LHASH *lh, FILE *fp) void OPENSSL_LH_stats_bio(const OPENSSL_LHASH *lh, BIO *out) { - OPENSSL_LHASH *lh_mut = (OPENSSL_LHASH *) lh; - int ret; - 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); + BIO_printf(out, "num_nodes = %u\n", lh->num_nodes); + BIO_printf(out, "num_alloc_nodes = %u\n", lh->num_alloc_nodes); BIO_printf(out, "num_expands = %lu\n", lh->num_expands); 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); - CRYPTO_atomic_add(&lh_mut->num_hash_calls, 0, &ret, - lh->retrieve_stats_lock); - BIO_printf(out, "num_hash_calls = %d\n", ret); - CRYPTO_atomic_add(&lh_mut->num_comp_calls, 0, &ret, - lh->retrieve_stats_lock); - BIO_printf(out, "num_comp_calls = %d\n", ret); + 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); 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); - CRYPTO_atomic_add(&lh_mut->num_retrieve, 0, &ret, lh->retrieve_stats_lock); - BIO_printf(out, "num_retrieve = %d\n", ret); - CRYPTO_atomic_add(&lh_mut->num_retrieve_miss, 0, &ret, - lh->retrieve_stats_lock); - BIO_printf(out, "num_retrieve_miss = %d\n", ret); - CRYPTO_atomic_add(&lh_mut->num_hash_comps, 0, &ret, - lh->retrieve_stats_lock); - BIO_printf(out, "num_hash_comps = %d\n", ret); + 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); } 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 8f28c48c4d..28528817a1 100644 --- a/crypto/lhash/lhash.c +++ b/crypto/lhash/lhash.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2017 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 @@ -32,8 +32,6 @@ OPENSSL_LHASH *OPENSSL_LH_new(OPENSSL_LH_HASHFUNC h, OPENSSL_LH_COMPFUNC c) return NULL; if ((ret->b = OPENSSL_zalloc(sizeof(*ret->b) * MIN_NODES)) == NULL) goto err; - if ((ret->retrieve_stats_lock = CRYPTO_THREAD_lock_new()) == NULL) - goto err; 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; @@ -41,7 +39,7 @@ OPENSSL_LHASH *OPENSSL_LH_new(OPENSSL_LH_HASHFUNC h, OPENSSL_LH_COMPFUNC c) ret->pmax = MIN_NODES / 2; ret->up_load = UP_LOAD; ret->down_load = DOWN_LOAD; - return (ret); + return ret; err: OPENSSL_free(ret->b); @@ -65,7 +63,6 @@ void OPENSSL_LH_free(OPENSSL_LHASH *lh) n = nn; } } - CRYPTO_THREAD_lock_free(lh->retrieve_stats_lock); OPENSSL_free(lh->b); OPENSSL_free(lh); } @@ -85,7 +82,7 @@ void *OPENSSL_LH_insert(OPENSSL_LHASH *lh, void *data) if (*rn == NULL) { if ((nn = OPENSSL_malloc(sizeof(*nn))) == NULL) { lh->error++; - return (NULL); + return NULL; } nn->data = data; nn->next = NULL; @@ -95,12 +92,11 @@ void *OPENSSL_LH_insert(OPENSSL_LHASH *lh, void *data) lh->num_insert++; lh->num_items++; } else { /* replace same key */ - ret = (*rn)->data; (*rn)->data = data; lh->num_replace++; } - return (ret); + return ret; } void *OPENSSL_LH_delete(OPENSSL_LHASH *lh, const void *data) @@ -114,7 +110,7 @@ void *OPENSSL_LH_delete(OPENSSL_LHASH *lh, const void *data) if (*rn == NULL) { lh->num_no_delete++; - return (NULL); + return NULL; } else { nn = *rn; *rn = nn->next; @@ -128,7 +124,7 @@ void *OPENSSL_LH_delete(OPENSSL_LHASH *lh, const void *data) (lh->down_load >= (lh->num_items * LH_LOAD_MULT / lh->num_nodes))) contract(lh); - return (ret); + return ret; } void *OPENSSL_LH_retrieve(OPENSSL_LHASH *lh, const void *data) @@ -136,17 +132,16 @@ void *OPENSSL_LH_retrieve(OPENSSL_LHASH *lh, const void *data) unsigned long hash; OPENSSL_LH_NODE **rn; void *ret; - int scratch; lh->error = 0; rn = getrn(lh, data, &hash); if (*rn == NULL) { - CRYPTO_atomic_add(&lh->num_retrieve_miss, 1, &scratch, lh->retrieve_stats_lock); + lh->num_retrieve_miss++; return NULL; } else { ret = (*rn)->data; - CRYPTO_atomic_add(&lh->num_retrieve, 1, &scratch, lh->retrieve_stats_lock); + lh->num_retrieve++; } return ret; } @@ -274,10 +269,9 @@ static OPENSSL_LH_NODE **getrn(OPENSSL_LHASH *lh, OPENSSL_LH_NODE **ret, *n1; unsigned long hash, nn; OPENSSL_LH_COMPFUNC cf; - int scratch; hash = (*(lh->hash)) (data); - CRYPTO_atomic_add(&lh->num_hash_calls, 1, &scratch, lh->retrieve_stats_lock); + lh->num_hash_calls++; *rhash = hash; nn = hash % lh->pmax; @@ -287,17 +281,17 @@ static OPENSSL_LH_NODE **getrn(OPENSSL_LHASH *lh, cf = lh->comp; ret = &(lh->b[(int)nn]); for (n1 = *ret; n1 != NULL; n1 = n1->next) { - CRYPTO_atomic_add(&lh->num_hash_comps, 1, &scratch, lh->retrieve_stats_lock); + lh->num_hash_comps++; if (n1->hash != hash) { ret = &(n1->next); continue; } - CRYPTO_atomic_add(&lh->num_comp_calls, 1, &scratch, lh->retrieve_stats_lock); + lh->num_comp_calls++; if (cf(n1->data, data) == 0) break; ret = &(n1->next); } - return (ret); + return ret; } /* @@ -313,7 +307,7 @@ unsigned long OPENSSL_LH_strhash(const char *c) int r; if ((c == NULL) || (*c == '\0')) - return (ret); + return ret; n = 0x100; while (*c) { @@ -325,7 +319,7 @@ unsigned long OPENSSL_LH_strhash(const char *c) ret ^= v * v; c++; } - return ((ret >> 16) ^ ret); + return (ret >> 16) ^ ret; } unsigned long OPENSSL_LH_num_items(const OPENSSL_LHASH *lh) diff --git a/crypto/lhash/lhash_lcl.h b/crypto/lhash/lhash_lcl.h index 64d3134fc1..78691eb622 100644 --- a/crypto/lhash/lhash_lcl.h +++ b/crypto/lhash/lhash_lcl.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2017 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 @@ -18,13 +18,6 @@ struct lhash_st { OPENSSL_LH_NODE **b; OPENSSL_LH_COMPFUNC comp; OPENSSL_LH_HASHFUNC hash; - /* - * some stats are updated on lookup, which callers aren't expecting to have - * to take an exclusive lock around. This lock protects them on platforms - * without atomics, and their types are int rather than unsigned long below - * so they can be adjusted with CRYPTO_atomic_add. - */ - CRYPTO_RWLOCK *retrieve_stats_lock; unsigned int num_nodes; unsigned int num_alloc_nodes; unsigned int p; @@ -36,14 +29,14 @@ struct lhash_st { unsigned long num_expand_reallocs; unsigned long num_contracts; unsigned long num_contract_reallocs; - int num_hash_calls; - int num_comp_calls; + unsigned long num_hash_calls; + unsigned long num_comp_calls; unsigned long num_insert; unsigned long num_replace; unsigned long num_delete; unsigned long num_no_delete; - int num_retrieve; - int num_retrieve_miss; - int num_hash_comps; + unsigned long num_retrieve; + unsigned long num_retrieve_miss; + unsigned long num_hash_comps; int error; }; |