aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2020-12-08 17:50:54 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2020-12-08 17:50:54 -0500
commit1f229f4fdcf88d8fe7cb0b7442a4894cd4d1c47c (patch)
tree56efdf11448b3432e5759a69dcc5fe65bd1a1d31
parent5303706b320864332abd99b666a466863ffece22 (diff)
downloadpostgresql-1f229f4fdcf88d8fe7cb0b7442a4894cd4d1c47c.tar.gz
postgresql-1f229f4fdcf88d8fe7cb0b7442a4894cd4d1c47c.zip
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
-rw-r--r--src/backend/optimizer/util/clauses.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index b68c22ba152..28b6a2c0a43 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -1602,7 +1602,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:
@@ -1643,6 +1642,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:
{
/*