1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-26 12:21:12 +03:00

Back-patch "Only quote libpq connection string values that need quoting."

Back-patch commit 2953cd6d17 and certain
runPgDump() bits of 3dee636e04 to 9.2 and
9.1.  This synchronizes their doConnStrQuoting() implementations with
later releases.  Subsequent security patches will modify that function.

Security: CVE-2016-5424
This commit is contained in:
Noah Misch
2016-08-08 10:07:53 -04:00
parent 2d69f5b12e
commit c761c9fee0

View File

@ -1620,7 +1620,7 @@ dumpDatabases(PGconn *conn)
static int static int
runPgDump(const char *dbname) runPgDump(const char *dbname)
{ {
PQExpBuffer connstr = createPQExpBuffer(); PQExpBuffer connstrbuf = createPQExpBuffer();
PQExpBuffer cmd = createPQExpBuffer(); PQExpBuffer cmd = createPQExpBuffer();
int ret; int ret;
@ -1642,11 +1642,10 @@ runPgDump(const char *dbname)
* database name as is, but if it contains any = characters, it would * database name as is, but if it contains any = characters, it would
* incorrectly treat it as a connection string. * incorrectly treat it as a connection string.
*/ */
appendPQExpBuffer(connstr, "dbname='"); appendPQExpBufferStr(connstrbuf, "dbname=");
doConnStrQuoting(connstr, dbname); doConnStrQuoting(connstrbuf, dbname);
appendPQExpBuffer(connstr, "'");
doShellQuoting(cmd, connstr->data); doShellQuoting(cmd, connstrbuf->data);
appendPQExpBuffer(cmd, "%s", SYSTEMQUOTE); appendPQExpBuffer(cmd, "%s", SYSTEMQUOTE);
@ -1659,7 +1658,7 @@ runPgDump(const char *dbname)
ret = system(cmd->data); ret = system(cmd->data);
destroyPQExpBuffer(cmd); destroyPQExpBuffer(cmd);
destroyPQExpBuffer(connstr); destroyPQExpBuffer(connstrbuf);
return ret; return ret;
} }
@ -1891,15 +1890,40 @@ dumpTimestamp(char *msg)
static void static void
doConnStrQuoting(PQExpBuffer buf, const char *str) doConnStrQuoting(PQExpBuffer buf, const char *str)
{ {
while (*str) const char *s;
{ bool needquotes;
/* ' and \ must be escaped by to \' and \\ */
if (*str == '\'' || *str == '\\')
appendPQExpBufferChar(buf, '\\');
appendPQExpBufferChar(buf, *str); /*
str++; * If the string consists entirely of plain ASCII characters, no need to
* quote it. This is quite conservative, but better safe than sorry.
*/
needquotes = false;
for (s = str; *s; s++)
{
if (!((*s >= 'a' && *s <= 'z') || (*s >= 'A' && *s <= 'Z') ||
(*s >= '0' && *s <= '9') || *s == '_' || *s == '.'))
{
needquotes = true;
break;
}
} }
if (needquotes)
{
appendPQExpBufferChar(buf, '\'');
while (*str)
{
/* ' and \ must be escaped by to \' and \\ */
if (*str == '\'' || *str == '\\')
appendPQExpBufferChar(buf, '\\');
appendPQExpBufferChar(buf, *str);
str++;
}
appendPQExpBufferChar(buf, '\'');
}
else
appendPQExpBufferStr(buf, str);
} }
/* /*