From 5f5684523f47e7d3b20c4efad5a9c335aade7831 Mon Sep 17 00:00:00 2001
From: Mats Kindahl <mats@timescale.com>
Date: Thu, 8 Dec 2022 10:00:23 +0100
Subject: Check return value of strdup when starting backend

Inside `BackendInitialize`, if `strdup` returns NULL because it is out
of memory, this will later trigger a server crash because of
dereferencing a null pointer.

This commit fixes this by checking the return values of `strdup` and
exit the backend with exit status 1 if any of the allocations failed.
This will be handled as a normal shutdown in the postmaster, which will
report the exiting backend and continue executing.
---
 src/backend/postmaster/postmaster.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index f459dab360..eef3b7f85c 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -4278,6 +4278,14 @@ BackendInitialize(Port *port)
 	port->remote_host = strdup(remote_host);
 	port->remote_port = strdup(remote_port);
 
+	if (port->remote_host == NULL || port->remote_port == NULL) {
+		/* Since we are out of memory, we use strerror_r and write_stderr
+		   here. They do not allocate memory and just use the stack. */
+		char sebuf[PG_STRERROR_R_BUFLEN];
+		write_stderr("out of memory: %s", strerror_r(errno, sebuf, sizeof(sebuf)));
+		proc_exit(1);
+	}
+
 	/* And now we can issue the Log_connections message, if wanted */
 	if (Log_connections)
 	{
@@ -4307,7 +4315,13 @@ BackendInitialize(Port *port)
 		ret == 0 &&
 		strspn(remote_host, "0123456789.") < strlen(remote_host) &&
 		strspn(remote_host, "0123456789ABCDEFabcdef:") < strlen(remote_host))
+	{
+		/* It is not necessary to check the return value since code that uses
+		 * remote_hostname assumes that if it is NULL, the reverse lookup was
+		 * not done. */
 		port->remote_hostname = strdup(remote_host);
+	}
+
 
 	/*
 	 * Ready to begin client interaction.  We will give up and _exit(1) after
-- 
2.34.1

