aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeModifyTable.c
diff options
context:
space:
mode:
authorDean Rasheed <dean.a.rasheed@gmail.com>2023-08-07 09:24:27 +0100
committerDean Rasheed <dean.a.rasheed@gmail.com>2023-08-07 09:24:27 +0100
commitcb2ae5741f2458a474ed3c31458d242e678ff229 (patch)
treeb3d6404d2f2555c140bff2ff2c19497016a68eb1 /src/backend/executor/nodeModifyTable.c
parentaccf4f84887eb8b53978a0dbf9cb5656e1779fcb (diff)
downloadpostgresql-cb2ae5741f2458a474ed3c31458d242e678ff229.tar.gz
postgresql-cb2ae5741f2458a474ed3c31458d242e678ff229.zip
Fix RLS policy usage in MERGE.
If MERGE executes an UPDATE action on a table with row-level security, the code incorrectly applied the WITH CHECK clauses from the target table's INSERT policies to new rows, instead of the clauses from the table's UPDATE policies. In addition, it failed to check new rows against the target table's SELECT policies, if SELECT permissions were required (likely to always be the case). In addition, if MERGE executes a DO NOTHING action for matched rows, the code incorrectly applied the USING clauses from the target table's DELETE policies to existing target tuples. These policies were applied as checks that would throw an error, if they did not pass. Fix this, so that a MERGE UPDATE action applies the same RLS policies as a plain UPDATE query with a WHERE clause, and a DO NOTHING action does not apply any RLS checks (other than adding clauses from SELECT policies to the join). Back-patch to v15, where MERGE was introduced. Dean Rasheed, reviewed by Stephen Frost. Security: CVE-2023-39418
Diffstat (limited to 'src/backend/executor/nodeModifyTable.c')
-rw-r--r--src/backend/executor/nodeModifyTable.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c
index ca62cb707a4..daf48dc0f0e 100644
--- a/src/backend/executor/nodeModifyTable.c
+++ b/src/backend/executor/nodeModifyTable.c
@@ -2842,13 +2842,14 @@ lmerge_matched:;
* UPDATE/DELETE RLS policies. If those checks fail, we throw an
* error.
*
- * The WITH CHECK quals are applied in ExecUpdate() and hence we need
- * not do anything special to handle them.
+ * The WITH CHECK quals for UPDATE RLS policies are applied in
+ * ExecUpdateAct() and hence we need not do anything special to handle
+ * them.
*
* NOTE: We must do this after WHEN quals are evaluated, so that we
* check policies only when they matter.
*/
- if (resultRelInfo->ri_WithCheckOptions)
+ if (resultRelInfo->ri_WithCheckOptions && commandType != CMD_NOTHING)
{
ExecWithCheckOptions(commandType == CMD_UPDATE ?
WCO_RLS_MERGE_UPDATE_CHECK : WCO_RLS_MERGE_DELETE_CHECK,