]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Allow 0 length comparisons in OBJ_CMP to return 0 without UB memcmp
authorBob Beck <beck@openssl.org>
Wed, 22 Apr 2026 18:37:29 +0000 (12:37 -0600)
committerNeil Horman <nhorman@openssl.org>
Wed, 6 May 2026 14:55:07 +0000 (10:55 -0400)
X509_verify is documented to return -1 if the algorithm is invalid
or can't be compared for any reason.

Sadly this implies that it is legitimate to pass it an incorrect X509
object and it should see this. If we hand it a new X509 object with
nothing filled in, it will memcmp(NULL...) at the end of a stack of
FOO_cmp abstractions, which is UB.

Fix this by permitting the 0 length case to return equal without
a memcmp, as suggested by slontis@ and botovq@

Fixes: https://github.com/openssl/openssl/issues/30922
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Reviewed-by: Matt Caswell <matt@openssl.foundation>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
Reviewed-by: Neil Horman <nhorman@openssl.org>
MergeDate: Wed May  6 14:55:20 2026
(Merged from https://github.com/openssl/openssl/pull/30943)

crypto/objects/obj_lib.c
test/x509_test.c

index 0d3ca0334cdc701e34cc7d4c4844930711165cb5..89be08810c4b81384b9c3fe6a4a66a054506db0d 100644 (file)
@@ -59,5 +59,7 @@ int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b)
     ret = (a->length - b->length);
     if (ret)
         return ret;
+    if (a->length == 0)
+        return 0;
     return memcmp(a->data, b->data, a->length);
 }
index 5ce8a647c07f124ee184cde370e68e527c675c62..e9529148d41a2679c8ea0d6555336f94ce81f4ca 100644 (file)
@@ -103,6 +103,21 @@ static int test_x509_tbs_cache(void)
     return ret;
 }
 
+static int test_x509_verify_with_new(void)
+{
+    int ret;
+    EVP_PKEY *pkey = NULL;
+    X509 *x = NULL;
+
+    ret = TEST_ptr(x = X509_new())
+        && TEST_ptr(pkey = EVP_PKEY_new())
+        && TEST_int_eq(X509_verify(x, pkey), -1)
+        && TEST_int_eq(X509_verify(x, pubkey), -1);
+    X509_free(x);
+    EVP_PKEY_free(pkey);
+    return ret;
+}
+
 /*
  * Test for Regression discussed in PR #19388
  * In order for this simple test to fail, it requires the digest used for
@@ -575,6 +590,7 @@ int setup_tests(void)
     ADD_TEST(test_drop_empty_cert_keyids);
     ADD_TEST(test_drop_empty_csr_keyids);
     ADD_TEST(test_rsaesoaep_spki);
+    ADD_TEST(test_x509_verify_with_new);
     return 1;
 }