Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 75e03ea

Browse files
committed
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
1 parent bb385c4 commit 75e03ea

File tree

1 file changed

+9
-0
lines changed

1 file changed

+9
-0
lines changed

src/backend/commands/trigger.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3109,6 +3109,15 @@ ExecBRUpdateTriggers(EState *estate, EPQState *epqstate,
31093109
{
31103110
ExecForceStoreHeapTuple(newtuple, newslot);
31113111

3112+
/*
3113+
* If the tuple returned by the trigger / being stored, is the old
3114+
* row version, and the heap tuple passed to the trigger was
3115+
* allocated locally, materialize the slot. Otherwise we might
3116+
* free it while still referenced by the slot.
3117+
*/
3118+
if (should_free_trig && newtuple == trigtuple)
3119+
ExecMaterializeSlot(newslot);
3120+
31123121
if (should_free_new)
31133122
heap_freetuple(oldtuple);
31143123

0 commit comments

Comments
 (0)