From 91cbb4b492cbea889e8392a85e246c1778ca2a45 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 1 Apr 2024 13:47:27 -0400 Subject: [PATCH] Fix assorted resource leaks in new pg_createsubscriber code. Various error paths did not release resources before returning. While it's likely that the program would just exit shortly later, none of the functions in question have summary exit(1) calls, so they should not be assuming that. Ranier Vilela and Tom Lane, per reports from Coverity Discussion: https://postgr.es/m/CAEudQAr2_SZFxB4kXJiL4+2UaNZxUk5UBJtj0oXyJYMGZu-03g@mail.gmail.com --- src/bin/pg_basebackup/pg_createsubscriber.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/bin/pg_basebackup/pg_createsubscriber.c b/src/bin/pg_basebackup/pg_createsubscriber.c index a6e0986670..90cc580811 100644 --- a/src/bin/pg_basebackup/pg_createsubscriber.c +++ b/src/bin/pg_basebackup/pg_createsubscriber.c @@ -251,8 +251,8 @@ usage(void) static char * get_base_conninfo(const char *conninfo, char **dbname) { - PQExpBuffer buf = createPQExpBuffer(); - PQconninfoOption *conn_opts = NULL; + PQExpBuffer buf; + PQconninfoOption *conn_opts; PQconninfoOption *conn_opt; char *errmsg = NULL; char *ret; @@ -262,9 +262,11 @@ get_base_conninfo(const char *conninfo, char **dbname) if (conn_opts == NULL) { pg_log_error("could not parse connection string: %s", errmsg); + PQfreemem(errmsg); return NULL; } + buf = createPQExpBuffer(); i = 0; for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++) { @@ -497,9 +499,10 @@ connect_database(const char *conninfo, bool exit_on_error) { pg_log_error("connection to database failed: %s", PQerrorMessage(conn)); + PQfinish(conn); + if (exit_on_error) exit(1); - return NULL; } @@ -509,9 +512,11 @@ connect_database(const char *conninfo, bool exit_on_error) { pg_log_error("could not clear search_path: %s", PQresultErrorMessage(res)); + PQclear(res); + PQfinish(conn); + if (exit_on_error) exit(1); - return NULL; } PQclear(res); @@ -941,6 +946,8 @@ check_publisher(const struct LogicalRepInfo *dbinfo) failed = true; } + pg_free(wal_level); + if (failed) exit(1); } @@ -1209,6 +1216,8 @@ create_logical_replication_slot(PGconn *conn, struct LogicalRepInfo *dbinfo) pg_log_error("could not create replication slot \"%s\" on database \"%s\": %s", slot_name, dbinfo->dbname, PQresultErrorMessage(res)); + PQclear(res); + destroyPQExpBuffer(str); return NULL; }