From 70df675dd4f5e4a593b2f95406c1aac031aa8bc7 Mon Sep 17 00:00:00 2001
From: Michael Catanzaro <mcatanzaro@redhat.com>
Date: Thu, 21 Aug 2025 17:21:01 -0500
Subject: [PATCH] openssl: check return values of BIO_new()

We probably need to check even more return values of even more OpenSSL
functions, but these ones allocate memory and that's particularly
important to get right.

CVE: CVE-2025-60019

Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib-networking/-/commit/70df675dd4f5e4a593b2f95406c1aac031aa8bc7]

Signed-off-by: Rajeshkumar Ramasamy <rajeshkumar.ramasamy@windriver.com>
---
 tls/openssl/gtlscertificate-openssl.c | 42 ++++++++++++++++++++-------
 1 file changed, 32 insertions(+), 10 deletions(-)

diff --git a/tls/openssl/gtlscertificate-openssl.c b/tls/openssl/gtlscertificate-openssl.c
index b536559..4fa5286 100644
--- a/tls/openssl/gtlscertificate-openssl.c
+++ b/tls/openssl/gtlscertificate-openssl.c
@@ -166,6 +166,9 @@ export_privkey_to_der (GTlsCertificateOpenssl  *openssl,
     goto err;

   bio = BIO_new (BIO_s_mem ());
+  if (!bio)
+    goto err;
+
   if (i2d_PKCS8_PRIV_KEY_INFO_bio (bio, pkcs8) == 0)
     goto err;

@@ -199,6 +202,9 @@ export_privkey_to_pem (GTlsCertificateOpenssl *openssl)
     return NULL;

   bio = BIO_new (BIO_s_mem ());
+  if (!bio)
+    goto out;
+
   ret = PEM_write_bio_PKCS8PrivateKey (bio, openssl->key, NULL, NULL, 0, NULL, NULL);
   if (ret == 0)
     goto out;
@@ -211,7 +217,7 @@ export_privkey_to_pem (GTlsCertificateOpenssl *openssl)
   result = g_strdup (data);

 out:
-  BIO_free_all (bio);
+  g_clear_pointer (&bio, BIO_free_all);
   return result;
 }

@@ -232,6 +238,9 @@ maybe_import_pkcs12 (GTlsCertificateOpenssl *openssl)
     return;

   bio = BIO_new (BIO_s_mem ());
+  if (!bio)
+    goto import_failed;
+
   status = BIO_write (bio, openssl->pkcs12_data->data, openssl->pkcs12_data->len);
   if (status <= 0)
     goto import_failed;
@@ -323,7 +332,7 @@ g_tls_certificate_openssl_get_property (GObject    *object,
   guint8 *data;
   BIO *bio;
   GByteArray *byte_array;
-  char *certificate_pem;
+  const char *certificate_pem;
   long size;

   const ASN1_TIME *time_asn1;
@@ -362,12 +371,12 @@ g_tls_certificate_openssl_get_property (GObject    *object,
     case PROP_CERTIFICATE_PEM:
       bio = BIO_new (BIO_s_mem ());

-      if (PEM_write_bio_X509 (bio, openssl->cert) == 1 && BIO_write (bio, "\0", 1) == 1)
+      if (bio && PEM_write_bio_X509 (bio, openssl->cert) == 1 && BIO_write (bio, "\0", 1) == 1)
         {
           BIO_get_mem_data (bio, &certificate_pem);
           g_value_set_string (value, certificate_pem);
         }
-      BIO_free_all (bio);
+      g_clear_pointer (&bio, BIO_free_all);
       break;

     case PROP_PRIVATE_KEY:
@@ -407,6 +416,8 @@ g_tls_certificate_openssl_get_property (GObject    *object,

     case PROP_SUBJECT_NAME:
       bio = BIO_new (BIO_s_mem ());
+      if (!bio)
+        break;
       name = X509_get_subject_name (openssl->cert);
       if (X509_NAME_print_ex (bio, name, 0, XN_FLAG_SEP_COMMA_PLUS) < 0 ||
           BIO_write (bio, "\0", 1) != 1)
@@ -421,6 +432,8 @@ g_tls_certificate_openssl_get_property (GObject    *object,

     case PROP_ISSUER_NAME:
       bio = BIO_new (BIO_s_mem ());
+      if (!bio)
+        break;
       name = X509_get_issuer_name (openssl->cert);
       if (X509_NAME_print_ex (bio, name, 0, XN_FLAG_SEP_COMMA_PLUS) < 0 ||
           BIO_write (bio, "\0", 1) != 1)
@@ -533,8 +546,11 @@ g_tls_certificate_openssl_set_property (GObject      *object,
         break;
       CRITICAL_IF_CERTIFICATE_INITIALIZED ("certificate-pem");
       bio = BIO_new_mem_buf ((gpointer)string, -1);
-      openssl->cert = PEM_read_bio_X509 (bio, NULL, NULL, NULL);
-      BIO_free (bio);
+      if (bio)
+        {
+          openssl->cert = PEM_read_bio_X509 (bio, NULL, NULL, NULL);
+          BIO_free (bio);
+        }
       if (openssl->cert)
         openssl->have_cert = TRUE;
       else if (!openssl->construct_error)
@@ -554,8 +570,11 @@ g_tls_certificate_openssl_set_property (GObject      *object,
       CRITICAL_IF_KEY_INITIALIZED ("private-key");

       bio = BIO_new_mem_buf (bytes->data, bytes->len);
-      openssl->key = d2i_PrivateKey_bio (bio, NULL);
-      BIO_free (bio);
+      if (bio)
+        {
+          openssl->key = d2i_PrivateKey_bio (bio, NULL);
+          BIO_free (bio);
+        }
       if (openssl->key)
         openssl->have_key = TRUE;
       else if (!openssl->construct_error)
@@ -575,8 +594,11 @@ g_tls_certificate_openssl_set_property (GObject      *object,
       CRITICAL_IF_KEY_INITIALIZED ("private-key-pem");

       bio = BIO_new_mem_buf ((gpointer)string, -1);
-      openssl->key = PEM_read_bio_PrivateKey (bio, NULL, NULL, NULL);
-      BIO_free (bio);
+      if (bio)
+        {
+          openssl->key = PEM_read_bio_PrivateKey (bio, NULL, NULL, NULL);
+          BIO_free (bio);
+        }
       if (openssl->key)
         openssl->have_key = TRUE;
       else if (!openssl->construct_error)
--
2.48.1
