aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2012-02-23 15:53:30 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2012-02-23 15:53:30 -0500
commitd975e166052e5992e1d082273f5680e85239b935 (patch)
tree1e21ad8b6776d7ea4b5fb4caed2f884d816f4c3d
parent4ee9db0cd94a1ecfce4f76de29fa213ddc892c6e (diff)
downloadpostgresql-d975e166052e5992e1d082273f5680e85239b935.tar.gz
postgresql-d975e166052e5992e1d082273f5680e85239b935.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.c60
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 9bf0639cbf1..f64046b1a60 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -83,6 +83,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);
@@ -2803,6 +2804,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 ";
@@ -2824,12 +2828,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 && !ropt->noTablespace)
- 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)
@@ -2921,6 +2952,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)
{