Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 7f1f72c

Browse files
committed
Fix usage of whole-row variables in WCO and RLS policy expressions.
Since WITH CHECK OPTION was introduced, ExecInitModifyTable has initialized WCO expressions with the wrong plan node as parent -- that is, it passed its input subplan not the ModifyTable node itself. Up to now we thought this was harmless, but bug #16006 from Vinay Banakar shows it's not: if the input node is a SubqueryScan then ExecInitWholeRowVar can get confused into doing the wrong thing. (The fact that ExecInitWholeRowVar contains such logic is certainly a horrid kluge that doesn't deserve to live, but figuring out another way to do that is a task for some other day.) Andres had already noticed the wrong-parent mistake and fixed it in commit 148e632, but not being aware of any user-visible consequences, he quite reasonably didn't back-patch. This patch is simply a back-patch of 148e632, plus addition of a test case based on bug #16006. I also added the test case to v12/HEAD, even though the bug is already fixed there. Back-patch to all supported branches. 9.4 lacks RLS policies so the new test case doesn't work there, but I'm pretty sure a test could be devised based on using a whole-row Var in a plain WITH CHECK OPTION condition. (I lack the cycles to do so myself, though.) Andres Freund and Tom Lane Discussion: https://postgr.es/m/16006-99290d2e4642cbd5@postgresql.org Discussion: https://postgr.es/m/20181205225213.hiwa3kgoxeybqcqv@alap3.anarazel.de
1 parent 614cdea commit 7f1f72c

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

src/test/regress/expected/rowsecurity.out

+34
Original file line numberDiff line numberDiff line change
@@ -3958,6 +3958,40 @@ DROP OPERATOR <<< (int, int);
39583958
DROP FUNCTION op_leak(int, int);
39593959
RESET SESSION AUTHORIZATION;
39603960
DROP TABLE rls_tbl;
3961+
-- Bug #16006: whole-row Vars in a policy don't play nice with sub-selects
3962+
SET SESSION AUTHORIZATION regress_rls_alice;
3963+
CREATE TABLE rls_tbl (a int, b int, c int);
3964+
CREATE POLICY p1 ON rls_tbl USING (rls_tbl >= ROW(1,1,1));
3965+
ALTER TABLE rls_tbl ENABLE ROW LEVEL SECURITY;
3966+
ALTER TABLE rls_tbl FORCE ROW LEVEL SECURITY;
3967+
INSERT INTO rls_tbl SELECT 10, 20, 30;
3968+
EXPLAIN (VERBOSE, COSTS OFF)
3969+
INSERT INTO rls_tbl
3970+
SELECT * FROM (SELECT b, c FROM rls_tbl ORDER BY a) ss;
3971+
QUERY PLAN
3972+
--------------------------------------------------------------------
3973+
Insert on regress_rls_schema.rls_tbl
3974+
-> Subquery Scan on ss
3975+
Output: ss.b, ss.c, NULL::integer
3976+
-> Sort
3977+
Output: rls_tbl_1.b, rls_tbl_1.c, rls_tbl_1.a
3978+
Sort Key: rls_tbl_1.a
3979+
-> Seq Scan on regress_rls_schema.rls_tbl rls_tbl_1
3980+
Output: rls_tbl_1.b, rls_tbl_1.c, rls_tbl_1.a
3981+
Filter: (rls_tbl_1.* >= '(1,1,1)'::record)
3982+
(9 rows)
3983+
3984+
INSERT INTO rls_tbl
3985+
SELECT * FROM (SELECT b, c FROM rls_tbl ORDER BY a) ss;
3986+
SELECT * FROM rls_tbl;
3987+
a | b | c
3988+
----+----+----
3989+
10 | 20 | 30
3990+
20 | 30 |
3991+
(2 rows)
3992+
3993+
DROP TABLE rls_tbl;
3994+
RESET SESSION AUTHORIZATION;
39613995
--
39623996
-- Clean up objects
39633997
--

src/test/regress/sql/rowsecurity.sql

+19
Original file line numberDiff line numberDiff line change
@@ -1810,6 +1810,25 @@ DROP FUNCTION op_leak(int, int);
18101810
RESET SESSION AUTHORIZATION;
18111811
DROP TABLE rls_tbl;
18121812

1813+
-- Bug #16006: whole-row Vars in a policy don't play nice with sub-selects
1814+
SET SESSION AUTHORIZATION regress_rls_alice;
1815+
CREATE TABLE rls_tbl (a int, b int, c int);
1816+
CREATE POLICY p1 ON rls_tbl USING (rls_tbl >= ROW(1,1,1));
1817+
1818+
ALTER TABLE rls_tbl ENABLE ROW LEVEL SECURITY;
1819+
ALTER TABLE rls_tbl FORCE ROW LEVEL SECURITY;
1820+
1821+
INSERT INTO rls_tbl SELECT 10, 20, 30;
1822+
EXPLAIN (VERBOSE, COSTS OFF)
1823+
INSERT INTO rls_tbl
1824+
SELECT * FROM (SELECT b, c FROM rls_tbl ORDER BY a) ss;
1825+
INSERT INTO rls_tbl
1826+
SELECT * FROM (SELECT b, c FROM rls_tbl ORDER BY a) ss;
1827+
SELECT * FROM rls_tbl;
1828+
1829+
DROP TABLE rls_tbl;
1830+
RESET SESSION AUTHORIZATION;
1831+
18131832
--
18141833
-- Clean up objects
18151834
--

0 commit comments

Comments
 (0)