Skip to content

Commit 3ca43db

Browse files
committed
Add permission check for MERGE/SPLIT partition operations
Currently, we check only owner permission for the parent table before MERGE/SPLIT partition operations. This leads to a security hole when users can get access to the data of partitions without permission. This commit fixes this problem by requiring owner permission on all the partitions involved. Reported-by: Alexander Lakhin Discussion: https://postgr.es/m/0520c72e-8d97-245e-53f9-173beca2ab2e%40gmail.com Author: Dmitry Koval, Alexander Korotkov
1 parent cff4e5a commit 3ca43db

File tree

5 files changed

+129
-0
lines changed

5 files changed

+129
-0
lines changed

src/backend/parser/parse_utilcmd.c

+5
Original file line numberDiff line numberDiff line change
@@ -3456,6 +3456,11 @@ checkPartition(Relation rel, Oid partRelOid)
34563456
RelationGetRelationName(partRel),
34573457
RelationGetRelationName(rel))));
34583458

3459+
/* Permissions checks */
3460+
if (!object_ownercheck(RelationRelationId, RelationGetRelid(partRel), GetUserId()))
3461+
aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(partRel->rd_rel->relkind),
3462+
RelationGetRelationName(partRel));
3463+
34593464
relation_close(partRel, AccessShareLock);
34603465
}
34613466

src/test/regress/expected/partition_merge.out

+29
Original file line numberDiff line numberDiff line change
@@ -881,6 +881,35 @@ ORDER BY c.relname;
881881

882882
DROP TABLE t;
883883
DROP ACCESS METHOD partitions_merge_heap;
884+
-- Test permission checks. The user needs to own the parent table and all
885+
-- the merging partitions to do the merge.
886+
CREATE ROLE regress_partition_merge_alice;
887+
CREATE ROLE regress_partition_merge_bob;
888+
SET SESSION AUTHORIZATION regress_partition_merge_alice;
889+
CREATE TABLE t (i int) PARTITION BY RANGE (i);
890+
CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1);
891+
CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2);
892+
SET SESSION AUTHORIZATION regress_partition_merge_bob;
893+
ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
894+
ERROR: must be owner of table t
895+
RESET SESSION AUTHORIZATION;
896+
ALTER TABLE t OWNER TO regress_partition_merge_bob;
897+
SET SESSION AUTHORIZATION regress_partition_merge_bob;
898+
ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
899+
ERROR: must be owner of table tp_0_1
900+
RESET SESSION AUTHORIZATION;
901+
ALTER TABLE tp_0_1 OWNER TO regress_partition_merge_bob;
902+
SET SESSION AUTHORIZATION regress_partition_merge_bob;
903+
ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
904+
ERROR: must be owner of table tp_1_2
905+
RESET SESSION AUTHORIZATION;
906+
ALTER TABLE tp_1_2 OWNER TO regress_partition_merge_bob;
907+
SET SESSION AUTHORIZATION regress_partition_merge_bob;
908+
ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
909+
RESET SESSION AUTHORIZATION;
910+
DROP TABLE t;
911+
DROP ROLE regress_partition_merge_alice;
912+
DROP ROLE regress_partition_merge_bob;
884913
RESET search_path;
885914
--
886915
DROP SCHEMA partitions_merge_schema;

src/test/regress/expected/partition_split.out

+29
Original file line numberDiff line numberDiff line change
@@ -1514,6 +1514,35 @@ ORDER BY c.relname;
15141514

15151515
DROP TABLE t;
15161516
DROP ACCESS METHOD partition_split_heap;
1517+
-- Test permission checks. The user needs to own the parent table and the
1518+
-- the partition to split to do the split.
1519+
CREATE ROLE regress_partition_merge_alice;
1520+
CREATE ROLE regress_partition_merge_bob;
1521+
SET SESSION AUTHORIZATION regress_partition_merge_alice;
1522+
CREATE TABLE t (i int) PARTITION BY RANGE (i);
1523+
CREATE TABLE tp_0_2 PARTITION OF t FOR VALUES FROM (0) TO (2);
1524+
SET SESSION AUTHORIZATION regress_partition_merge_bob;
1525+
ALTER TABLE t SPLIT PARTITION tp_0_2 INTO
1526+
(PARTITION tp_0_1 FOR VALUES FROM (0) TO (1),
1527+
PARTITION tp_1_2 FOR VALUES FROM (1) TO (2));
1528+
ERROR: must be owner of table t
1529+
RESET SESSION AUTHORIZATION;
1530+
ALTER TABLE t OWNER TO regress_partition_merge_bob;
1531+
SET SESSION AUTHORIZATION regress_partition_merge_bob;
1532+
ALTER TABLE t SPLIT PARTITION tp_0_2 INTO
1533+
(PARTITION tp_0_1 FOR VALUES FROM (0) TO (1),
1534+
PARTITION tp_1_2 FOR VALUES FROM (1) TO (2));
1535+
ERROR: must be owner of table tp_0_2
1536+
RESET SESSION AUTHORIZATION;
1537+
ALTER TABLE tp_0_2 OWNER TO regress_partition_merge_bob;
1538+
SET SESSION AUTHORIZATION regress_partition_merge_bob;
1539+
ALTER TABLE t SPLIT PARTITION tp_0_2 INTO
1540+
(PARTITION tp_0_1 FOR VALUES FROM (0) TO (1),
1541+
PARTITION tp_1_2 FOR VALUES FROM (1) TO (2));
1542+
RESET SESSION AUTHORIZATION;
1543+
DROP TABLE t;
1544+
DROP ROLE regress_partition_merge_alice;
1545+
DROP ROLE regress_partition_merge_bob;
15171546
--
15181547
DROP SCHEMA partition_split_schema;
15191548
DROP SCHEMA partition_split_schema2;

