git.postgresql.org Git - postgresql.git/commitdiff

git projects / postgresql.git / commitdiff
? search:
summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: bb385c4)
Fix potential use-after-free for BEFORE UPDATE row triggers on non-core AMs.
2019年4月19日 00:53:54 +0000 (17:53 -0700)
2019年4月19日 00:53:54 +0000 (17:53 -0700)
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


diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 3ae2640abd4cd9b22b8a2bdad9ed489713101780..c81ccc8fcffc9108594aa40530107595cecb606f 100644 (file)
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -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);
This is the main PostgreSQL git repository.
RSS Atom

AltStyle によって変換されたページ (->オリジナル) /