Blame SOURCES/openssl-1.1.1-cve-2023-0215-BIO-UAF.patch

877dfe
From c3829dd8825c654652201e16f8a0a0c46ee3f344 Mon Sep 17 00:00:00 2001
877dfe
From: Matt Caswell <matt@openssl.org>
877dfe
Date: Wed, 14 Dec 2022 16:18:14 +0000
877dfe
Subject: [PATCH 4/6] Fix a UAF resulting from a bug in BIO_new_NDEF
877dfe
877dfe
If the aux->asn1_cb() call fails in BIO_new_NDEF then the "out" BIO will
877dfe
be part of an invalid BIO chain. This causes a "use after free" when the
877dfe
BIO is eventually freed.
877dfe
877dfe
Based on an original patch by Viktor Dukhovni and an idea from Theo
877dfe
Buehler.
877dfe
877dfe
Thanks to Octavio Galland for reporting this issue.
877dfe
877dfe
Reviewed-by: Paul Dale <pauli@openssl.org>
877dfe
Reviewed-by: Tomas Mraz <tomas@openssl.org>
877dfe
---
877dfe
 crypto/asn1/bio_ndef.c | 39 ++++++++++++++++++++++++++++++++-------
877dfe
 1 file changed, 32 insertions(+), 7 deletions(-)
877dfe
877dfe
diff --git a/crypto/asn1/bio_ndef.c b/crypto/asn1/bio_ndef.c
877dfe
index 760e4846a4..f8d4b1b9aa 100644
877dfe
--- a/crypto/asn1/bio_ndef.c
877dfe
+++ b/crypto/asn1/bio_ndef.c
877dfe
@@ -49,12 +49,19 @@ static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
877dfe
 static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen,
877dfe
                             void *parg);
877dfe
 
877dfe
+/*
877dfe
+ * On success, the returned BIO owns the input BIO as part of its BIO chain.
877dfe
+ * On failure, NULL is returned and the input BIO is owned by the caller.
877dfe
+ *
877dfe
+ * Unfortunately cannot constify this due to CMS_stream() and PKCS7_stream()
877dfe
+ */
877dfe
 BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
877dfe
 {
877dfe
     NDEF_SUPPORT *ndef_aux = NULL;
877dfe
     BIO *asn_bio = NULL;
877dfe
     const ASN1_AUX *aux = it->funcs;
877dfe
     ASN1_STREAM_ARG sarg;
877dfe
+    BIO *pop_bio = NULL;
877dfe
 
877dfe
     if (!aux || !aux->asn1_cb) {
877dfe
         ASN1err(ASN1_F_BIO_NEW_NDEF, ASN1_R_STREAMING_NOT_SUPPORTED);
877dfe
@@ -69,21 +76,39 @@ BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
877dfe
     out = BIO_push(asn_bio, out);
877dfe
     if (out == NULL)
877dfe
         goto err;
877dfe
+    pop_bio = asn_bio;
877dfe
 
877dfe
-    BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free);
877dfe
-    BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free);
877dfe
+    if (BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free) <= 0
877dfe
+            || BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free) <= 0
877dfe
+            || BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux) <= 0)
877dfe
+        goto err;
877dfe
 
877dfe
     /*
877dfe
-     * Now let callback prepends any digest, cipher etc BIOs ASN1 structure
877dfe
-     * needs.
877dfe
+     * Now let the callback prepend any digest, cipher, etc., that the BIO's
877dfe
+     * ASN1 structure needs.
877dfe
      */
877dfe
 
877dfe
     sarg.out = out;
877dfe
     sarg.ndef_bio = NULL;
877dfe
     sarg.boundary = NULL;
877dfe
 
