]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Handle RLS dependencies in inlined set-returning functions properly.
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 8 May 2023 14:12:45 +0000 (10:12 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 8 May 2023 14:12:45 +0000 (10:12 -0400)
If an SRF in the FROM clause references a table having row-level
security policies, and we inline that SRF into the calling query,
we neglected to mark the plan as potentially dependent on which
role is executing it.  This could lead to later executions in the
same session returning or hiding rows that should have been hidden
or returned instead.

Our thanks to Wolfgang Walther for reporting this problem.

Stephen Frost and Tom Lane

Security: CVE-2023-2455

src/backend/optimizer/util/clauses.c
src/test/regress/expected/rowsecurity.out
src/test/regress/sql/rowsecurity.sql

index edb56ab3a47b711824a524280b08fc59c00e21e0..d77054ad42af6f0675b37b8cf3503d8271cc77cc 100644 (file)
@@ -5342,6 +5342,13 @@ inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte)
         */
        record_plan_function_dependency(root, func_oid);
 
+       /*
+        * We must also notice if the inserted query adds a dependency on the
+        * calling role due to RLS quals.
+        */
+       if (querytree->hasRowSecurity)
+               root->glob->dependsOnRole = true;
+
        return querytree;
 
        /* Here if func is not inlinable: release temp memory and return NULL */
index 194d960b8903f4c0374ce3bc87380dcfc6642872..81b4fad12e91003414c22807c196253fc1ef9be9 100644 (file)
@@ -4039,6 +4039,33 @@ SELECT * FROM rls_tbl;
 
 DROP TABLE rls_tbl;
 RESET SESSION AUTHORIZATION;
+-- CVE-2023-2455: inlining an SRF may introduce an RLS dependency
+create table rls_t (c text);
+insert into rls_t values ('invisible to bob');
+alter table rls_t enable row level security;
+grant select on rls_t to regress_rls_alice, regress_rls_bob;
+create policy p1 on rls_t for select to regress_rls_alice using (true);
+create policy p2 on rls_t for select to regress_rls_bob using (false);
+create function rls_f () returns setof rls_t
+  stable language sql
+  as $$ select * from rls_t $$;
+prepare q as select current_user, * from rls_f();
+set role regress_rls_alice;
+execute q;
+   current_user    |        c         
+-------------------+------------------
+ regress_rls_alice | invisible to bob
+(1 row)
+
+set role regress_rls_bob;
+execute q;
+ current_user | c 
+--------------+---
+(0 rows)
+
+RESET ROLE;
+DROP FUNCTION rls_f();
+DROP TABLE rls_t;
 --
 -- Clean up objects
 --
index 5c01d6f416815ad4c3389bf708944369501e70eb..caa464f5152708eb80f2b6f9fc3f12e309a7f503 100644 (file)
@@ -1876,6 +1876,26 @@ SELECT * FROM rls_tbl;
 DROP TABLE rls_tbl;
 RESET SESSION AUTHORIZATION;
 
+-- CVE-2023-2455: inlining an SRF may introduce an RLS dependency
+create table rls_t (c text);
+insert into rls_t values ('invisible to bob');
+alter table rls_t enable row level security;
+grant select on rls_t to regress_rls_alice, regress_rls_bob;
+create policy p1 on rls_t for select to regress_rls_alice using (true);
+create policy p2 on rls_t for select to regress_rls_bob using (false);
+create function rls_f () returns setof rls_t
+  stable language sql
+  as $$ select * from rls_t $$;
+prepare q as select current_user, * from rls_f();
+set role regress_rls_alice;
+execute q;
+set role regress_rls_bob;
+execute q;
+
+RESET ROLE;
+DROP FUNCTION rls_f();
+DROP TABLE rls_t;
+
 --
 -- Clean up objects
 --