From 6e3a51ff8adae78e4c8ee10b281f2d3922b8cf83 Mon Sep 17 00:00:00 2001 From: Peter Geoghegan Date: Wed, 12 Oct 2016 15:59:58 -0700 Subject: [PATCH] Fix use-after-free around DISTINCT transition function calls. Have tuplesort_gettupleslot() copy the contents of its current table slot as needed. This is based on an approach taken by tuplestore_gettupleslot(). In the future, tuplesort_gettupleslot() may also be taught to avoid copying the tuple where caller can determine that that is safe (the tuplestore_gettupleslot() interface already offers this option to callers). Per bug #14344 from Regina Obe. Report: <20160929035538.20224.39628@wrigleys.postgresql.org> Backpatch-through: 9.6 --- src/backend/utils/sort/tuplesort.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c index f6eb30c..e69b0e6 100644 --- a/src/backend/utils/sort/tuplesort.c +++ b/src/backend/utils/sort/tuplesort.c @@ -2084,6 +2084,10 @@ tuplesort_gettuple_common(Tuplesortstate *state, bool forward, * determination of "non-equal tuple" based on simple binary inequality. A * NULL value in leading attribute will set abbreviated value to zeroed * representation, which caller may rely on in abbreviated inequality check. + * + * The slot receives a copied tuple (allocated in tuplesort memory context) + * that will stay valid regardless of future manipulations of the tuplesort's + * state. */ bool tuplesort_gettupleslot(Tuplesortstate *state, bool forward, @@ -2104,6 +2108,11 @@ tuplesort_gettupleslot(Tuplesortstate *state, bool forward, if (state->sortKeys->abbrev_converter && abbrev) *abbrev = stup.datum1; + if (!should_free) + { + stup.tuple = heap_copy_minimal_tuple((MinimalTuple) stup.tuple); + should_free = true; + } ExecStoreMinimalTuple((MinimalTuple) stup.tuple, slot, should_free); return true; } -- 2.7.4