aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2009-10-03 20:04:45 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2009-10-03 20:04:45 +0000
commit83a673808dc3a47363eae6388bea8571e2bc07a3 (patch)
tree71637ca690559288d1ccb3eaec972c356e2c3155
parent70b533e029728cd364cac5134d3ba991044cf3ef (diff)
downloadpostgresql-83a673808dc3a47363eae6388bea8571e2bc07a3.tar.gz
postgresql-83a673808dc3a47363eae6388bea8571e2bc07a3.zip
Fix assorted memory leaks in pg_hba.conf parsing. Over a sufficiently
large number of SIGHUP cycles, these would have run the postmaster out of memory. Noted while testing memory-leak scenario in postgresql.conf configuration-change-printing patch.
-rw-r--r--src/backend/libpq/hba.c28
1 files changed, 16 insertions, 12 deletions
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index 27e0c431ca8..d5f44bb49f6 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.188 2009/06/24 13:39:42 mha Exp $
+ * $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.188.2.1 2009/10/03 20:04:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -710,6 +710,8 @@ parse_hba_line(List *line, int line_num, HbaLine *parsedline)
line_num, HbaFileName)));
return false;
}
+
+ /* need a modifiable copy of token */
token = pstrdup(lfirst(line_item));
/* Check if it has a CIDR suffix and if so isolate it */
@@ -736,16 +738,12 @@ parse_hba_line(List *line, int line_num, HbaLine *parsedline)
token, gai_strerror(ret)),
errcontext("line %d of configuration file \"%s\"",
line_num, HbaFileName)));
- if (cidr_slash)
- *cidr_slash = '/';
if (gai_result)
pg_freeaddrinfo_all(hints.ai_family, gai_result);
+ pfree(token);
return false;
}
- if (cidr_slash)
- *cidr_slash = '/';
-
memcpy(&parsedline->addr, gai_result->ai_addr, gai_result->ai_addrlen);
pg_freeaddrinfo_all(hints.ai_family, gai_result);
@@ -755,18 +753,22 @@ parse_hba_line(List *line, int line_num, HbaLine *parsedline)
if (pg_sockaddr_cidr_mask(&parsedline->mask, cidr_slash + 1,
parsedline->addr.ss_family) < 0)
{
+ *cidr_slash = '/'; /* restore token for message */
ereport(LOG,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("invalid CIDR mask in address \"%s\"",
token),
errcontext("line %d of configuration file \"%s\"",
line_num, HbaFileName)));
+ pfree(token);
return false;
}
+ pfree(token);
}
else
{
/* Read the mask field. */
+ pfree(token);
line_item = lnext(line_item);
if (!line_item)
{
@@ -1253,7 +1255,7 @@ load_role(void)
}
/*
- * Free the contents of a hba record
+ * Free an HbaLine structure
*/
static void
free_hba_record(HbaLine *record)
@@ -1262,6 +1264,8 @@ free_hba_record(HbaLine *record)
pfree(record->database);
if (record->role)
pfree(record->role);
+ if (record->usermap)
+ pfree(record->usermap);
if (record->pamservice)
pfree(record->pamservice);
if (record->ldapserver)
@@ -1274,6 +1278,7 @@ free_hba_record(HbaLine *record)
pfree(record->krb_server_hostname);
if (record->krb_realm)
pfree(record->krb_realm);
+ pfree(record);
}
/*
@@ -1342,20 +1347,22 @@ load_hba(void)
{
/* Parse error in the file, so indicate there's a problem */
free_hba_record(newline);
- pfree(newline);
+ ok = false;
/*
* Keep parsing the rest of the file so we can report errors on
* more than the first row. Error has already been reported in the
* parsing function, so no need to log it here.
*/
- ok = false;
continue;
}
new_parsed_lines = lappend(new_parsed_lines, newline);
}
+ /* Free the temporary lists */
+ free_lines(&hba_lines, &hba_line_nums);
+
if (!ok)
{
/* Parsing failed at one or more rows, so bail out */
@@ -1367,9 +1374,6 @@ load_hba(void)
clean_hba_list(parsed_hba_lines);
parsed_hba_lines = new_parsed_lines;
- /* Free the temporary lists */
- free_lines(&hba_lines, &hba_line_nums);
-
return true;
}