10000 Convert newlines to spaces in names written in pg_dump comments. · jcsston/postgres@02f013e · GitHub
[go: up one dir, main page]

Skip to content

Commit 02f013e

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 850d341 commit 02f013e

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
@@ -89,6 +89,7 @@ static ArchiveHandle *_allocAH(const char *FileSpec, const ArchiveFormat fmt,
8989
static void _getObjectDescription(PQExpBuffer buf, TocEntry *te,
9090
ArchiveHandle *AH);
9191
static void _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isData, bool acl_pass);
92+
static char *replace_line_endings(const char *str);
9293

9394

9495
static void _doSetFixedOutputState(ArchiveHandle *AH);
@@ -2876,6 +2877,9 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
28762877
if (!AH->noTocComments)
28772878
{
28782879
const char *pfx;
2880+
char *sanitized_name;
2881+
char *sanitized_schema;
2882+
char *sanitized_owner;
28792883

28802884
if (isData)
28812885
pfx = "Data for ";
@@ -2897,12 +2901,39 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
28972901
ahprintf(AH, "\n");
28982902
}
28992903
}
2904+
2905+
/*
2906+
* Zap any line endings embedded in user-supplied fields, to prevent
2907+
* corruption of the dump (which could, in the worst case, present an
2908+
* SQL injection vulnerability if someone were to incautiously load a
2909+
* dump containing objects with maliciously crafted names).
2910+
*/
2911+
sanitized_name = replace_line_endings(te->tag);
2912+
if (te->namespace)
2913+
sanitized_schema = replace_line_endings(te->namespace);
2914+
else
2915+
sanitized_schema = strdup("-");
2916+
if (!ropt->noOwner)
2917+
sanitized_owner = replace_line_endings(te->owner);
2918+
else
2919+
sanitized_owner = strdup("-");
2920+
29002921
ahprintf(AH, "-- %sName: %s; Type: %s; Schema: %s; Owner: %s",
2901-
pfx, te->tag, te->desc,
2902-
te->namespace ? te->namespace : "-",
2903-
ropt->noOwner ? "-" : te->owner);
2922+
pfx, sanitized_name, te->desc, sanitized_schema,
2923+
sanitized_owner);
2924+
2925+
free(sanitized_name);
2926+
free(sanitized_schema);
2927+
free(sanitized_owner);
2928+
29042929
if (te->tablespace && !ropt->noTablespace)
2905-
ahprintf(AH, "; Tablespace: %s", te->tablespace);
2930+
{
2931+
char *sanitized_tablespace;
2932+
2933+
sanitized_tablespace = replace_line_endings(te->tablespace);
2934+
ahprintf(AH, "; Tablespace: %s", sanitized_tablespace);
2935+
free(sanitized_tablespace);
2936+
}
29062937
ahprintf(AH, "\n");
29072938

29082939
if (AH->PrintExtraTocPtr !=NULL)
@@ -2995,6 +3026,27 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
29953026
}
29963027
}
29973028

3029+
/*
3030+
* Sanitize a string to be included in an SQL comment, by replacing any
3031+
* newlines with spaces.
3032+
*/
3033+
static char *
3034+
replace_line_endings(const char *str)
3035+
{
3036+
char *result;
3037+
char *s;
3038+
3039+
result = strdup(str);
3040+
3041+
for (s = result; *s != '\0'; s++)
3042+
{
3043+
if (*s == '\n' || *s == '\r')
3044+
*s = ' ';
3045+
}
3046+
3047+
return result;
3048+
}
3049+
29983050
void
29993051
WriteHead(ArchiveHandle *AH)
30003052
{

0 commit comments

Comments
 (0)
0