summaryrefslogtreecommitdiffstats
path: root/crypto/objects
diff options
context:
space:
mode:
authorNeil Horman <nhorman@openssl.org>2023-10-11 09:34:02 -0400
committerTomas Mraz <tomas@openssl.org>2023-10-18 16:52:45 +0200
commitcd920f8fa1bb603a620bea697027f5573fadc12e (patch)
tree0249e438230b93d3710efd3a8bdaf8392da2315f /crypto/objects
parentbd160912dcc5e39bcdc925d9aa6538f20e37ad16 (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')
-rw-r--r--crypto/objects/obj_dat.c35
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;