flagged (could not find it in DL).
While it is intentional that ExecForPortionOfLeftovers() skips INSERT ACL
permission checks, the leftover rows are newly inserted rows and should
still satisfy INSERT/ALL RLS policies unless I'm missing something.
Currently, the rewrite phase only
attaches UPDATE/DELETE RLS checks for the target relation, leaving
ExecInsert() without a WCO_RLS_INSERT_CHECK to enforce for the
leftovers.
Maybe we should address this in rowsecurity.c by fetching CMD_INSERT
policies and adding them as WCO_RLS_INSERT_CHECK entries for queries
with a FOR PORTION OF clause?
Something like this:
--- a/src/backend/rewrite/rowsecurity.c
+++ b/src/backend/rewrite/rowsecurity.c
@@ -393,6 +393,34 @@ get_row_security_policies(Query *root, RangeTblEntry *rte, int rt_index,
}
}
+ /*
+ * UPDATE/DELETE FOR PORTION OF commands insert temporal leftovers via
+ * ExecInsert(). Those internal inserts intentionally skip INSERT ACL
+ * permission checks, but they still create new rows and must satisfy any
+ * INSERT/ALL RLS WITH CHECK policies.
+ */
+ if ((commandType == CMD_UPDATE || commandType == CMD_DELETE) &&
+ root->forPortionOf != NULL)
+ {
+ List *insert_permissive_policies;
+ List *insert_restrictive_policies;
+
+ /* This should be the target relation */
+ Assert(rt_index == root->resultRelation);
+
+ get_policies_for_relation(rel, CMD_INSERT, user_id,
+ &insert_permissive_policies,
+ &insert_restrictive_policies);
+
+ add_with_check_options(rel, rt_index,
+ WCO_RLS_INSERT_CHECK,
+ insert_permissive_policies,
+ insert_restrictive_policies,
+ withCheckOptions,
+ hasSubLinks,
+ false);
+ }
+
Thoughts?
Regards,
Ayush