patch

application/octet-stream

Filename: patch
Type: application/octet-stream
Part: 0
Message: Re: Support for NSS as a libpq TLS backend
From e18895eb33b3ab6c66c1cd461061096784a62e3a Mon Sep 17 00:00:00 2001
From: Jacob Champion <pchampion@vmware.com>
Date: Wed, 11 Nov 2020 09:56:48 -0800
Subject: [PATCH] init_iolayer: manage fd->secret during close

In debug builds, NSPR's default close implementation for descriptors
checks to make sure that any private fd->secret has been NULLed out,
presumably to prove that NSPR does not leak the last reference to
allocated memory. Add a custom close implementation to handle the Port
that is connected to the fd.
---
 src/backend/libpq/be-secure-nss.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/src/backend/libpq/be-secure-nss.c b/src/backend/libpq/be-secure-nss.c
index 86ac400782..76523e9870 100644
--- a/src/backend/libpq/be-secure-nss.c
+++ b/src/backend/libpq/be-secure-nss.c
@@ -477,9 +477,6 @@ be_tls_open_server(Port *port)
 	if (!layer)
 		goto error;
 
-	/* Store the Port as private data available in callbacks */
-	layer->secret = (void *) port;
-
 	if (PR_PushIOLayer(pr_fd, PR_TOP_IO_LAYER, layer) != PR_SUCCESS)
 	{
 		PR_Close(layer);
@@ -1052,6 +1049,17 @@ pg_ssl_write(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
 	return n_write;
 }
 
+static PRStatus
+pg_ssl_close(PRFileDesc *fd)
+{
+	/*
+	 * Disconnect our private Port from the fd before closing out the stack.
+	 * (Debug builds of NSPR will assert if we do not.)
+	 */
+	fd->secret = NULL;
+	return PR_GetDefaultIOMethods()->close(fd);
+}
+
 static PRFileDesc *
 init_iolayer(Port *port)
 {
@@ -1068,6 +1076,7 @@ init_iolayer(Port *port)
 
 	pr_iomethods.recv = pg_ssl_read;
 	pr_iomethods.send = pg_ssl_write;
+	pr_iomethods.close = pg_ssl_close;
 
 	/*
 	 * Each IO layer must be identified by a unique name, where uniqueness is
@@ -1096,6 +1105,9 @@ init_iolayer(Port *port)
 		return NULL;
 	}
 
+	/* Store the Port as private data available in callbacks */
+	layer->secret = (void *) port;
+
 	return layer;
 }
 
-- 
2.24.1