From: Bob Beck Date: Wed, 22 Apr 2026 18:37:29 +0000 (-0600) Subject: Allow 0 length comparisons in OBJ_CMP to return 0 without UB memcmp X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ce22d29f5fbeaa976fbc6ab2fc5be7a806142df0;p=thirdparty%2Fopenssl.git 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 Reviewed-by: Matt Caswell Reviewed-by: Shane Lontis Reviewed-by: Nikola Pajkovsky Reviewed-by: Neil Horman 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 0d3ca0334cd..89be08810c4 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 5ce8a647c07..e9529148d41 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; }