Commit ce22d29f5f for openssl.org
commit ce22d29f5fbeaa976fbc6ab2fc5be7a806142df0
Author: Bob Beck <beck@openssl.org>
Date: Wed Apr 22 12:37:29 2026 -0600
Allow 0 length comparisons in OBJ_CMP to return 0 without UB memcmp
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)
diff --git a/crypto/objects/obj_lib.c b/crypto/objects/obj_lib.c
index 0d3ca0334c..89be08810c 100644
--- a/crypto/objects/obj_lib.c
+++ b/crypto/objects/obj_lib.c
@@ -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);
}
diff --git a/test/x509_test.c b/test/x509_test.c
index 5ce8a647c0..e9529148d4 100644
--- a/test/x509_test.c
+++ b/test/x509_test.c
@@ -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;
}