From 1f23d1cd21ed46dba882729bedd9c40b71995989 Mon Sep 17 00:00:00 2001 From: Dean Rasheed Date: Mon, 6 Nov 2017 09:16:24 +0000 Subject: Always require SELECT permission for ON CONFLICT DO UPDATE. The update path of an INSERT ... ON CONFLICT DO UPDATE requires SELECT permission on the columns of the arbiter index, but it failed to check for that in the case of an arbiter specified by constraint name. In addition, for a table with row level security enabled, it failed to check updated rows against the table's SELECT policies when the update path was taken (regardless of how the arbiter index was specified). Backpatch to 9.5 where ON CONFLICT DO UPDATE and RLS were introduced. Security: CVE-2017-15099 --- src/backend/rewrite/rowsecurity.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'src/backend/rewrite/rowsecurity.c') diff --git a/src/backend/rewrite/rowsecurity.c b/src/backend/rewrite/rowsecurity.c index 6b34c596f39..ad5e2d870f7 100644 --- a/src/backend/rewrite/rowsecurity.c +++ b/src/backend/rewrite/rowsecurity.c @@ -309,6 +309,8 @@ get_row_security_policies(Query *root, RangeTblEntry *rte, int rt_index, { List *conflict_permissive_policies; List *conflict_restrictive_policies; + List *conflict_select_permissive_policies = NIL; + List *conflict_select_restrictive_policies = NIL; /* Get the policies that apply to the auxiliary UPDATE */ get_policies_for_relation(rel, CMD_UPDATE, user_id, @@ -338,9 +340,6 @@ get_row_security_policies(Query *root, RangeTblEntry *rte, int rt_index, */ if (rte->requiredPerms & ACL_SELECT) { - List *conflict_select_permissive_policies = NIL; - List *conflict_select_restrictive_policies = NIL; - get_policies_for_relation(rel, CMD_SELECT, user_id, &conflict_select_permissive_policies, &conflict_select_restrictive_policies); @@ -361,6 +360,21 @@ get_row_security_policies(Query *root, RangeTblEntry *rte, int rt_index, withCheckOptions, hasSubLinks, false); + + /* + * Add ALL/SELECT policies as WCO_RLS_UPDATE_CHECK WCOs, to ensure + * that the final updated row is visible when taking the UPDATE + * path of an INSERT .. ON CONFLICT DO UPDATE, if SELECT rights + * are required for this relation. + */ + if (rte->requiredPerms & ACL_SELECT) + add_with_check_options(rel, rt_index, + WCO_RLS_UPDATE_CHECK, + conflict_select_permissive_policies, + conflict_select_restrictive_policies, + withCheckOptions, + hasSubLinks, + true); } } -- cgit v1.2.3