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

Commit 2d2f63d

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 e6fcb03 commit 2d2f63d

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
@@ -97,6 +97,7 @@ static ArchiveHandle *_allocAH(const char *FileSpec, const ArchiveFormat fmt,
9797
static void _getObjectDescription(PQExpBuffer buf, TocEntry *te,
9898
ArchiveHandle *AH);
9999
static void _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isData, bool acl_pass);
100+
static char *replace_line_endings(const char *str);
100101

101102

102103
static void _doSetFixedOutputState(ArchiveHandle *AH);
@@ -2939,6 +2940,9 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
29392940
if (!AH->noTocComments)
29402941
{
29412942
const char *pfx;
2943+
char *sanitized_name;
2944+
char *sanitized_schema;
2945+
char *sanitized_owner;
29422946

29432947
if (isData)
29442948
pfx = "Data for ";
@@ -2960,12 +2964,39 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
29602964
ahprintf(AH, "\n");
29612965
}
29622966
}
2967+
2968+
/*
2969+
* Zap any line endings embedded in user-supplied fields, to prevent
2970+
* corruption of the dump (which could, in the worst case, present an
2971+
* SQL injection vulnerability if someone were to incautiously load a
2972+
* dump containing objects with maliciously crafted names).
2973+
*/
2974+
sanitized_name = replace_line_endings(te->tag);
2975+
if (te->namespace)
2976+
sanitized_schema = replace_line_endings(te->namespace);
2977+
else
2978+
sanitized_schema = strdup("-");
2979+
if (!ropt->noOwner)
2980+
sanitized_owner = replace_line_endings(te->owner);
2981+
else
2982+
sanitized_owner = strdup("-");
2983+
29632984
ahprintf(AH, "-- %sName: %s; Type: %s; Schema: %s; Owner: %s",
2964-
pfx, te->tag, te->desc,
2965-
te->namespace ? te->namespace : "-",
2966-
ropt->noOwner ? "-" : te->owner);
2985+
pfx, sanitized_name, te->desc, sanitized_schema,
2986+
sanitized_owner);
2987+
2988+
free(sanitized_name);
2989+
free(sanitized_schema);
2990+
free(sanitized_owner);
2991+
29672992
if (te->tablespace && !ropt->noTablespace)
2968-
ahprintf(AH, "; Tablespace: %s", te->tablespace);
2993+
{
2994+
char *sanitized_tablespace;
2995+
2996+
sanitized_tablespace = replace_line_endings(te->tablespace);
2997+
ahprintf(AH, "; Tablespace: %s", sanitized_tablespace);
2998+
free(sanitized_tablespace);
2999+
}
29693000
ahprintf(AH, "\n");
29703001

29713002
if (AH->PrintExtraTocPtr !=NULL)
@@ -3060,6 +3091,27 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
30603091
}
30613092
}
30623093

3094+
/*
3095+
* Sanitize a string to be included in an SQL comment, by replacing any
3096+
* newlines with spaces.
3097+
*/
3098+
static char *
3099+
replace_line_endings(const char *str)
3100+
{
3101+
char *result;
3102+
char *s;
3103+
3104+
result = strdup(str);
3105+
3106+
for (s = result; *s != '\0'; s++)
3107+
{
3108+
if (*s == '\n' || *s == '\r')
3109+
*s = ' ';
3110+
}
3111+
3112+
return result;
3113+
}
3114+
30633115
void
30643116
WriteHead(ArchiveHandle *AH)
30653117
{

0 commit comments

Comments
 (0)