Commit 75e03eab authored by Andres Freund's avatar Andres Freund

Fix potential use-after-free for BEFORE UPDATE row triggers on non-core AMs.

When such a trigger returns the old row version, it naturally get
stored in the slot for the trigger result. When a table AMs doesn't
store HeapTuples internally, ExecBRUpdateTriggers() frees the old row
version passed to triggers - but before this fix it might still be
referenced by the slot holding the new tuple.

Noticed when running the out-of-core zheap AM against the in-core
version of tableam.

Author: Andres Freund
parent bb385c4f
......@@ -3109,6 +3109,15 @@ ExecBRUpdateTriggers(EState *estate, EPQState *epqstate,
{
ExecForceStoreHeapTuple(newtuple, newslot);
/*
* If the tuple returned by the trigger / being stored, is the old
* row version, and the heap tuple passed to the trigger was
* allocated locally, materialize the slot. Otherwise we might
* free it while still referenced by the slot.
*/
if (should_free_trig && newtuple == trigtuple)
ExecMaterializeSlot(newslot);
if (should_free_new)
heap_freetuple(oldtuple);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment