From 168c8f4b62bdbbf905af9d0c7f3f7af68cf8c6e9 Mon Sep 17 00:00:00 2001
From: Daniel Gustafsson <dgustafsson@postgresql.org>
Date: Wed, 20 Sep 2023 10:31:10 +0200
Subject: [PATCH v2] Avoid potential pfree on NULL on OpenSSL errors

Guard against the pointer being NULL before pfreeing upon en error
returned from OpenSSL.  Also handle errors from X509_NAME_print_ex
which also can return -1 on memory allocation errors.

Author: Sergey Shinderuk <s.shinderuk@postgrespro.ru>
Discussion: https://postgr.es/m/8db5374d-32e0-6abb-d402-40762511eff2@postgrespro.ru
---
 src/backend/libpq/be-secure-openssl.c | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
index 658b09988d..31b6a6eacd 100644
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -620,8 +620,11 @@ aloop:
 		bio = BIO_new(BIO_s_mem());
 		if (!bio)
 		{
-			pfree(port->peer_cn);
-			port->peer_cn = NULL;
+			if (port->peer_cn != NULL)
+			{
+				pfree(port->peer_cn);
+				port->peer_cn = NULL;
+			}
 			return -1;
 		}
 
@@ -632,12 +635,15 @@ aloop:
 		 * which make regular expression matching a bit easier. Also note that
 		 * it prints the Subject fields in reverse order.
 		 */
-		X509_NAME_print_ex(bio, x509name, 0, XN_FLAG_RFC2253);
-		if (BIO_get_mem_ptr(bio, &bio_buf) <= 0)
+		if (X509_NAME_print_ex(bio, x509name, 0, XN_FLAG_RFC2253) == -1 ||
+			BIO_get_mem_ptr(bio, &bio_buf) <= 0)
 		{
 			BIO_free(bio);
-			pfree(port->peer_cn);
-			port->peer_cn = NULL;
+			if (port->peer_cn != NULL)
+			{
+				pfree(port->peer_cn);
+				port->peer_cn = NULL;
+			}
 			return -1;
 		}
 		peer_dn = MemoryContextAlloc(TopMemoryContext, bio_buf->length + 1);
@@ -651,8 +657,11 @@ aloop:
 					(errcode(ERRCODE_PROTOCOL_VIOLATION),
 					 errmsg("SSL certificate's distinguished name contains embedded null")));
 			pfree(peer_dn);
-			pfree(port->peer_cn);
-			port->peer_cn = NULL;
+			if (port->peer_cn != NULL)
+			{
+				pfree(port->peer_cn);
+				port->peer_cn = NULL;
+			}
 			return -1;
 		}
 
-- 
2.32.1 (Apple Git-133)

