Skip to content

Commit 0f9d4d7

Browse files
committed
Silence leakage complaint about postgres_fdw's InitPgFdwOptions.
Valgrind complains that the PQconninfoOption array returned by libpq is leaked. We apparently believed that we could suppress that warning by storing that array's address in a static variable. However, modern C compilers are bright enough to optimize the static variable away. We could escalate that arms race by making the variable global. But on the whole it seems better to revise the code so that it can free libpq's result properly. The only thing that costs us is copying the parameter-name keywords; which seems like a pretty negligible cost in a function that runs at most once per process. Author: Tom Lane <tgl@sss.pgh.pa.us> Reviewed-by: Matheus Alcantara <matheusssilv97@gmail.com> Discussion: https://postgr.es/m/2976982.1748049023@sss.pgh.pa.us
1 parent 7387380 commit 0f9d4d7

File tree

1 file changed

+12
-21
lines changed

1 file changed

+12
-21
lines changed

contrib/postgres_fdw/option.c

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "libpq/libpq-be.h"
2222
#include "postgres_fdw.h"
2323
#include "utils/guc.h"
24+
#include "utils/memutils.h"
2425
#include "utils/varlena.h"
2526

2627
/*
@@ -39,12 +40,6 @@ typedef struct PgFdwOption
3940
*/
4041
static PgFdwOption *postgres_fdw_options;
4142

42-
/*
43-
* Valid options for libpq.
44-
* Allocated and filled in InitPgFdwOptions.
45-
*/
46-
static PQconninfoOption *libpq_options;
47-
4843
/*
4944
* GUC parameters
5045
*/
@@ -239,6 +234,7 @@ static void
239234
InitPgFdwOptions(void)
240235
{
241236
int num_libpq_opts;
237+
PQconninfoOption *libpq_options;
242238
PQconninfoOption *lopt;
243239
PgFdwOption *popt;
244240

@@ -307,8 +303,8 @@ InitPgFdwOptions(void)
307303
* Get list of valid libpq options.
308304
*
309305
* To avoid unnecessary work, we get the list once and use it throughout
310-
* the lifetime of this backend process. We don't need to care about
311-
* memory context issues, because PQconndefaults allocates with malloc.
306+
* the lifetime of this backend process. Hence, we'll allocate it in
307+
* TopMemoryContext.
312308
*/
313309
libpq_options = PQconndefaults();
314310
if (!libpq_options) /* assume reason for failure is OOM */
@@ -325,19 +321,11 @@ InitPgFdwOptions(void)
325321
/*
326322
* Construct an array which consists of all valid options for
327323
* postgres_fdw, by appending FDW-specific options to libpq options.
328-
*
329-
* We use plain malloc here to allocate postgres_fdw_options because it
330-
* lives as long as the backend process does. Besides, keeping
331-
* libpq_options in memory allows us to avoid copying every keyword
332-
* string.
333324
*/
334325
postgres_fdw_options = (PgFdwOption *)
335-
malloc(sizeof(PgFdwOption) * num_libpq_opts +
336-
sizeof(non_libpq_options));
337-
if (postgres_fdw_options == NULL)
338-
ereport(ERROR,
339-
(errcode(ERRCODE_FDW_OUT_OF_MEMORY),
340-
errmsg("out of memory")));
326+
MemoryContextAlloc(TopMemoryContext,
327+
sizeof(PgFdwOption) * num_libpq_opts +
328+
sizeof(non_libpq_options));
341329

342330
popt = postgres_fdw_options;
343331
for (lopt = libpq_options; lopt->keyword; lopt++)
@@ -355,8 +343,8 @@ InitPgFdwOptions(void)
355343
if (strncmp(lopt->keyword, "oauth_", strlen("oauth_")) == 0)
356344
continue;
357345

358-
/* We don't have to copy keyword string, as described above. */
359-
popt->keyword = lopt->keyword;
346+
popt->keyword = MemoryContextStrdup(TopMemoryContext,
347+
lopt->keyword);
360348

361349
/*
362350
* "user" and any secret options are allowed only on user mappings.
@@ -371,6 +359,9 @@ InitPgFdwOptions(void)
371359
popt++;
372360
}
373361

362+
/* Done with libpq's output structure. */
363+
PQconninfoFree(libpq_options);
364+
374365
/* Append FDW-specific options and dummy terminator. */
375366
memcpy(popt, non_libpq_options, sizeof(non_libpq_options));
376367
}

0 commit comments

Comments
 (0)