diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2020-12-08 17:50:54 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2020-12-08 17:50:54 -0500 |
commit | 17c77c8c90f7c566a8f42e0809e425072d8f26b7 (patch) | |
tree | f069ea1c097e6fae2f26f6e664f9ba82b65d1d73 /src | |
parent | 2bf5d1a74a33ed45939ed4c16054aee51ab65540 (diff) |
Teach contain_leaked_vars that assignment SubscriptingRefs are leaky.
array_get_element and array_get_slice qualify as leakproof, since
they will silently return NULL for bogus subscripts. But
array_set_element and array_set_slice throw errors for such cases,
making them clearly not leakproof. contain_leaked_vars was evidently
written with only the former case in mind, as it gave the wrong answer
for assignment SubscriptingRefs (nee ArrayRefs).
This would be a live security bug, were it not that assignment
SubscriptingRefs can only occur in INSERT and UPDATE target lists,
while we only care about leakproofness for qual expressions; so the
wrong answer can't occur in practice. Still, that's a rather shaky
answer for a security-related question; and maybe in future somebody
will want to ask about leakproofness of a tlist. So it seems wise to
fix and even back-patch this correction.
(We would need some change here anyway for the upcoming
generic-subscripting patch, since extensions might make different
tradeoffs about whether to throw errors. Commit 558d77f20 attempted
to lay groundwork for that by asking check_functions_in_node whether a
SubscriptingRef contains leaky functions; but that idea fails now that
the implementation methods of a SubscriptingRef are not SQL-visible
functions that could be marked leakproof or not.)
Back-patch to 9.6. While 9.5 has the same issue, the code's a bit
different. It seems quite unlikely that we'd introduce any actual bug
in the short time 9.5 has left to live, so the work/risk/reward balance
isn't attractive for changing 9.5.
Discussion: https://postgr.es/m/3143742.1607368115@sss.pgh.pa.us
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/optimizer/util/clauses.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index 02866f363d6..17844a3a480 100644 --- a/src/backend/optimizer/util/clauses.c +++ b/src/backend/optimizer/util/clauses.c @@ -1505,7 +1505,6 @@ contain_leaked_vars_walker(Node *node, void *context) case T_Var: case T_Const: case T_Param: - case T_ArrayRef: case T_ArrayExpr: case T_FieldSelect: case T_FieldStore: @@ -1544,6 +1543,23 @@ contain_leaked_vars_walker(Node *node, void *context) return true; break; + case T_ArrayRef: + { + ArrayRef *aref = (ArrayRef *) node; + + /* + * array assignment is leaky, but subscripted fetches + * are not + */ + if (aref->refassgnexpr != NULL) + { + /* Node is leaky, so reject if it contains Vars */ + if (contain_var_clause(node)) + return true; + } + } + break; + case T_RowCompareExpr: { /* |