summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2018-02-05 15:37:30 +0000
committerTom Lane2018-02-05 15:37:30 +0000
commitfe921a360a4858f537c99d1872d3c3a5a09d6df0 (patch)
tree29564feaeaea8d3ec48d570e2777858ac860f044
parent20446a4a04240ce9880331eea3082c906ede4f26 (diff)
Fix RelationBuildPartitionKey's processing of partition key expressions.
Failure to advance the list pointer while reading partition expressions from a list results in invoking an input function with inappropriate data, possibly leading to crashes or, with carefully crafted input, disclosure of arbitrary backend memory. Bug discovered independently by Álvaro Herrera and David Rowley. This patch is by Álvaro but owes something to David's proposed fix. Back-patch to v10 where the issue was introduced. Security: CVE-2018-1052
-rw-r--r--src/backend/utils/cache/relcache.c5
-rw-r--r--src/test/regress/expected/create_table.out31
-rw-r--r--src/test/regress/sql/create_table.sql11
3 files changed, 36 insertions, 11 deletions
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 6bd93b03d08..5e497aee9fe 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -964,9 +964,14 @@ RelationBuildPartitionKey(Relation relation)
}
else
{
+ if (partexprs_item == NULL)
+ elog(ERROR, "wrong number of partition key expressions");
+
key->parttypid[i] = exprType(lfirst(partexprs_item));
key->parttypmod[i] = exprTypmod(lfirst(partexprs_item));
key->parttypcoll[i] = exprCollation(lfirst(partexprs_item));
+
+ partexprs_item = lnext(partexprs_item);
}
get_typlenbyvalalign(key->parttypid[i],
&key->parttyplen[i],
diff --git a/src/test/regress/expected/create_table.out b/src/test/regress/expected/create_table.out
index 34305a96d02..f887781c6df 100644
--- a/src/test/regress/expected/create_table.out
+++ b/src/test/regress/expected/create_table.out
@@ -414,8 +414,9 @@ DETAIL: table partitioned depends on function plusone(integer)
HINT: Use DROP ... CASCADE to drop the dependent objects too.
-- partitioned table cannot participate in regular inheritance
CREATE TABLE partitioned2 (
- a int
-) PARTITION BY LIST ((a+1));
+ a int,
+ b text
+) PARTITION BY RANGE ((a+1), substr(b, 1, 5));
CREATE TABLE fail () INHERITS (partitioned2);
ERROR: cannot inherit from partitioned table "partitioned2"
-- Partition key in describe output
@@ -429,12 +430,26 @@ ERROR: cannot inherit from partitioned table "partitioned2"
d | text | | |
Partition key: RANGE (a oid_ops, plusone(b), c, d COLLATE "C")
-\d partitioned2
- Table "public.partitioned2"
- Column | Type | Collation | Nullable | Default
---------+---------+-----------+----------+---------
- a | integer | | |
-Partition key: LIST (((a + 1)))
+\d+ partitioned2
+ Table "public.partitioned2"
+ Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
+--------+---------+-----------+----------+---------+----------+--------------+-------------
+ a | integer | | | | plain | |
+ b | text | | | | extended | |
+Partition key: RANGE (((a + 1)), substr(b, 1, 5))
+
+INSERT INTO partitioned2 VALUES (1, 'hello');
+ERROR: no partition of relation "partitioned2" found for row
+DETAIL: Partition key of the failing row contains ((a + 1), substr(b, 1, 5)) = (2, hello).
+CREATE TABLE part2_1 PARTITION OF partitioned2 FOR VALUES FROM (-1, 'aaaaa') TO (100, 'ccccc');
+\d+ part2_1
+ Table "public.part2_1"
+ Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
+--------+---------+-----------+----------+---------+----------+--------------+-------------
+ a | integer | | | | plain | |
+ b | text | | | | extended | |
+Partition of: partitioned2 FOR VALUES FROM ('-1', 'aaaaa') TO (100, 'ccccc')
+Partition constraint: (((a + 1) IS NOT NULL) AND (substr(b, 1, 5) IS NOT NULL) AND (((a + 1) > '-1'::integer) OR (((a + 1) = '-1'::integer) AND (substr(b, 1, 5) >= 'aaaaa'::text))) AND (((a + 1) < 100) OR (((a + 1) = 100) AND (substr(b, 1, 5) < 'ccccc'::text))))
DROP TABLE partitioned, partitioned2;
--
diff --git a/src/test/regress/sql/create_table.sql b/src/test/regress/sql/create_table.sql
index c43fc56647f..9e8fc2f11f2 100644
--- a/src/test/regress/sql/create_table.sql
+++ b/src/test/regress/sql/create_table.sql
@@ -415,13 +415,18 @@ DROP FUNCTION plusone(int);
-- partitioned table cannot participate in regular inheritance
CREATE TABLE partitioned2 (
- a int
-) PARTITION BY LIST ((a+1));
+ a int,
+ b text
+) PARTITION BY RANGE ((a+1), substr(b, 1, 5));
CREATE TABLE fail () INHERITS (partitioned2);
-- Partition key in describe output
\d partitioned
-\d partitioned2
+\d+ partitioned2
+
+INSERT INTO partitioned2 VALUES (1, 'hello');
+CREATE TABLE part2_1 PARTITION OF partitioned2 FOR VALUES FROM (-1, 'aaaaa') TO (100, 'ccccc');
+\d+ part2_1
DROP TABLE partitioned, partitioned2;