Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 12fd81c

Browse filesBrowse files
committed
Ignore attempts to \gset into specially treated variables.
If an interactive psql session used \gset when querying a compromised server, the attacker could execute arbitrary code as the operating system account running psql. Using a prefix not found among specially treated variables, e.g. every lowercase string, precluded the attack. Fix by issuing a warning and setting no variable for the column in question. Users wanting the old behavior can use a prefix and then a meta-command like "\set HISTSIZE :prefix_HISTSIZE". Back-patch to 9.5 (all supported versions). Reviewed by Robert Haas. Reported by Nick Cleaton. Security: CVE-2020-25696
1 parent ff3de4c commit 12fd81c
Copy full SHA for 12fd81c

File tree

Expand file treeCollapse file tree

5 files changed

+33
-0
lines changed
Filter options
Expand file treeCollapse file tree

5 files changed

+33
-0
lines changed

‎src/bin/psql/common.c

Copy file name to clipboardExpand all lines: src/bin/psql/common.c
+7Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,13 @@ StoreQueryTuple(const PGresult *result)
795795
/* concatenate prefix and column name */
796796
varname = psprintf("%s%s", pset.gset_prefix, colname);
797797

798+
if (VariableHasHook(pset.vars, varname))
799+
{
800+
psql_error("attempt to \\gset into specially treated variable \"%s\" ignored\n",
801+
varname);
802+
continue;
803+
}
804+
798805
if (!PQgetisnull(result, 0, i))
799806
value = PQgetvalue(result, 0, i);
800807
else

‎src/bin/psql/variables.c

Copy file name to clipboardExpand all lines: src/bin/psql/variables.c
+18Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,24 @@ SetVariableAssignHook(VariableSpace space, const char *name, VariableAssignHook
264264
return true;
265265
}
266266

267+
/*
268+
* Return true iff the named variable has an assign hook function.
269+
*/
270+
bool
271+
VariableHasHook(VariableSpace space, const char *name)
272+
{
273+
struct _variable *current;
274+
275+
Assert(space);
276+
Assert(name);
277+
278+
for (current = space->next; current; current = current->next)
279+
if (strcmp(current->name, name) == 0)
280+
return current->assign_hook != NULL;
281+
282+
return false;
283+
}
284+
267285
bool
268286
SetVariableBool(VariableSpace space, const char *name)
269287
{

‎src/bin/psql/variables.h

Copy file name to clipboardExpand all lines: src/bin/psql/variables.h
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ void PrintVariables(VariableSpace space);
5050

5151
bool SetVariable(VariableSpace space, const char *name, const char *value);
5252
bool SetVariableAssignHook(VariableSpace space, const char *name, VariableAssignHook hook);
53+
bool VariableHasHook(VariableSpace space, const char *name);
5354
bool SetVariableBool(VariableSpace space, const char *name);
5455
bool DeleteVariable(VariableSpace space, const char *name);
5556

‎src/test/regress/expected/psql.out

Copy file name to clipboardExpand all lines: src/test/regress/expected/psql.out
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ select 10 as test01, 20 as test02, 'Hello' as test03 \gset pref01_
1010
select 10 as "bad name"
1111
\gset
1212
could not set variable "bad name"
13+
select 'terse' as "OSITY", 'ok' as _foo \gset VERB
14+
attempt to \gset into specially treated variable "VERBOSITY" ignored
15+
\echo :VERB_foo :VERBOSITY
16+
ok default
1317
-- multiple backslash commands in one line
1418
select 1 as x, 2 as y \gset pref01_ \\ \echo :pref01_x
1519
1

‎src/test/regress/sql/psql.sql

Copy file name to clipboardExpand all lines: src/test/regress/sql/psql.sql
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ select 10 as test01, 20 as test02, 'Hello' as test03 \gset pref01_
1313
select 10 as "bad name"
1414
\gset
1515

16+
select 'terse' as "OSITY", 'ok' as _foo \gset VERB
17+
\echo :VERB_foo :VERBOSITY
18+
1619
-- multiple backslash commands in one line
1720
select 1 as x, 2 as y \gset pref01_ \\ \echo :pref01_x
1821
select 3 as x, 4 as y \gset pref01_ \echo :pref01_x \echo :pref01_y

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.