Skip to content

Commit d975e16

Browse files
committed
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
1 parent 4ee9db0 commit d975e16

File tree

1 file changed

+56
-4
lines changed

1 file changed

+56
-4
lines changed

src/bin/pg_dump/pg_backup_archiver.c

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ static ArchiveHandle *_allocAH(const char *FileSpec, const ArchiveFormat fmt,
8383
static void _getObjectDescription(PQExpBuffer buf, TocEntry *te,
8484
ArchiveHandle *AH);
8585
static void _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isData, bool acl_pass);
86+
static char *replace_line_endings(const char *str);
8687

8788

8889
static void _doSetFixedOutputState(ArchiveHandle *AH);
@@ -2803,6 +2804,9 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
28032804
if (!AH->noTocComments)
28042805
{
28052806
const char *pfx;
2807+
char *sanitized_name;
2808+
char *sanitized_schema;
2809+
char *sanitized_owner;
28062810

28072811
if (isData)
28082812
pfx = "Data for ";
@@ -2824,12 +2828,39 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
28242828
ahprintf(AH, "\n");
28252829
}
28262830
}
2831+
2832+
/*
2833+
* Zap any line endings embedded in user-supplied fields, to prevent
2834+
* corruption of the dump (which could, in the worst case, present an
2835+
* SQL injection vulnerability if someone were to incautiously load a
2836+
* dump containing objects with maliciously crafted names).
2837+
*/
2838+
sanitized_name = replace_line_endings(te->tag);
2839+
if (te->namespace)
2840+
sanitized_schema = replace_line_endings(te->namespace);
2841+
else
2842+
sanitized_schema = strdup("-");
2843+
if (!ropt->noOwner)
2844+
sanitized_owner = replace_line_endings(te->owner);
2845+
else
2846+
sanitized_owner = strdup("-");
2847+
28272848
ahprintf(AH, "-- %sName: %s; Type: %s; Schema: %s; Owner: %s",
2828-
pfx, te->tag, te->desc,
2829-
te->namespace ? te->namespace : "-",
2830-
ropt->noOwner ? "-" : te->owner);
2849+
pfx, sanitized_name, te->desc, sanitized_schema,
2850+
sanitized_owner);
2851+
2852+
free(sanitized_name);
2853+
free(sanitized_schema);
2854+
free(sanitized_owner);
2855+
28312856
if (te->tablespace && !ropt->noTablespace)
2832-
ahprintf(AH, "; Tablespace: %s", te->tablespace);
2857+
{
2858+
char *sanitized_tablespace;
2859+
2860+
sanitized_tablespace = replace_line_endings(te->tablespace);
2861+
ahprintf(AH, "; Tablespace: %s", sanitized_tablespace);
2862+
free(sanitized_tablespace);
2863+
}
28332864
ahprintf(AH, "\n");
28342865

28352866
if (AH->PrintExtraTocPtr !=NULL)
@@ -2921,6 +2952,27 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
29212952
}
29222953
}
29232954

2955+
/*
2956+
* Sanitize a string to be included in an SQL comment, by replacing any
2957+
* newlines with spaces.
2958+
*/
2959+
static char *
2960+
replace_line_endings(const char *str)
2961+
{
2962+
char *result;
2963+
char *s;
2964+
2965+
result = strdup(str);
2966+
2967+
for (s = result; *s != '\0'; s++)
2968+
{
2969+
if (*s == '\n' || *s == '\r')
2970+
*s = ' ';
2971+
}
2972+
2973+
return result;
2974+
}
2975+
29242976
void
29252977
WriteHead(ArchiveHandle *AH)
29262978
{

0 commit comments

Comments
 (0)