summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bin/pg_dump/dumputils.c37
-rw-r--r--src/bin/pg_dump/dumputils.h1
-rw-r--r--src/bin/pg_dump/pg_backup_archiver.c37
-rw-r--r--src/bin/pg_dump/pg_dump.c5
-rw-r--r--src/bin/pg_dump/pg_dumpall.c13
-rw-r--r--src/bin/pg_dump/t/002_pg_dump.pl21
-rw-r--r--src/bin/pg_dump/t/003_pg_dump_with_server.pl17
7 files changed, 90 insertions, 41 deletions
diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c
index 5649859aa1e..9e5748311e0 100644
--- a/src/bin/pg_dump/dumputils.c
+++ b/src/bin/pg_dump/dumputils.c
@@ -30,6 +30,43 @@ static void AddAcl(PQExpBuffer aclbuf, const char *keyword,
/*
+ * Sanitize a string to be included in an SQL comment or TOC listing, by
+ * replacing any newlines with spaces. This ensures each logical output line
+ * is in fact one physical output line, 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).
+ *
+ * The result is a freshly malloc'd string. If the input string is NULL,
+ * return a malloc'ed empty string, unless want_hyphen, in which case return a
+ * malloc'ed hyphen.
+ *
+ * Note that we currently don't bother to quote names, meaning that the name
+ * fields aren't automatically parseable. "pg_restore -L" doesn't care because
+ * it only examines the dumpId field, but someday we might want to try harder.
+ */
+char *
+sanitize_line(const char *str, bool want_hyphen)
+{
+ char *result;
+ char *s;
+
+ if (!str)
+ return pg_strdup(want_hyphen ? "-" : "");
+
+ result = pg_strdup(str);
+
+ for (s = result; *s != '\0'; s++)
+ {
+ if (*s == '\n' || *s == '\r')
+ *s = ' ';
+ }
+
+ return result;
+}
+
+
+/*
* Build GRANT/REVOKE command(s) for an object.
*
* name: the object name, in the form to use in the commands (already quoted)
diff --git a/src/bin/pg_dump/dumputils.h b/src/bin/pg_dump/dumputils.h
index 98c71c6bf94..d1248d9061b 100644
--- a/src/bin/pg_dump/dumputils.h
+++ b/src/bin/pg_dump/dumputils.h
@@ -36,6 +36,7 @@
#endif
+extern char *sanitize_line(const char *str, bool want_hyphen);
extern bool buildACLCommands(const char *name, const char *subname, const char *nspname,
const char *type, const char *acls, const char *baseacls,
const char *owner, const char *prefix, int remoteVersion,
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index f1ffed038b0..9d0b5d0bd7f 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -54,7 +54,6 @@ static ArchiveHandle *_allocAH(const char *FileSpec, const ArchiveFormat fmt,
DataDirSyncMethod sync_method);
static void _getObjectDescription(PQExpBuffer buf, const TocEntry *te);
static void _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData);
-static char *sanitize_line(const char *str, bool want_hyphen);
static void _doSetFixedOutputState(ArchiveHandle *AH);
static void _doSetSessionAuth(ArchiveHandle *AH, const char *user);
static void _reconnectToDB(ArchiveHandle *AH, const char *dbname);
@@ -3916,42 +3915,6 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData)
}
/*
- * Sanitize a string to be included in an SQL comment or TOC listing, by
- * replacing any newlines with spaces. This ensures each logical output line
- * is in fact one physical output line, 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).
- *
- * The result is a freshly malloc'd string. If the input string is NULL,
- * return a malloc'ed empty string, unless want_hyphen, in which case return a
- * malloc'ed hyphen.
- *
- * Note that we currently don't bother to quote names, meaning that the name
- * fields aren't automatically parseable. "pg_restore -L" doesn't care because
- * it only examines the dumpId field, but someday we might want to try harder.
- */
-static char *
-sanitize_line(const char *str, bool want_hyphen)
-{
- char *result;
- char *s;
-
- if (!str)
- return pg_strdup(want_hyphen ? "-" : "");
-
- result = pg_strdup(str);
-
- for (s = result; *s != '\0'; s++)
- {
- if (*s == '\n' || *s == '\r')
- *s = ' ';
- }
-
- return result;
-}
-
-/*
* Write the file header for a custom-format archive
*/
void
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 0f26b018d4a..201b17697a4 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -2657,11 +2657,14 @@ dumpTableData(Archive *fout, const TableDataInfo *tdinfo)
forcePartitionRootLoad(tbinfo)))
{
TableInfo *parentTbinfo;
+ char *sanitized;
parentTbinfo = getRootTableInfo(tbinfo);
copyFrom = fmtQualifiedDumpable(parentTbinfo);
+ sanitized = sanitize_line(copyFrom, true);
printfPQExpBuffer(copyBuf, "-- load via partition root %s",
- copyFrom);
+ sanitized);
+ free(sanitized);
tdDefn = pg_strdup(copyBuf->data);
}
else
diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c
index d5282ecb17a..1f98c89c34a 100644
--- a/src/bin/pg_dump/pg_dumpall.c
+++ b/src/bin/pg_dump/pg_dumpall.c
@@ -1462,7 +1462,13 @@ dumpUserConfig(PGconn *conn, const char *username)
res = executeQuery(conn, buf->data);
if (PQntuples(res) > 0)
- fprintf(OPF, "\n--\n-- User Config \"%s\"\n--\n\n", username);
+ {
+ char *sanitized;
+
+ sanitized = sanitize_line(username, true);
+ fprintf(OPF, "\n--\n-- User Config \"%s\"\n--\n\n", sanitized);
+ free(sanitized);
+ }
for (int i = 0; i < PQntuples(res); i++)
{
@@ -1564,6 +1570,7 @@ dumpDatabases(PGconn *conn)
for (i = 0; i < PQntuples(res); i++)
{
char *dbname = PQgetvalue(res, i, 0);
+ char *sanitized;
const char *create_opts;
int ret;
@@ -1580,7 +1587,9 @@ dumpDatabases(PGconn *conn)
pg_log_info("dumping database \"%s\"", dbname);
- fprintf(OPF, "--\n-- Database \"%s\" dump\n--\n\n", dbname);
+ sanitized = sanitize_line(dbname, true);
+ fprintf(OPF, "--\n-- Database \"%s\" dump\n--\n\n", sanitized);
+ free(sanitized);
/*
* We assume that "template1" and "postgres" already exist in the
diff --git a/src/bin/pg_dump/t/002_pg_dump.pl b/src/bin/pg_dump/t/002_pg_dump.pl
index 58306d307ec..5e256b52d24 100644
--- a/src/bin/pg_dump/t/002_pg_dump.pl
+++ b/src/bin/pg_dump/t/002_pg_dump.pl
@@ -1893,6 +1893,27 @@ my %tests = (
},
},
+ 'newline of role or table name in comment' => {
+ create_sql => qq{CREATE ROLE regress_newline;
+ ALTER ROLE regress_newline SET enable_seqscan = off;
+ ALTER ROLE regress_newline
+ RENAME TO "regress_newline\nattack";
+
+ -- meet getPartitioningInfo() "unsafe" condition
+ CREATE TYPE pp_colors AS
+ ENUM ('green', 'blue', 'black');
+ CREATE TABLE pp_enumpart (a pp_colors)
+ PARTITION BY HASH (a);
+ CREATE TABLE pp_enumpart1 PARTITION OF pp_enumpart
+ FOR VALUES WITH (MODULUS 2, REMAINDER 0);
+ CREATE TABLE pp_enumpart2 PARTITION OF pp_enumpart
+ FOR VALUES WITH (MODULUS 2, REMAINDER 1);
+ ALTER TABLE pp_enumpart
+ RENAME TO "pp_enumpart\nattack";},
+ regexp => qr/\n--[^\n]*\nattack/s,
+ like => {},
+ },
+
'CREATE TABLESPACE regress_dump_tablespace' => {
create_order => 2,
create_sql => q(
diff --git a/src/bin/pg_dump/t/003_pg_dump_with_server.pl b/src/bin/pg_dump/t/003_pg_dump_with_server.pl
index b5a14455507..6948dcd2984 100644
--- a/src/bin/pg_dump/t/003_pg_dump_with_server.pl
+++ b/src/bin/pg_dump/t/003_pg_dump_with_server.pl
@@ -17,6 +17,22 @@ $node->init;
$node->start;
#########################################
+# pg_dumpall: newline in database name
+
+$node->safe_psql('postgres', qq{CREATE DATABASE "regress_\nattack"});
+
+my (@cmd, $stdout, $stderr);
+@cmd = ("pg_dumpall", '--port' => $port, '--exclude-database=postgres');
+print("# Running: " . join(" ", @cmd) . "\n");
+my $result = IPC::Run::run \@cmd, '>' => \$stdout, '2>' => \$stderr;
+ok(!$result, "newline in dbname: exit code not 0");
+like(
+ $stderr,
+ qr/shell command argument contains a newline/,
+ "newline in dbname: stderr matches");
+unlike($stdout, qr/^attack/m, "newline in dbname: no comment escape");
+
+#########################################
# Verify that dumping foreign data includes only foreign tables of
# matching servers
@@ -26,7 +42,6 @@ $node->safe_psql('postgres', "CREATE SERVER s1 FOREIGN DATA WRAPPER dummy");
$node->safe_psql('postgres', "CREATE SERVER s2 FOREIGN DATA WRAPPER dummy");
$node->safe_psql('postgres', "CREATE FOREIGN TABLE t0 (a int) SERVER s0");
$node->safe_psql('postgres', "CREATE FOREIGN TABLE t1 (a int) SERVER s1");
-my ($cmd, $stdout, $stderr, $result);
command_fails_like(
[ "pg_dump", '-p', $port, '--include-foreign-data=s0', 'postgres' ],