move added creation to happen outside of write lock

We have a global ADDED_OBJ hashtable, and we check to create it
on every object add with the write lock potentially held.  move that
creation to a RUN_ONCE routine so that its always created before the
write lock is held

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Paul Dale <ppzgs1@gmail.com>
(Merged from https://github.com/openssl/openssl/pull/28081)
This commit is contained in:
Neil Horman 2025-07-13 08:51:41 -04:00
parent 758ca8acf0
commit cff8031163
1 changed files with 11 additions and 11 deletions

View File

@ -37,6 +37,9 @@ struct added_obj_st {
ASN1_OBJECT *obj; ASN1_OBJECT *obj;
}; };
static unsigned long added_obj_hash(const ADDED_OBJ *ca);
static int added_obj_cmp(const ADDED_OBJ *ca, const ADDED_OBJ *cb);
static LHASH_OF(ADDED_OBJ) *added = NULL; static LHASH_OF(ADDED_OBJ) *added = NULL;
static CRYPTO_RWLOCK *ossl_obj_lock = NULL; static CRYPTO_RWLOCK *ossl_obj_lock = NULL;
#ifdef TSAN_REQUIRES_LOCKING #ifdef TSAN_REQUIRES_LOCKING
@ -68,6 +71,10 @@ DEFINE_RUN_ONCE_STATIC(obj_lock_initialise)
return 0; return 0;
} }
#endif #endif
added = lh_ADDED_OBJ_new(added_obj_hash, added_obj_cmp);
if (added == NULL)
return 0;
return 1; return 1;
} }
@ -82,19 +89,19 @@ static ossl_inline int ossl_init_added_lock(void)
static ossl_inline int ossl_obj_write_lock(int lock) static ossl_inline int ossl_obj_write_lock(int lock)
{ {
if (!lock)
return 1;
if (!ossl_init_added_lock()) if (!ossl_init_added_lock())
return 0; return 0;
if (!lock)
return 1;
return CRYPTO_THREAD_write_lock(ossl_obj_lock); return CRYPTO_THREAD_write_lock(ossl_obj_lock);
} }
static ossl_inline int ossl_obj_read_lock(int lock) static ossl_inline int ossl_obj_read_lock(int lock)
{ {
if (!lock)
return 1;
if (!ossl_init_added_lock()) if (!ossl_init_added_lock())
return 0; return 0;
if (!lock)
return 1;
return CRYPTO_THREAD_read_lock(ossl_obj_lock); return CRYPTO_THREAD_read_lock(ossl_obj_lock);
} }
@ -282,13 +289,6 @@ static int ossl_obj_add_object(const ASN1_OBJECT *obj, int lock)
ERR_raise(ERR_LIB_OBJ, ERR_R_UNABLE_TO_GET_WRITE_LOCK); ERR_raise(ERR_LIB_OBJ, ERR_R_UNABLE_TO_GET_WRITE_LOCK);
goto err2; goto err2;
} }
if (added == NULL) {
added = lh_ADDED_OBJ_new(added_obj_hash, added_obj_cmp);
if (added == NULL) {
ERR_raise(ERR_LIB_OBJ, ERR_R_CRYPTO_LIB);
goto err;
}
}
for (i = ADDED_DATA; i <= ADDED_NID; i++) { for (i = ADDED_DATA; i <= ADDED_NID; i++) {
if (ao[i] != NULL) { if (ao[i] != NULL) {