Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 89e0bac

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 077711c commit 89e0bac

File tree

1 file changed

+56
-4
lines changed

1 file changed

+56
-4
lines changed

src/bin/pg_dump/pg_backup_archiver.c

+56-4
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ static ArchiveHandle *_allocAH(const char *FileSpec, const ArchiveFormat fmt,
9999
static void _getObjectDescription(PQExpBuffer buf, TocEntry *te,
100100
ArchiveHandle *AH);
101101
static void _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isData, bool acl_pass);
102+
static char *replace_line_endings(const char *str);
102103

103104

104105
static void _doSetFixedOutputState(ArchiveHandle *AH);
@@ -2932,6 +2933,9 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
29322933
if (!AH->noTocComments)
29332934
{
29342935
const char *pfx;
2936+
char *sanitized_name;
2937+
char *sanitized_schema;
2938+
char *sanitized_owner;
29352939

29362940
if (isData)
29372941
pfx = "Data for ";
@@ -2953,12 +2957,39 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
29532957
ahprintf(AH, "\n");
29542958
}
29552959
}
2960+
2961+
/*
2962+
* Zap any line endings embedded in user-supplied fields, to prevent
2963+
* corruption of the dump (which could, in the worst case, present an
2964+
* SQL injection vulnerability if someone were to incautiously load a
2965+
* dump containing objects with maliciously crafted names).
2966+
*/
2967+
sanitized_name = replace_line_endings(te->tag);
2968+
if (te->namespace)
2969+
sanitized_schema = replace_line_endings(te->namespace);
2970+
else
2971+
sanitized_schema = pg_strdup("-");
2972+
if (!ropt->noOwner)
2973+
sanitized_owner = replace_line_endings(te->owner);
2974+
else
2975+
sanitized_owner = pg_strdup("-");
2976+
29562977
ahprintf(AH, "-- %sName: %s; Type: %s; Schema: %s; Owner: %s",
2957-
pfx, te->tag, te->desc,
2958-
te->namespace ? te->namespace : "-",
2959-
ropt->noOwner ? "-" : te->owner);
2978+
pfx, sanitized_name, te->desc, sanitized_schema,
2979+
sanitized_owner);
2980+
2981+
free(sanitized_name);
2982+
free(sanitized_schema);
2983+
free(sanitized_owner);
2984+
29602985
if (te->tablespace && !ropt->noTablespace)
2961-
ahprintf(AH, "; Tablespace: %s", te->tablespace);
2986+
{
2987+
char *sanitized_tablespace;
2988+
2989+
sanitized_tablespace = replace_line_endings(te->tablespace);
2990+
ahprintf(AH, "; Tablespace: %s", sanitized_tablespace);
2991+
free(sanitized_tablespace);
2992+
}
29622993
ahprintf(AH, "\n");
29632994

29642995
if (AH->PrintExtraTocPtr !=NULL)
@@ -3053,6 +3084,27 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
30533084
}
30543085
}
30553086

3087+
/*
3088+
* Sanitize a string to be included in an SQL comment, by replacing any
3089+
* newlines with spaces.
3090+
*/
3091+
static char *
3092+
replace_line_endings(const char *str)
3093+
{
3094+
char *result;
3095+
char *s;
3096+
3097+
result = pg_strdup(str);
3098+
3099+
for (s = result; *s != '\0'; s++)
3100+
{
3101+
if (*s == '\n' || *s == '\r')
3102+
*s = ' ';
3103+
}
3104+
3105+
return result;
3106+
}
3107+
30563108
void
30573109
WriteHead(ArchiveHandle *AH)
30583110
{

0 commit comments

Comments
 (0)