10000 Sanitize newlines in object names in "pg_restore -l" output. · anrs/postgres@e6d2ba4 · GitHub
[go: up one dir, main page]

Skip to content

Commit e6d2ba4

Browse files
committed
Sanitize newlines in object names in "pg_restore -l" output.
Commits 89e0bac et al replaced newlines with spaces in object names printed in SQL comments, but we neglected to consider that the same names are also printed by "pg_restore -l", and a newline would render the output unparseable by "pg_restore -L". Apply the same replacement in "-l" output. Since "pg_restore -L" doesn't actually examine any object names, only the dump ID field that starts each line, this is enough to fix things for its purposes. The previous fix was treated as a security issue, and we might have done that here as well, except that the issue was reported publicly to start with. Anyway it's hard to see how this could be exploited for SQL injection; "pg_restore -L" doesn't do much with the file except parse it for leading integers. Per bug #14587 from Milos Urbanek. Back-patch to all supported versions. Discussion: https://postgr.es/m/20170310155318.1425.30483@wrigleys.postgresql.org
1 parent 731afc9 commit e6d2ba4

File tree

1 file changed

+34
-5
lines changed

1 file changed

+34
-5
lines changed

src/bin/pg_dump/pg_backup_archiver.c

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -938,7 +938,8 @@ PrintTOCSummary(Archive *AHX, RestoreOptions *ropt)
938938

939939
ahprintf(AH, ";\n; Archive created at %s", ctime(&AH->createDate));
940940
ahprintf(AH, "; dbname: %s\n; TOC Entries: %d\n; Compression: %d\n",
941-
AH->archdbname, AH->tocCount, AH->compression);
941+
replace_line_endings(AH->archdbname),
942+
AH->tocCount, AH->compression);
942943

943944
switch (AH->format)
944945
{
@@ -975,10 +976,37 @@ PrintTOCSummary(Archive *AHX, RestoreOptions *ropt)
975976
curSection = te->section;
976977
if (ropt->verbose ||
977978
(_tocEntryRequired(te, curSection, ropt) & (REQ_SCHEMA | REQ_DATA)) != 0)
979+
{
980+
char *sanitized_name;
981+
char *sanitized_schema;
982+
char *sanitized_owner;
983+
984+
/*
985+
* As in _printTocEntry(), sanitize strings that might contain
986+
* newlines, to ensure that each logical output line is in fact
987+
* one physical output line. This prevents confusion when the
988+
* file is read by "pg_restore -L". Note that we currently don't
989+
* bother to quote names, meaning that the name fields aren't
990+
* automatically parseable. "pg_restore -L" doesn't care because
991+
* it only examines the dumpId field, but someday we might want to
992+
* try harder.
993+
*/
994+
sanitized_name = replace_line_endings(te->tag);
995+
if (te->namespace)
996+
sanitized_schema = replace_line_endings(te->namespace);
997+
else
998+
sanitized_schema = pg_strdup("-");
999+
sanitized_owner = replace_line_endings(te->owner);
1000+
9781001
ahprintf(AH, "%d; %u %u %s %s %s %s\n", te->dumpId,
9791002
te->catalogId.tableoid, te->catalogId.oid,
980-
te->desc, te->namespace ? te->namespace : "-",
981-
te->tag, te->owner);
1003+
te->desc, sanitized_schema, sanitized_name,
1004+
sanitized_owner);
1005+
1006+
free(sanitized_name);
1007+
free(sanitized_schema);
1008+
free(sanitized_owner);
1009+
}
9821010
if (ropt->verbose && te->nDeps > 0)
9831011
{
9841012
int i;
@@ -3231,8 +3259,9 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
32313259
}
32323260

32333261
/*
3234-
* Sanitize a string to be included in an SQL comment, by replacing any
3235-
* newlines with spaces.
3262+
* Sanitize a string to be included in an SQL comment or TOC listing,
3263+
* by replacing any newlines with spaces.
3264+
* The result is a freshly malloc'd string.
32363265
*/
32373266
static char *
32383267
replace_line_endings(const char *str)

0 commit comments

Comments
 (0)
0