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 | 39 ++++++++++++++++++++-------
 1 file changed, 29 insertions(+), 10 deletions(-)

diff --git a/tls/openssl/gtlscertificate-openssl.c b/tls/openssl/gtlscertificate-openssl.c
index 8f828a7..f7fde51 100644
--- a/tls/openssl/gtlscertificate-openssl.c
+++ b/tls/openssl/gtlscertificate-openssl.c
@@ -156,6 +156,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;

@@ -189,6 +192,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;
@@ -201,7 +207,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;
 }

@@ -216,7 +222,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;
@@ -251,12 +257,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:
@@ -296,6 +302,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)
@@ -310,6 +318,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)
@@ -377,8 +387,11 @@ g_tls_certificate_openssl_set_property (GObject      *object,
         break;
       g_return_if_fail (openssl->have_cert == FALSE);
       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)
@@ -397,8 +410,11 @@ g_tls_certificate_openssl_set_property (GObject      *object,
         break;
       g_return_if_fail (openssl->have_key == FALSE);
       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)
@@ -417,8 +433,11 @@ g_tls_certificate_openssl_set_property (GObject      *object,
         break;
       g_return_if_fail (openssl->have_key == FALSE);
       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
