Skip to content

Commit fe921a3

Browse files
committed
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
1 parent 20446a4 commit fe921a3

File tree

3 files changed

+36
-11
lines changed

3 files changed

+36
-11
lines changed

src/backend/utils/cache/relcache.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -964,9 +964,14 @@ RelationBuildPartitionKey(Relation relation)
964964
}
965965
else
966966
{
967+
if (partexprs_item == NULL)
968+
elog(ERROR, "wrong number of partition key expressions");
969+
967970
key->parttypid[i] = exprType(lfirst(partexprs_item));
968971
key->parttypmod[i] = exprTypmod(lfirst(partexprs_item));
969972
key->parttypcoll[i] = exprCollation(lfirst(partexprs_item));
973+
974+
partexprs_item = lnext(partexprs_item);
970975
}
971976
get_typlenbyvalalign(key->parttypid[i],
972977
&key->parttyplen[i],

src/test/regress/expected/create_table.out

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -414,8 +414,9 @@ DETAIL: table partitioned depends on function plusone(integer)
414414
HINT: Use DROP ... CASCADE to drop the dependent objects too.
415415
-- partitioned table cannot participate in regular inheritance
416416
CREATE TABLE partitioned2 (
417-
a int
418-
) PARTITION BY LIST ((a+1));
417+
a int,
418+
b text
419+
) PARTITION BY RANGE ((a+1), substr(b, 1, 5));
419420
CREATE TABLE fail () INHERITS (partitioned2);
420421
ERROR: cannot inherit from partitioned table "partitioned2"
421422
-- Partition key in describe output
@@ -429,12 +430,26 @@ ERROR: cannot inherit from partitioned table "partitioned2"
429430
d | text | | |
430431
Partition key: RANGE (a oid_ops, plusone(b), c, d COLLATE "C")
431432

432-
\d partitioned2
433-
Table "public.partitioned2"
434-
Column | Type | Collation | Nullable | Default
435-
--------+---------+-----------+----------+---------
436-
a | integer | | |
437-
Partition key: LIST (((a + 1)))
433+
\d+ partitioned2
434+
Table "public.partitioned2"
435+
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
436+
--------+---------+-----------+----------+---------+----------+--------------+-------------
437+
a | integer | | | | plain | |
438+
b | text | | | | extended | |
439+
Partition key: RANGE (((a + 1)), substr(b, 1, 5))
440+
441+
INSERT INTO partitioned2 VALUES (1, 'hello');
442+
ERROR: no partition of relation "partitioned2" found for row
443+
DETAIL: Partition key of the failing row contains ((a + 1), substr(b, 1, 5)) = (2, hello).
444+
CREATE TABLE part2_1 PARTITION OF partitioned2 FOR VALUES FROM (-1, 'aaaaa') TO (100, 'ccccc');
445+
\d+ part2_1
446+
Table "public.part2_1"
447+
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
448+
--------+---------+-----------+----------+---------+----------+--------------+-------------
449+
a | integer | | | | plain | |
450+
b | text | | | | extended | |
451+
Partition of: partitioned2 FOR VALUES FROM ('-1', 'aaaaa') TO (100, 'ccccc')
452+
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))))
438453

439454
DROP TABLE partitioned, partitioned2;
440455
--

src/test/regress/sql/create_table.sql

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -415,13 +415,18 @@ DROP FUNCTION plusone(int);
415415

416416
-- partitioned table cannot participate in regular inheritance
417417
CREATE TABLE partitioned2 (
418-
a int
419-
) PARTITION BY LIST ((a+1));
418+
a int,
419+
b text
420+
) PARTITION BY RANGE ((a+1), substr(b, 1, 5));
420421
CREATE TABLE fail () INHERITS (partitioned2);
421422

422423
-- Partition key in describe output
423424
\d partitioned
424-
\d partitioned2
425+
\d+ partitioned2
426+
427+
INSERT INTO partitioned2 VALUES (1, 'hello');
428+
CREATE TABLE part2_1 PARTITION OF partitioned2 FOR VALUES FROM (-1, 'aaaaa') TO (100, 'ccccc');
429+
\d+ part2_1
425430

426431
DROP TABLE partitioned, partitioned2;
427432

0 commit comments

Comments
 (0)