commit 5a9783fc2fdd9ea8723d2cd7c3737b854c12fc25 Author: Jacob Champion 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, "", "", "", ¶ms, 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) {