Use a more fine-grained lock in by_dir.c Different BY_DIR_ENTRYs don't need to share a lock. Also switch some code to use OPENSSL_strndup. Change-Id: I3809e001afb9577bb96aab214e80e173900356fe Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/66012 Reviewed-by: Bob Beck <bbe@google.com> Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/crypto/x509/by_dir.c b/crypto/x509/by_dir.c index 5eca97b..d49220d 100644 --- a/crypto/x509/by_dir.c +++ b/crypto/x509/by_dir.c
@@ -72,6 +72,7 @@ } BY_DIR_HASH; typedef struct lookup_dir_entry_st { + CRYPTO_MUTEX lock; char *dir; int dir_type; STACK_OF(BY_DIR_HASH) *hashes; @@ -156,6 +157,7 @@ static void by_dir_entry_free(BY_DIR_ENTRY *ent) { if (ent != NULL) { + CRYPTO_MUTEX_cleanup(&ent->lock); OPENSSL_free(ent->dir); sk_BY_DIR_HASH_pop_free(ent->hashes, by_dir_hash_free); OPENSSL_free(ent); @@ -215,15 +217,12 @@ if (!ent) { return 0; } + CRYPTO_MUTEX_init(&ent->lock); ent->dir_type = type; ent->hashes = sk_BY_DIR_HASH_new(by_dir_hash_cmp); - ent->dir = OPENSSL_malloc(len + 1); - if (!ent->dir || !ent->hashes) { - by_dir_entry_free(ent); - return 0; - } - OPENSSL_strlcpy(ent->dir, ss, len + 1); - if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent)) { + ent->dir = OPENSSL_strndup(ss, len); + if (ent->dir == NULL || ent->hashes == NULL || + !sk_BY_DIR_ENTRY_push(ctx->dirs, ent)) { by_dir_entry_free(ent); return 0; } @@ -232,10 +231,6 @@ return 1; } -// g_ent_hashes_lock protects the |hashes| member of all |BY_DIR_ENTRY| -// objects. -static CRYPTO_MUTEX g_ent_hashes_lock = CRYPTO_MUTEX_INIT; - static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, X509_OBJECT *ret) { union { @@ -300,7 +295,7 @@ } if (type == X509_LU_CRL && ent->hashes) { htmp.hash = h; - CRYPTO_MUTEX_lock_read(&g_ent_hashes_lock); + CRYPTO_MUTEX_lock_read(&ent->lock); if (sk_BY_DIR_HASH_find(ent->hashes, &idx, &htmp)) { hent = sk_BY_DIR_HASH_value(ent->hashes, idx); k = hent->suffix; @@ -308,7 +303,7 @@ hent = NULL; k = 0; } - CRYPTO_MUTEX_unlock_read(&g_ent_hashes_lock); + CRYPTO_MUTEX_unlock_read(&ent->lock); } else { k = 0; hent = NULL; @@ -341,7 +336,7 @@ // If a CRL, update the last file suffix added for this if (type == X509_LU_CRL) { - CRYPTO_MUTEX_lock_write(&g_ent_hashes_lock); + CRYPTO_MUTEX_lock_write(&ent->lock); // Look for entry again in case another thread added an entry // first. if (!hent) { @@ -354,14 +349,14 @@ if (!hent) { hent = OPENSSL_malloc(sizeof(BY_DIR_HASH)); if (hent == NULL) { - CRYPTO_MUTEX_unlock_write(&g_ent_hashes_lock); + CRYPTO_MUTEX_unlock_write(&ent->lock); ok = 0; goto finish; } hent->hash = h; hent->suffix = k; if (!sk_BY_DIR_HASH_push(ent->hashes, hent)) { - CRYPTO_MUTEX_unlock_write(&g_ent_hashes_lock); + CRYPTO_MUTEX_unlock_write(&ent->lock); OPENSSL_free(hent); ok = 0; goto finish; @@ -371,7 +366,7 @@ hent->suffix = k; } - CRYPTO_MUTEX_unlock_write(&g_ent_hashes_lock); + CRYPTO_MUTEX_unlock_write(&ent->lock); } if (tmp != NULL) {