diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2012-02-23 15:53:34 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2012-02-23 15:53:34 -0500 |
commit | a7f6cb85486b1f3eacd86155af2fdc20a1dc2bec (patch) | |
tree | d06fa9ce0fcf382574e0914f46bc1e581786896c | |
parent | d1b8b8fbea0b34907b9571d2f7506e2089adb011 (diff) | |
download | postgresql-a7f6cb85486b1f3eacd86155af2fdc20a1dc2bec.tar.gz postgresql-a7f6cb85486b1f3eacd86155af2fdc20a1dc2bec.zip |
Convert newlines to spaces in names written in pg_dump comments.
pg_dump was incautious about sanitizing object names that are emitted
within SQL comments in its output script. A name containing a newline
would at least render the script syntactically incorrect. Maliciously
crafted object names could present a SQL injection risk when the script
is reloaded.
Reported by Heikki Linnakangas, patch by Robert Haas
Security: CVE-2012-0868
-rw-r--r-- | src/bin/pg_dump/pg_backup_archiver.c | 60 |
1 files changed, 56 insertions, 4 deletions
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c index 12e27288450..cec764fd59c 100644 --- a/src/bin/pg_dump/pg_backup_archiver.c +++ b/src/bin/pg_dump/pg_backup_archiver.c @@ -44,6 +44,7 @@ static ArchiveHandle *_allocAH(const char *FileSpec, const ArchiveFormat fmt, static void _getObjectDescription(PQExpBuffer buf, TocEntry *te, ArchiveHandle *AH); static void _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isData, bool acl_pass); +static char *replace_line_endings(const char *str); static void _doSetFixedOutputState(ArchiveHandle *AH); @@ -2574,6 +2575,9 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat if (!AH->noTocComments) { const char *pfx; + char *sanitized_name; + char *sanitized_schema; + char *sanitized_owner; if (isData) pfx = "Data for "; @@ -2595,12 +2599,39 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat ahprintf(AH, "\n"); } } + + /* + * Zap any line endings embedded in user-supplied fields, to prevent + * corruption of the dump (which could, in the worst case, present an + * SQL injection vulnerability if someone were to incautiously load a + * dump containing objects with maliciously crafted names). + */ + sanitized_name = replace_line_endings(te->tag); + if (te->namespace) + sanitized_schema = replace_line_endings(te->namespace); + else + sanitized_schema = strdup("-"); + if (!ropt->noOwner) + sanitized_owner = replace_line_endings(te->owner); + else + sanitized_owner = strdup("-"); + ahprintf(AH, "-- %sName: %s; Type: %s; Schema: %s; Owner: %s", - pfx, te->tag, te->desc, - te->namespace ? te->namespace : "-", - ropt->noOwner ? "-" : te->owner); + pfx, sanitized_name, te->desc, sanitized_schema, + sanitized_owner); + + free(sanitized_name); + free(sanitized_schema); + free(sanitized_owner); + if (te->tablespace) - ahprintf(AH, "; Tablespace: %s", te->tablespace); + { + char *sanitized_tablespace; + + sanitized_tablespace = replace_line_endings(te->tablespace); + ahprintf(AH, "; Tablespace: %s", sanitized_tablespace); + free(sanitized_tablespace); + } ahprintf(AH, "\n"); if (AH->PrintExtraTocPtr !=NULL) @@ -2689,6 +2720,27 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat } } +/* + * Sanitize a string to be included in an SQL comment, by replacing any + * newlines with spaces. + */ +static char * +replace_line_endings(const char *str) +{ + char *result; + char *s; + + result = strdup(str); + + for (s = result; *s != '\0'; s++) + { + if (*s == '\n' || *s == '\r') + *s = ' '; + } + + return result; +} + void WriteHead(ArchiveHandle *AH) { |