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
This commit is contained in:
parent
4ee9db0cd9
commit
d975e16605
@ -83,6 +83,7 @@ static ArchiveHandle *_allocAH(const char *FileSpec, const ArchiveFormat fmt,
|
|||||||
static void _getObjectDescription(PQExpBuffer buf, TocEntry *te,
|
static void _getObjectDescription(PQExpBuffer buf, TocEntry *te,
|
||||||
ArchiveHandle *AH);
|
ArchiveHandle *AH);
|
||||||
static void _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isData, bool acl_pass);
|
static void _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isData, bool acl_pass);
|
||||||
|
static char *replace_line_endings(const char *str);
|
||||||
|
|
||||||
|
|
||||||
static void _doSetFixedOutputState(ArchiveHandle *AH);
|
static void _doSetFixedOutputState(ArchiveHandle *AH);
|
||||||
@ -2803,6 +2804,9 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
|
|||||||
if (!AH->noTocComments)
|
if (!AH->noTocComments)
|
||||||
{
|
{
|
||||||
const char *pfx;
|
const char *pfx;
|
||||||
|
char *sanitized_name;
|
||||||
|
char *sanitized_schema;
|
||||||
|
char *sanitized_owner;
|
||||||
|
|
||||||
if (isData)
|
if (isData)
|
||||||
pfx = "Data for ";
|
pfx = "Data for ";
|
||||||
@ -2824,12 +2828,39 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
|
|||||||
ahprintf(AH, "\n");
|
ahprintf(AH, "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Zap any line endings embedded in user-supplied fields, 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).
|
||||||
|
*/
|
||||||
|
sanitized_name = replace_line_endings(te->tag);
|
||||||
|
if (te->namespace)
|
||||||
|
sanitized_schema = replace_line_endings(te->namespace);
|
||||||
|
else
|
||||||
|
sanitized_schema = strdup("-");
|
||||||
|
if (!ropt->noOwner)
|
||||||
|
sanitized_owner = replace_line_endings(te->owner);
|
||||||
|
else
|
||||||
|
sanitized_owner = strdup("-");
|
||||||
|
|
||||||
ahprintf(AH, "-- %sName: %s; Type: %s; Schema: %s; Owner: %s",
|
ahprintf(AH, "-- %sName: %s; Type: %s; Schema: %s; Owner: %s",
|
||||||
pfx, te->tag, te->desc,
|
pfx, sanitized_name, te->desc, sanitized_schema,
|
||||||
te->namespace ? te->namespace : "-",
|
sanitized_owner);
|
||||||
ropt->noOwner ? "-" : te->owner);
|
|
||||||
|
free(sanitized_name);
|
||||||
|
free(sanitized_schema);
|
||||||
|
free(sanitized_owner);
|
||||||
|
|
||||||
if (te->tablespace && !ropt->noTablespace)
|
if (te->tablespace && !ropt->noTablespace)
|
||||||
ahprintf(AH, "; Tablespace: %s", te->tablespace);
|
{
|
||||||
|
char *sanitized_tablespace;
|
||||||
|
|
||||||
|
sanitized_tablespace = replace_line_endings(te->tablespace);
|
||||||
|
ahprintf(AH, "; Tablespace: %s", sanitized_tablespace);
|
||||||
|
free(sanitized_tablespace);
|
||||||
|
}
|
||||||
ahprintf(AH, "\n");
|
ahprintf(AH, "\n");
|
||||||
|
|
||||||
if (AH->PrintExtraTocPtr !=NULL)
|
if (AH->PrintExtraTocPtr !=NULL)
|
||||||
@ -2921,6 +2952,27 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sanitize a string to be included in an SQL comment, by replacing any
|
||||||
|
* newlines with spaces.
|
||||||
|
*/
|
||||||
|
static char *
|
||||||
|
replace_line_endings(const char *str)
|
||||||
|
{
|
||||||
|
char *result;
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
result = strdup(str);
|
||||||
|
|
||||||
|
for (s = result; *s != '\0'; s++)
|
||||||
|
{
|
||||||
|
if (*s == '\n' || *s == '\r')
|
||||||
|
*s = ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
WriteHead(ArchiveHandle *AH)
|
WriteHead(ArchiveHandle *AH)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user