From e18895eb33b3ab6c66c1cd461061096784a62e3a Mon Sep 17 00:00:00 2001 From: Jacob Champion 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