Hello, hackers! The last query in the following script crashes Postgres:
create table t (id serial, amount int); insert into t (amount) select random() * 1000 from generate_series(1, 100); create extension btree_gist; create index t_gist_idx on t using gist(id, amount); select p.id, p.amount, s.nearest from t as p left join lateral ( select p.id, array_agg(l.id) as nearest from ( select id from t order by amount <-> p.amount limit 10 ) l ) s using(id); In gistrescan() IndexScanDesc.xs_hitup is not reset after MemoryContextReset() of so->queueCxt in which xs_hitup was allocated, then getNextNearest() tries to pfree() dangling xs_hitup, which results in the reuse of this pointer and the subsequent crash. Attached patches fix this bug introduced in commit d04c8ed9044eccebce043143a930617e3998c005 "Add support for index-only scans in GiST". The bug is present in v9.5, v9.6, v10.0. -- Nikita Glukhov Postgres Professional:http://www.postgrespro.com The Russian Postgres Company
diff --git a/src/backend/access/gist/gistscan.c b/src/backend/access/gist/gistscan.c index 2526a39..580b6ac 100644 --- a/src/backend/access/gist/gistscan.c +++ b/src/backend/access/gist/gistscan.c @@ -148,6 +148,11 @@ gistrescan(IndexScanDesc scan, ScanKey key, int nkeys, /* third or later time through */ MemoryContextReset(so->queueCxt); first_time = false; + /* + * scan->xs_itup is allocated in so->queueCxt and now it is invalid, + * so we need to reset it to prevent it from freeing in getNextNearest(). + */ + scan->xs_itup = NULL; } /*
diff --git a/src/backend/access/gist/gistscan.c b/src/backend/access/gist/gistscan.c index 81ff8fc..5e10ada 100644 --- a/src/backend/access/gist/gistscan.c +++ b/src/backend/access/gist/gistscan.c @@ -148,6 +148,11 @@ gistrescan(IndexScanDesc scan, ScanKey key, int nkeys, /* third or later time through */ MemoryContextReset(so->queueCxt); first_time = false; + /* + * scan->xs_hitup is allocated in so->queueCxt and now it is invalid, + * so we need to reset it to prevent it from freeing in getNextNearest(). + */ + scan->xs_hitup = NULL; } /*
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers