Commit 35a173ab authored by Tom Lane's avatar Tom Lane

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.
parent 54d60bbd
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.191 2009/10/01 01:58:57 tgl Exp $ * $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.192 2009/10/03 20:04:39 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -804,16 +804,12 @@ parse_hba_line(List *line, int line_num, HbaLine *parsedline) ...@@ -804,16 +804,12 @@ parse_hba_line(List *line, int line_num, HbaLine *parsedline)
token, gai_strerror(ret)), token, gai_strerror(ret)),
errcontext("line %d of configuration file \"%s\"", errcontext("line %d of configuration file \"%s\"",
line_num, HbaFileName))); line_num, HbaFileName)));
if (cidr_slash)
*cidr_slash = '/';
if (gai_result) if (gai_result)
pg_freeaddrinfo_all(hints.ai_family, gai_result); pg_freeaddrinfo_all(hints.ai_family, gai_result);
pfree(token);
return false; return false;
} }
if (cidr_slash)
*cidr_slash = '/';
memcpy(&parsedline->addr, gai_result->ai_addr, memcpy(&parsedline->addr, gai_result->ai_addr,
gai_result->ai_addrlen); gai_result->ai_addrlen);
pg_freeaddrinfo_all(hints.ai_family, gai_result); pg_freeaddrinfo_all(hints.ai_family, gai_result);
...@@ -824,18 +820,22 @@ parse_hba_line(List *line, int line_num, HbaLine *parsedline) ...@@ -824,18 +820,22 @@ parse_hba_line(List *line, int line_num, HbaLine *parsedline)
if (pg_sockaddr_cidr_mask(&parsedline->mask, cidr_slash + 1, if (pg_sockaddr_cidr_mask(&parsedline->mask, cidr_slash + 1,
parsedline->addr.ss_family) < 0) parsedline->addr.ss_family) < 0)
{ {
*cidr_slash = '/'; /* restore token for message */
ereport(LOG, ereport(LOG,
(errcode(ERRCODE_CONFIG_FILE_ERROR), (errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("invalid CIDR mask in address \"%s\"", errmsg("invalid CIDR mask in address \"%s\"",
token), token),
errcontext("line %d of configuration file \"%s\"", errcontext("line %d of configuration file \"%s\"",
line_num, HbaFileName))); line_num, HbaFileName)));
pfree(token);
return false; return false;
} }
pfree(token);
} }
else else
{ {
/* Read the mask field. */ /* Read the mask field. */
pfree(token);
line_item = lnext(line_item); line_item = lnext(line_item);
if (!line_item) if (!line_item)
{ {
...@@ -1266,7 +1266,7 @@ check_hba(hbaPort *port) ...@@ -1266,7 +1266,7 @@ check_hba(hbaPort *port)
} }
/* /*
* Free the contents of a hba record * Free an HbaLine structure
*/ */
static void static void
free_hba_record(HbaLine *record) free_hba_record(HbaLine *record)
...@@ -1275,6 +1275,8 @@ free_hba_record(HbaLine *record) ...@@ -1275,6 +1275,8 @@ free_hba_record(HbaLine *record)
pfree(record->database); pfree(record->database);
if (record->role) if (record->role)
pfree(record->role); pfree(record->role);
if (record->usermap)
pfree(record->usermap);
if (record->pamservice) if (record->pamservice)
pfree(record->pamservice); pfree(record->pamservice);
if (record->ldapserver) if (record->ldapserver)
...@@ -1287,6 +1289,7 @@ free_hba_record(HbaLine *record) ...@@ -1287,6 +1289,7 @@ free_hba_record(HbaLine *record)
pfree(record->krb_server_hostname); pfree(record->krb_server_hostname);
if (record->krb_realm) if (record->krb_realm)
pfree(record->krb_realm); pfree(record->krb_realm);
pfree(record);
} }
/* /*
...@@ -1355,20 +1358,22 @@ load_hba(void) ...@@ -1355,20 +1358,22 @@ load_hba(void)
{ {
/* Parse error in the file, so indicate there's a problem */ /* Parse error in the file, so indicate there's a problem */
free_hba_record(newline); free_hba_record(newline);
pfree(newline); ok = false;
/* /*
* Keep parsing the rest of the file so we can report errors on * 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 * more than the first row. Error has already been reported in the
* parsing function, so no need to log it here. * parsing function, so no need to log it here.
*/ */
ok = false;
continue; continue;
} }
new_parsed_lines = lappend(new_parsed_lines, newline); new_parsed_lines = lappend(new_parsed_lines, newline);
} }
/* Free the temporary lists */
free_lines(&hba_lines, &hba_line_nums);
if (!ok) if (!ok)
{ {
/* Parsing failed at one or more rows, so bail out */ /* Parsing failed at one or more rows, so bail out */
...@@ -1380,9 +1385,6 @@ load_hba(void) ...@@ -1380,9 +1385,6 @@ load_hba(void)
clean_hba_list(parsed_hba_lines); clean_hba_list(parsed_hba_lines);
parsed_hba_lines = new_parsed_lines; parsed_hba_lines = new_parsed_lines;
/* Free the temporary lists */
free_lines(&hba_lines, &hba_line_nums);
return true; return true;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment