Skip to content

Commit 098fb00

Browse 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 0c3185e commit 098fb00

File tree

5 files changed

+41
-0
lines changed

5 files changed

+41
-0
lines changed

src/bin/psql/common.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,13 @@ StoreQueryTuple(const PGresult *result)
786786
/* concatenate prefix and column name */
787787
varname = psprintf("%s%s", pset.gset_prefix, colname);
788788

789+
if (VariableHasHook(pset.vars, varname))
790+
{
791+
pg_log_warning("attempt to \\gset into specially treated variable \"%s\" ignored",
792+
varname);
793+
continue;
794+
}
795+
789796
if (!PQgetisnull(result, 0, i))
790797
value = PQgetvalue(result, 0, i);
791798
else

src/bin/psql/variables.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,32 @@ SetVariableHooks(VariableSpace space, const char *name,
360360
(void) (*ahook) (current->value);
361361
}
362362

363+
/*
364+
* Return true iff the named variable has substitute and/or assign hook
365+
* functions.
366+
*/
367+
bool
368+
VariableHasHook(VariableSpace space, const char *name)
369+
{
370+
struct _variable *current;
371+
372+
Assert(space);
373+
Assert(name);
374+
375+
for (current = space->next; current; current = current->next)
376+
{
377+
int cmp = strcmp(current->name, name);
378+
379+
if (cmp == 0)
380+
return (current->substitute_hook != NULL ||
381+
current->assign_hook != NULL);
382+
if (cmp > 0)
383+
break; /* it's not there */
384+
}
385+
386+
return false;
387+
}
388+
363389
/*
364390
* Convenience function to set a variable's value to "on".
365391
*/

src/bin/psql/variables.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ bool DeleteVariable(VariableSpace space, const char *name);
9090
void SetVariableHooks(VariableSpace space, const char *name,
9191
VariableSubstituteHook shook,
9292
VariableAssignHook ahook);
93+
bool VariableHasHook(VariableSpace space, const char *name);
9394

9495
void PsqlVarEnumError(const char *name, const char *value, const char *suggestions);
9596

src/test/regress/expected/psql.out

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ select 10 as test01, 20 as test02, 'Hello' as test03 \gset pref01_
106106
select 10 as "bad name"
107107
\gset
108108
invalid variable name: "bad name"
109+
select 97 as "EOF", 'ok' as _foo \gset IGNORE
110+
attempt to \gset into specially treated variable "IGNOREEOF" ignored
111+
\echo :IGNORE_foo :IGNOREEOF
112+
ok 0
109113
-- multiple backslash commands in one line
110114
select 1 as x, 2 as y \gset pref01_ \\ \echo :pref01_x
111115
1

src/test/regress/sql/psql.sql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ select 10 as test01, 20 as test02, 'Hello' as test03 \gset pref01_
5555
select 10 as "bad name"
5656
\gset
5757

58+
select 97 as "EOF", 'ok' as _foo \gset IGNORE
59+
\echo :IGNORE_foo :IGNOREEOF
60+
5861
-- multiple backslash commands in one line
5962
select 1 as x, 2 as y \gset pref01_ \\ \echo :pref01_x
6063
select 3 as x, 4 as y \gset pref01_ \echo :pref01_x \echo :pref01_y

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy