]> granicus.if.org Git - postgresql/commitdiff
Fix tuple printing in error message of tuple routing for partitions
authorMichael Paquier <michael@paquier.xyz>
Mon, 6 May 2019 12:44:39 +0000 (21:44 +0900)
committerMichael Paquier <michael@paquier.xyz>
Mon, 6 May 2019 12:44:39 +0000 (21:44 +0900)
With correctly crafted DDLs, this could lead to disclosure of arbitrary
backend memory a user may have no right to access.  This impacts only
REL_11_STABLE, as the issue has been introduced by 34295b8.

On HEAD, add regression tests to cover this issue in the future.

Author: Michael Paquier
Reviewed-by: Noah Misch
Security: CVE-2019-10129

src/backend/executor/execPartition.c
src/test/regress/expected/insert.out
src/test/regress/sql/insert.sql

index 8061c7e449d08ae46458a57f44a9451fd49f4f90..0595d6bf1d64b05caf720a2ba1ddef18f1d3f556 100644 (file)
@@ -329,10 +329,6 @@ ExecFindPartition(ResultRelInfo *resultRelInfo, PartitionDispatch *pd,
                }
        }
 
-       /* Release the tuple in the lowest parent's dedicated slot. */
-       if (myslot != slot)
-               ExecClearTuple(myslot);
-
        /* A partition was not found. */
        if (result < 0)
        {
@@ -348,6 +344,10 @@ ExecFindPartition(ResultRelInfo *resultRelInfo, PartitionDispatch *pd,
                                 val_desc ? errdetail("Partition key of the failing row contains %s.", val_desc) : 0));
        }
 
+       /* Release the tuple in the lowest parent's dedicated slot. */
+       if (myslot != slot)
+               ExecClearTuple(myslot);
+
        MemoryContextSwitchTo(oldcxt);
        ecxt->ecxt_scantuple = ecxt_scantuple_old;
 
index 13f53e36490b14611a619be1cf0705c2af6633de..2d909972ff37f45b0565a09cfd7812fea4943e1b 100644 (file)
@@ -637,6 +637,9 @@ create table mlparted5 partition of mlparted
   for values from (1, 40) to (1, 50) partition by range (c);
 create table mlparted5_ab partition of mlparted5
   for values from ('a') to ('c') partition by list (c);
+-- This partitioned table should remain with no partitions.
+create table mlparted5_cd partition of mlparted5
+  for values from ('c') to ('e') partition by list (c);
 create table mlparted5_a partition of mlparted5_ab for values in ('a');
 create table mlparted5_b (d int, b int, c text, a int);
 alter table mlparted5_ab attach partition mlparted5_b for values in ('b');
@@ -644,6 +647,12 @@ truncate mlparted;
 insert into mlparted values (1, 2, 'a', 1);
 insert into mlparted values (1, 40, 'a', 1);  -- goes to mlparted5_a
 insert into mlparted values (1, 45, 'b', 1);  -- goes to mlparted5_b
+insert into mlparted values (1, 45, 'c', 1);  -- goes to mlparted5_cd, fails
+ERROR:  no partition of relation "mlparted5_cd" found for row
+DETAIL:  Partition key of the failing row contains (c) = (c).
+insert into mlparted values (1, 45, 'f', 1);  -- goes to mlparted5, fails
+ERROR:  no partition of relation "mlparted5" found for row
+DETAIL:  Partition key of the failing row contains (c) = (f).
 select tableoid::regclass, * from mlparted order by a, b, c, d;
   tableoid   | a | b  | c | d 
 -------------+---+----+---+---
@@ -660,6 +669,12 @@ alter table mlparted drop e;
 insert into mlparted values (1, 2, 'a', 1);
 insert into mlparted values (1, 40, 'a', 1);  -- goes to mlparted5_a
 insert into mlparted values (1, 45, 'b', 1);  -- goes to mlparted5_b
+insert into mlparted values (1, 45, 'c', 1);  -- goes to mlparted5_cd, fails
+ERROR:  no partition of relation "mlparted5_cd" found for row
+DETAIL:  Partition key of the failing row contains (c) = (c).
+insert into mlparted values (1, 45, 'f', 1);  -- goes to mlparted5, fails
+ERROR:  no partition of relation "mlparted5" found for row
+DETAIL:  Partition key of the failing row contains (c) = (f).
 select tableoid::regclass, * from mlparted order by a, b, c, d;
   tableoid   | a | b  | c | d 
 -------------+---+----+---+---
index 4d1c92a54df990c4f9c5314f9f043295ed87d2ed..23885f638c0851d3f223cbabf0ede7cf255c426c 100644 (file)
@@ -409,6 +409,9 @@ create table mlparted5 partition of mlparted
   for values from (1, 40) to (1, 50) partition by range (c);
 create table mlparted5_ab partition of mlparted5
   for values from ('a') to ('c') partition by list (c);
+-- This partitioned table should remain with no partitions.
+create table mlparted5_cd partition of mlparted5
+  for values from ('c') to ('e') partition by list (c);
 create table mlparted5_a partition of mlparted5_ab for values in ('a');
 create table mlparted5_b (d int, b int, c text, a int);
 alter table mlparted5_ab attach partition mlparted5_b for values in ('b');
@@ -416,6 +419,8 @@ truncate mlparted;
 insert into mlparted values (1, 2, 'a', 1);
 insert into mlparted values (1, 40, 'a', 1);  -- goes to mlparted5_a
 insert into mlparted values (1, 45, 'b', 1);  -- goes to mlparted5_b
+insert into mlparted values (1, 45, 'c', 1);  -- goes to mlparted5_cd, fails
+insert into mlparted values (1, 45, 'f', 1);  -- goes to mlparted5, fails
 select tableoid::regclass, * from mlparted order by a, b, c, d;
 alter table mlparted drop d;
 truncate mlparted;
@@ -425,6 +430,8 @@ alter table mlparted drop e;
 insert into mlparted values (1, 2, 'a', 1);
 insert into mlparted values (1, 40, 'a', 1);  -- goes to mlparted5_a
 insert into mlparted values (1, 45, 'b', 1);  -- goes to mlparted5_b
+insert into mlparted values (1, 45, 'c', 1);  -- goes to mlparted5_cd, fails
+insert into mlparted values (1, 45, 'f', 1);  -- goes to mlparted5, fails
 select tableoid::regclass, * from mlparted order by a, b, c, d;
 alter table mlparted drop d;
 drop table mlparted5;