diff options
author | Neil Horman <nhorman@openssl.org> | 2023-10-11 09:34:02 -0400 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2023-10-18 16:52:45 +0200 |
commit | cd920f8fa1bb603a620bea697027f5573fadc12e (patch) | |
tree | 0249e438230b93d3710efd3a8bdaf8392da2315f /crypto/objects/obj_dat.c | |
parent | bd160912dcc5e39bcdc925d9aa6538f20e37ad16 (diff) |
ensure that ossl_obj_nid_lock is allocated before use
external calls to OBJ_new_nid will fail on an attempt to lock the
ossl_obj_nid_lock as it won't have been initalized yet.
Bifurcate OBJ_new_nid into an external and internal variant, in which
the former calls ossl_obj_write_lock (ensuring that the nid_lock is
initalized), while OBJ_create (the sole internal caller) uses the latter
to avoid having to drop and re-acquire the lock
Fixes #22337
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22350)
Diffstat (limited to 'crypto/objects/obj_dat.c')
-rw-r--r-- | crypto/objects/obj_dat.c | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/crypto/objects/obj_dat.c b/crypto/objects/obj_dat.c index 209059aa7c..b0e1032ec2 100644 --- a/crypto/objects/obj_dat.c +++ b/crypto/objects/obj_dat.c @@ -221,25 +221,45 @@ void ossl_obj_cleanup_int(void) objs_free_locks(); } -int OBJ_new_nid(int num) +/* + * Requires that the ossl_obj_lock be held + * if TSAN_REQUIRES_LOCKING defined + */ +static int obj_new_nid_unlocked(int num) { static TSAN_QUALIFIER int new_nid = NUM_NID; #ifdef TSAN_REQUIRES_LOCKING int i; - if (!CRYPTO_THREAD_write_lock(ossl_obj_nid_lock)) { - ERR_raise(ERR_LIB_OBJ, ERR_R_UNABLE_TO_GET_WRITE_LOCK); - return NID_undef; - } i = new_nid; new_nid += num; - CRYPTO_THREAD_unlock(ossl_obj_nid_lock); + return i; #else return tsan_add(&new_nid, num); #endif } +int OBJ_new_nid(int num) +{ +#ifdef TSAN_REQUIRES_LOCKING + int i; + + if (!ossl_obj_write_lock(1)) { + ERR_raise(ERR_LIB_OBJ, ERR_R_UNABLE_TO_GET_WRITE_LOCK); + return NID_undef; + } + + i = obj_new_nid_unlocked(num); + + ossl_obj_unlock(1); + + return i; +#else + return obj_new_nid_unlocked(num); +#endif +} + static int ossl_obj_add_object(const ASN1_OBJECT *obj, int lock) { ASN1_OBJECT *o = NULL; @@ -785,7 +805,8 @@ int OBJ_create(const char *oid, const char *sn, const char *ln) goto err; } - tmpoid->nid = OBJ_new_nid(1); + tmpoid->nid = obj_new_nid_unlocked(1); + if (tmpoid->nid == NID_undef) goto err; |