src/test/regress/sql/partition_merge.sql

+33
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,39 @@ ORDER BY c.relname;
549549
DROP TABLE t;
550550
DROP ACCESS METHOD partitions_merge_heap;
551551

552+
-- Test permission checks. The user needs to own the parent table and all
553+
-- the merging partitions to do the merge.
554+
CREATE ROLE regress_partition_merge_alice;
555+
CREATE ROLE regress_partition_merge_bob;
556+
557+
SET SESSION AUTHORIZATION regress_partition_merge_alice;
558+
CREATE TABLE t (i int) PARTITION BY RANGE (i);
559+
CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1);
560+
CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2);
561+
562+
SET SESSION AUTHORIZATION regress_partition_merge_bob;
563+
ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
564+
RESET SESSION AUTHORIZATION;
565+
566+
ALTER TABLE t OWNER TO regress_partition_merge_bob;
567+
SET SESSION AUTHORIZATION regress_partition_merge_bob;
568+
ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
569+
RESET SESSION AUTHORIZATION;
570+
571+
ALTER TABLE tp_0_1 OWNER TO regress_partition_merge_bob;
572+
SET SESSION AUTHORIZATION regress_partition_merge_bob;
573+
ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
574+
RESET SESSION AUTHORIZATION;
575+
576+
ALTER TABLE tp_1_2 OWNER TO regress_partition_merge_bob;
577+
SET SESSION AUTHORIZATION regress_partition_merge_bob;
578+
ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
579+
RESET SESSION AUTHORIZATION;
580+
581+
DROP TABLE t;
582+
DROP ROLE regress_partition_merge_alice;
583+
DROP ROLE regress_partition_merge_bob;
584+
552585
RESET search_path;
553586

554587
--

src/test/regress/sql/partition_split.sql

+33
Original file line numberDiff line numberDiff line change
@@ -894,6 +894,39 @@ ORDER BY c.relname;
894894
DROP TABLE t;
895895
DROP ACCESS METHOD partition_split_heap;
896896

897+
-- Test permission checks. The user needs to own the parent table and the
898+
-- the partition to split to do the split.
899+
CREATE ROLE regress_partition_merge_alice;
900+
CREATE ROLE regress_partition_merge_bob;
901+
902+
SET SESSION AUTHORIZATION regress_partition_merge_alice;
903+
CREATE TABLE t (i int) PARTITION BY RANGE (i);
904+
CREATE TABLE tp_0_2 PARTITION OF t FOR VALUES FROM (0) TO (2);
905+
906+
SET SESSION AUTHORIZATION regress_partition_merge_bob;
907+
ALTER TABLE t SPLIT PARTITION tp_0_2 INTO
908+
(PARTITION tp_0_1 FOR VALUES FROM (0) TO (1),
909+
PARTITION tp_1_2 FOR VALUES FROM (1) TO (2));
910+
RESET SESSION AUTHORIZATION;
911+
912+
ALTER TABLE t OWNER TO regress_partition_merge_bob;
913+
SET SESSION AUTHORIZATION regress_partition_merge_bob;
914+
ALTER TABLE t SPLIT PARTITION tp_0_2 INTO
915+
(PARTITION tp_0_1 FOR VALUES FROM (0) TO (1),
916+
PARTITION tp_1_2 FOR VALUES FROM (1) TO (2));
917+
RESET SESSION AUTHORIZATION;
918+
919+
ALTER TABLE tp_0_2 OWNER TO regress_partition_merge_bob;
920+
SET SESSION AUTHORIZATION regress_partition_merge_bob;
921+
ALTER TABLE t SPLIT PARTITION tp_0_2 INTO
922+
(PARTITION tp_0_1 FOR VALUES FROM (0) TO (1),
923+
PARTITION tp_1_2 FOR VALUES FROM (1) TO (2));
924+
RESET SESSION AUTHORIZATION;
925+
926+
DROP TABLE t;
927+
DROP ROLE regress_partition_merge_alice;
928+
DROP ROLE regress_partition_merge_bob;
929+
897930

898931
--
899932
DROP SCHEMA partition_split_schema;

0 commit comments

Comments
 (0)