Thread

  1. Enforce INSERT RLS checks for FOR PORTION OF leftovers?

    Ayush Tiwari <ayushtiwari.slg01@gmail.com> — 2026-05-01T18:53:04Z

    Hi,
    
    I found what looks like a  discrepancy where UPDATE/DELETE FOR
    PORTION OF commands bypass INSERT RLS WITH CHECK
    policies when inserting temporal leftover rows. Not sure if it's already
    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