Fix use-after-free of qs in AfterTriggerEndQuery. afterTriggerInvokeEvents() may repalloc afterTriggers.query_stack while firing trigger events, leaving any precomputed entry pointer dangling. The loop body in AfterTriggerEndQuery() recomputes qs after each afterTriggerInvokeEvents() call for that reason, but the "all fired" break path exits without the recompute, and the subsequent FireAfterTriggerBatchCallbacks(qs->batch_callbacks) dereferences the freed pointer.
Fix by recomputing qs immediately before FireAfterTriggerBatchCallbacks(), as the loop body already does after each afterTriggerInvokeEvents() call. The hazard was introduced in 34a30786293, which added the qs->batch_callbacks dereference at this site. Reported-by: Amul Sul <[email protected]> Author: Amul Sul <[email protected]> Reviewed-by: Anthonin Bonnefoy <[email protected]> Reviewed-by: Amit Langote <[email protected]> Discussion: https://postgr.es/m/CAAJ_b95p6-qiVpE2Gpr=bUsNAqTcejD_rPgLnfjx9m=fo3r...@mail.gmail.com Branch ------ master Details ------- https://git.postgresql.org/pg/commitdiff/4b1b2be22f2588f00dfd330886c1ca949f7dd938 Modified Files -------------- src/backend/commands/trigger.c | 5 +++++ src/test/regress/expected/triggers.out | 24 ++++++++++++++++++++++++ src/test/regress/sql/triggers.sql | 23 +++++++++++++++++++++++ 3 files changed, 52 insertions(+)
