mirror of
https://github.com/postgres/postgres.git
synced 2026-10-23 13:29:09 +03:00
Fix RLS checks for FOR PORTION OF leftover rows
UPDATE/DELETE FOR PORTION OF may insert leftover rows to preserve the parts of the old row that are outside the target range. Those inserts go through ExecInsert(), which checks RLS policies using WCO_RLS_INSERT_CHECK. However, the rewriter only added RLS WITH CHECK options for the original statement command. For UPDATE, that meant only WCO_RLS_UPDATE_CHECK options were available, so ExecInsert() skipped them. For DELETE, no RLS WITH CHECK options were added at all. As a result, leftover rows could be inserted even when they violated INSERT RLS policies. Fix this by adding INSERT RLS WITH CHECK options for UPDATE/DELETE FOR PORTION OF target relations. Also add regression coverage for both UPDATE and DELETE, including cases where allowed leftovers still succeed and disallowed leftovers are rejected. Author: Chao Li <lic@highgo.com> Co-authored-by: Paul A Jungwirth <pj@illuminatedcomputing.com> Reviewed-by: Paul A Jungwirth <pj@illuminatedcomputing.com> Reviewed-by: Ayush Tiwari <ayushtiwari.slg01@gmail.com> Reviewed-by: Dean Rasheed <dean.a.rasheed@gmail.com> Discussion: https://www.postgresql.org/message-id/flat/6C34A987-AC50-4477-BD71-2D4AFEE1A589%40gmail.com Discussion: https://www.postgresql.org/message-id/flat/CAJTYsWWdeBkoH5g8D-k9LDw9ciqsMxb21EJSiFXAzP4J%3DXyxOQ%40mail.gmail.com
This commit is contained in:
@@ -530,6 +530,26 @@ CREATE POLICY <replaceable class="parameter">name</replaceable> ON <replaceable
|
||||
<entry>Check new row</entry>
|
||||
<entry>—</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><command>UPDATE ... FOR PORTION OF</command></entry>
|
||||
<entry>
|
||||
Filter existing row & check new row
|
||||
</entry>
|
||||
<entry>
|
||||
Check leftover rows <footnote id="rls-fpo-leftover">
|
||||
<para>
|
||||
<literal>FOR PORTION OF</literal> re-inserts the portions of the
|
||||
affected row that fall outside the targeted range, to preserve them.
|
||||
These leftover rows are checked against the <command>INSERT</command>
|
||||
policy's <literal>WITH CHECK</literal> expression, even though no
|
||||
<literal>INSERT</literal> privilege is required to store them.
|
||||
</para>
|
||||
</footnote>
|
||||
</entry>
|
||||
<entry>Filter existing row</entry>
|
||||
<entry>Check new row</entry>
|
||||
<entry>—</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><command>DELETE</command></entry>
|
||||
<entry>
|
||||
@@ -540,6 +560,18 @@ CREATE POLICY <replaceable class="parameter">name</replaceable> ON <replaceable
|
||||
<entry>—</entry>
|
||||
<entry>Filter existing row</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><command>DELETE ... FOR PORTION OF</command></entry>
|
||||
<entry>
|
||||
Filter existing row
|
||||
</entry>
|
||||
<entry>
|
||||
Check leftover rows <footnoteref linkend="rls-fpo-leftover"/>
|
||||
</entry>
|
||||
<entry>—</entry>
|
||||
<entry>—</entry>
|
||||
<entry>Filter existing row</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><command>INSERT ... ON CONFLICT</command></entry>
|
||||
<entry>
|
||||
|
||||
@@ -97,7 +97,8 @@ DELETE FROM [ ONLY ] <replaceable class="parameter">table_name</replaceable> [ *
|
||||
When <literal>FOR PORTION OF</literal> is used, the secondary inserts do
|
||||
not require <literal>INSERT</literal> privilege on the table. (This is
|
||||
because conceptually no new information is being added; the inserted rows
|
||||
only preserve existing data about the untargeted time period.)
|
||||
only preserve existing data about the untargeted time period.) Row-level
|
||||
security INSERT policies are still checked for these leftover inserts.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
|
||||
@@ -101,7 +101,8 @@ UPDATE [ ONLY ] <replaceable class="parameter">table_name</replaceable> [ * ]
|
||||
When <literal>FOR PORTION OF</literal> is used, the secondary inserts do
|
||||
not require <literal>INSERT</literal> privilege on the table. (This is
|
||||
because conceptually no new information is being added; the inserted rows
|
||||
only preserve existing data about the untargeted time period.)
|
||||
only preserve existing data about the untargeted time period.) Row-level
|
||||
security INSERT policies are still checked for these leftover inserts.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user