877dfe
-    if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0)
877dfe
+    /*
877dfe
+     * The asn1_cb(), must not have mutated asn_bio on error, leaving it in the
877dfe
+     * middle of some partially built, but not returned BIO chain.
877dfe
+     */
877dfe
+    if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0) {
877dfe
+        /*
877dfe
+         * ndef_aux is now owned by asn_bio so we must not free it in the err
877dfe
+         * clean up block
877dfe
+         */
877dfe
+        ndef_aux = NULL;
877dfe
         goto err;
877dfe
+    }
877dfe
+
877dfe
+    /*
877dfe
+     * We must not fail now because the callback has prepended additional
877dfe
+     * BIOs to the chain
877dfe
+     */
877dfe
 
877dfe
     ndef_aux->val = val;
877dfe
     ndef_aux->it = it;
877dfe
@@ -91,11 +116,11 @@ BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
877dfe
     ndef_aux->boundary = sarg.boundary;
877dfe
     ndef_aux->out = out;
877dfe
 
877dfe
-    BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux);
877dfe
-
877dfe
     return sarg.ndef_bio;
877dfe
 
877dfe
  err:
877dfe
+    /* BIO_pop() is NULL safe */
877dfe
+    (void)BIO_pop(pop_bio);
877dfe
     BIO_free(asn_bio);
877dfe
     OPENSSL_free(ndef_aux);
877dfe
     return NULL;
877dfe
-- 
877dfe
2.39.1
877dfe
877dfe
From f040f2577891d2bdb7610566c172233844cf673a Mon Sep 17 00:00:00 2001
877dfe
From: Matt Caswell <matt@openssl.org>
877dfe
Date: Wed, 14 Dec 2022 17:15:18 +0000
877dfe
Subject: [PATCH 5/6] Check CMS failure during BIO setup with -stream is
877dfe
 handled correctly
877dfe
877dfe
Test for the issue fixed in the previous commit
877dfe
877dfe
Reviewed-by: Paul Dale <pauli@openssl.org>
877dfe
Reviewed-by: Tomas Mraz <tomas@openssl.org>
877dfe
---
877dfe
 test/recipes/80-test_cms.t  | 15 +++++++++++++--
877dfe
 test/smime-certs/badrsa.pem | 18 ++++++++++++++++++
877dfe
 2 files changed, 31 insertions(+), 2 deletions(-)
877dfe
 create mode 100644 test/smime-certs/badrsa.pem
877dfe
877dfe
diff --git a/test/recipes/80-test_cms.t b/test/recipes/80-test_cms.t
877dfe
index 5dc6a3aebe..ec11bfc253 100644
877dfe
--- a/test/recipes/80-test_cms.t
877dfe
+++ b/test/recipes/80-test_cms.t
877dfe
@@ -13,7 +13,7 @@ use warnings;
877dfe
 use POSIX;
877dfe
 use File::Spec::Functions qw/catfile/;
877dfe
 use File::Compare qw/compare_text/;
877dfe
-use OpenSSL::Test qw/:DEFAULT srctop_dir srctop_file/;
877dfe
+use OpenSSL::Test qw/:DEFAULT srctop_dir srctop_file with/;
877dfe
 use OpenSSL::Test::Utils;
877dfe
 
877dfe
 setup("test_cms");
877dfe
@@ -27,7 +27,7 @@ my $smcont   = srctop_file("test", "smcont.txt");
877dfe
 my ($no_des, $no_dh, $no_dsa, $no_ec, $no_ec2m, $no_rc2, $no_zlib)
877dfe
     = disabled qw/des dh dsa ec ec2m rc2 zlib/;
877dfe
 
877dfe
-plan tests => 6;
877dfe
+plan tests => 7;
877dfe
 
