From 52635c276fe352276c157ccea36d7655729d328d Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Mon, 6 May 2019 21:44:39 +0900 Subject: [PATCH] Fix tuple printing in error message of tuple routing for partitions 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 | 8 ++++---- src/test/regress/expected/insert.out | 15 +++++++++++++++ src/test/regress/sql/insert.sql | 7 +++++++ 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c index 8061c7e449..0595d6bf1d 100644 --- a/src/backend/executor/execPartition.c +++ b/src/backend/executor/execPartition.c @@ -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; diff --git a/src/test/regress/expected/insert.out b/src/test/regress/expected/insert.out index 13f53e3649..2d909972ff 100644 --- a/src/test/regress/expected/insert.out +++ b/src/test/regress/expected/insert.out @@ -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 -------------+---+----+---+--- diff --git a/src/test/regress/sql/insert.sql b/src/test/regress/sql/insert.sql index 4d1c92a54d..23885f638c 100644 --- a/src/test/regress/sql/insert.sql +++ b/src/test/regress/sql/insert.sql @@ -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;