Hi hackers, While reading contrib/pageinspect I noticed that the GiST, B-tree and hash page_items() functions can read past the page image when handed a corrupt or crafted page. The attached patch fixes it and adds regression tests;
The only check they do before following a line pointer is
ItemIdIsValid(), but that just tests the pointer isn't NULL -- and it
never is. So a bogus line pointer offset makes the code read outside the
page image. heap_page_items() already guards against this; the attached
patch does the same for these three functions and adds regression tests.
Easy to see on an AddressSanitizer build:
CREATE EXTENSION pageinspect;
CREATE TABLE t AS SELECT point(i,i) p FROM generate_series(1,1000) i;
CREATE INDEX t_idx ON t USING gist (p);
-- overwrite the first line pointer with garbage:
SELECT gist_page_items_bytea(
set_byte(set_byte(set_byte(set_byte(
get_raw_page('t_idx', 0), 24, 255), 25, 255), 26, 255), 27, 255));
Without the patch this trips ASan (heap-buffer-overflow in
gist_page_items_bytea) and the backend goes down. With it, you just get:
ERROR: invalid line pointer at offset 1 in GiST page
These functions are superuser-only, so it's about not crashing on a
corrupt page rather than a security issue.
Thanks,
Shihao
0001-pageinspect-validate-line-pointers-before-using-them.patch
Description: Binary data