877dfe
 my @smime_pkcs7_tests = (
877dfe
 
877dfe
@@ -584,3 +584,14 @@ sub check_availability {
877dfe
 
877dfe
     return "";
877dfe
 }
877dfe
+
877dfe
+# Check that we get the expected failure return code
877dfe
+with({ exit_checker => sub { return shift == 6; } },
877dfe
+    sub {
877dfe
+        ok(run(app(['openssl', 'cms', '-encrypt',
877dfe
+                    '-in', srctop_file("test", "smcont.txt"),
877dfe
+                    '-stream', '-recip',
877dfe
+                    srctop_file("test/smime-certs", "badrsa.pem"),
877dfe
+                   ])),
877dfe
+            "Check failure during BIO setup with -stream is handled correctly");
877dfe
+    });
877dfe
diff --git a/test/smime-certs/badrsa.pem b/test/smime-certs/badrsa.pem
877dfe
new file mode 100644
877dfe
index 0000000000..f824fc2267
877dfe
--- /dev/null
877dfe
+++ b/test/smime-certs/badrsa.pem
877dfe
@@ -0,0 +1,18 @@
877dfe
+-----BEGIN CERTIFICATE-----
877dfe
+MIIDbTCCAlWgAwIBAgIToTV4Z0iuK08vZP20oTh//hC8BDANBgkqhkiG9w0BAQ0FADAtMSswKQYD
877dfe
+VfcDEyJTYW1wbGUgTEFNUFMgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MCAXDTE5MTEyMDA2NTQxOFoY
877dfe
+DzIwNTIwOTI3MDY1NDE4WjAZMRcwFQYDVQQDEw5BbGljZSBMb3ZlbGFjZTCCASIwDQYJKoZIhvcN
877dfe
+AQEBBQADggEPADCCAQoCggEBALT0iehYOBY+TZp/T5K2KNI05Hwr+E3wP6XTvyi6WWyTgBK9LCOw
877dfe
+I2juwdRrjFBmXkk7pWpjXwsA3A5GOtz0FpfgyC7OxsVcF7q4WHWZWleYXFKlQHJD73nQwXP968+A
877dfe
+/3rBX7PhO0DBbZnfitOLPgPEwjTtdg0VQQ6Wz+CRQ/YbHPKaw7aRphZO63dKvIKp4cQVtkWQHi6s
877dfe
+yTjGsgkLcLNau5LZDQUdsGV+SAo3nBdWCRYV+I65x8Kf4hCxqqmjV3d/2NKRu0BXnDe/N+iDz3X0
877dfe
+zEoj0fqXgq4SWcC0nsG1lyyXt1TL270I6ATKRGJWiQVCCpDtc0NT6vdJ45bCSxgCAwEAAaOBlzCB
877dfe
+lDAMBgNVHRMBAf8EAjAAMB4GA1UdEQQXMBWBE2FsaWNlQHNtaW1lLmV4YW1wbGUwEwYDVR0lBAww
877dfe
+CgYIKwYBBQUHAwQwDwYDVR0PAQH/BAUDAwfAADAdBgNVHQ4EFgQUu/bMsi0dBhIcl64papAQ0yBm
877dfe
+ZnMwHwYDVR0jBBgwFoAUeF8OWnjYa+RUcD2z3ez38fL6wEcwDQYJKoZIhvcNAQENBQADggEBABbW
877dfe
+eonR6TMTckehDKNOabwaCIcekahAIL6l9tTzUX5ew6ufiAPlC6I/zQlmUaU0iSyFDG1NW14kNbFt
877dfe
+5CAokyLhMtE4ASHBIHbiOp/ZSbUBTVYJZB61ot7w1/ol5QECSs08b8zrxIncf+t2DHGuVEy/Qq1d
877dfe
+rBz8d4ay8zpqAE1tUyL5Da6ZiKUfWwZQXSI/JlbjQFzYQqTRDnzHWrg1xPeMTO1P2/cplFaseTiv
877dfe
+yk4cYwOp/W9UAWymOZXF8WcJYCIUXkdcG/nEZxr057KlScrJmFXOoh7Y+8ON4iWYYcAfiNgpUFo/
877dfe
+j8BAwrKKaFvdlZS9k1Ypb2+UQY75mKJE9Bg=
877dfe
+-----END CERTIFICATE-----
877dfe
-- 
877dfe
2.39.1
877dfe