since-v43.diff.txt

text/plain

Filename: since-v43.diff.txt
Type: text/plain
Part: 0
Message: Re: Support for NSS as a libpq TLS backend
commit 5a9783fc2fdd9ea8723d2cd7c3737b854c12fc25
Author: Jacob Champion <pchampion@vmware.com>
Date:   Mon Oct 4 08:59:46 2021 -0700

    squash! nss: Support libnss as TLS library in libpq
    
    Don't use palloc() in front-end code.
    
    - ssl_protocol_version_to_string() returns static allocations for the
      OpenSSL implementation, so do the same here.
    - Use PQExpBuffers for sprintf-style allocation.
    - Use plain malloc() rather than pg_malloc().

diff --git a/src/common/protocol_nss.c b/src/common/protocol_nss.c
index e8225a4d9d..4d12c9f388 100644
--- a/src/common/protocol_nss.c
+++ b/src/common/protocol_nss.c
@@ -39,21 +39,21 @@ ssl_protocol_version_to_string(int v)
 			break;
 
 		case SSL_LIBRARY_VERSION_TLS_1_0:
-			return pstrdup("TLSv1.0");
+			return "TLSv1.0";
 #ifdef SSL_LIBRARY_VERSION_TLS_1_1
 		case SSL_LIBRARY_VERSION_TLS_1_1:
-			return pstrdup("TLSv1.1");
+			return "TLSv1.1";
 #endif
 #ifdef SSL_LIBRARY_VERSION_TLS_1_2
 		case SSL_LIBRARY_VERSION_TLS_1_2:
-			return pstrdup("TLSv1.2");
+			return "TLSv1.2";
 #endif
 #ifdef SSL_LIBRARY_VERSION_TLS_1_3
 		case SSL_LIBRARY_VERSION_TLS_1_3:
-			return pstrdup("TLSv1.3");
+			return "TLSv1.3";
 #endif
 	}
 
-	return pstrdup("unknown");
+	return "unknown";
 }
 
diff --git a/src/interfaces/libpq/fe-secure-nss.c b/src/interfaces/libpq/fe-secure-nss.c
index 51f09fb7fa..e1574997ee 100644
--- a/src/interfaces/libpq/fe-secure-nss.c
+++ b/src/interfaces/libpq/fe-secure-nss.c
@@ -229,12 +229,22 @@ pgtls_open_client(PGconn *conn)
 
 	if (conn->ssldatabase && strlen(conn->ssldatabase) > 0)
 	{
-		char	   *ssldatabase_path = psprintf("sql:%s", conn->ssldatabase);
+		PQExpBufferData ssldatabase_path;
 
-		conn->nss_context = NSS_InitContext(ssldatabase_path, "", "", "",
+		initPQExpBuffer(&ssldatabase_path);
+		appendPQExpBuffer(&ssldatabase_path, "sql:%s", conn->ssldatabase);
+
+		if (PQExpBufferDataBroken(ssldatabase_path))
+		{
+			printfPQExpBuffer(&conn->errorMessage,
+							  libpq_gettext("out of memory\n"));
+			return PGRES_POLLING_FAILED;
+		}
+
+		conn->nss_context = NSS_InitContext(ssldatabase_path.data, "", "", "",
 											&params,
 											NSS_INIT_READONLY | NSS_INIT_PK11RELOAD);
-		pfree(ssldatabase_path);
+		termPQExpBuffer(&ssldatabase_path);
 
 		if (!conn->nss_context)
 		{
@@ -647,7 +657,14 @@ pgtls_get_peer_certificate_hash(PGconn *conn, size_t *len)
 		goto cleanup;
 	}
 
-	ret = pg_malloc(digest.len);
+	ret = malloc(digest.len);
+	if (ret == NULL)
+	{
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("out of memory\n"));
+		goto cleanup;
+	}
+
 	memcpy(ret, digest.data, digest.len);
 	*len = digest_len;
 
@@ -799,9 +816,15 @@ static SECStatus
 pg_load_nss_module(SECMODModule **module, const char *library, const char *name)
 {
 	SECMODModule *mod;
-	char	   *modulespec;
+	PQExpBufferData modulespec;
 
-	modulespec = psprintf("library=\"%s\", name=\"%s\"", library, name);
+	initPQExpBuffer(&modulespec);
+	appendPQExpBuffer(&modulespec, "library=\"%s\", name=\"%s\"", library, name);
+	if (PQExpBufferDataBroken(modulespec))
+	{
+		PR_SetError(SEC_ERROR_NO_MEMORY, 0);
+		return SECFailure;
+	}
 
 	/*
 	 * Attempt to load the specified module. The second parameter is "parent"
@@ -811,8 +834,8 @@ pg_load_nss_module(SECMODModule **module, const char *library, const char *name)
 	 * defined in the modulespec, and since we don't support anything but
 	 * directly addressed modules we should pass PR_FALSE.
 	 */
-	mod = SECMOD_LoadUserModule(modulespec, NULL, PR_FALSE);
-	pfree(modulespec);
+	mod = SECMOD_LoadUserModule(modulespec.data, NULL, PR_FALSE);
+	termPQExpBuffer(&modulespec);
 
 	if (mod && mod->loaded)
 	{