]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
ensure that ossl_obj_nid_lock is allocated before use
authorNeil Horman <nhorman@openssl.org>
Wed, 11 Oct 2023 13:34:02 +0000 (09:34 -0400)
committerTomas Mraz <tomas@openssl.org>
Wed, 18 Oct 2023 14:52:45 +0000 (16:52 +0200)
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)

crypto/objects/obj_dat.c

index 209059aa7ce8bef150dd25e6bc36e6e842b213a0..b0e1032ec2cf859caa026fb0b2fa8a71ca29d304 100644 (file)
@@ -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;