Thread

  1. Re: Server crash: Use-after-free in AfterTriggerEndQuery()

    amit <amitlangote09@gmail.com> — 2026-05-05T07:45:26Z

    On Tue, May 5, 2026 at 15:37 Amul Sul <sulamul@gmail.com> wrote:
    
    > Hi,
    >
    > The crash occurs when the per-query firing loop in
    > AfterTriggerEndQuery() exits via the "all fired" path. If
    > afterTriggerInvokeEvents() reallocated query_stack while firing, the
    > loop's local qs pointer is left dangling, and the subsequent
    > FireAfterTriggerBatchCallbacks(qs->batch_callbacks) reads
    > batch_callbacks from the freed memory and crashes.
    >
    > Here is the reproducible test that has an AFTER INSERT trigger on a
    > referenced table that recursively inserts rows into itself:
    >
    > --
    > create table trigger_recursive_pk (id int primary key);
    > create table trigger_recursive_fk (id int references
    > trigger_recursive_pk(id));
    > insert into trigger_recursive_pk select g from generate_series(1, 15) g;
    >
    > create function trigger_recursive_fn() returns trigger language plpgsql as
    > $$
    > begin
    >     if new.id < 10 then
    >         insert into trigger_recursive_fk values (new.id + 1);
    >     end if;
    >     return new;
    > end$$;
    >
    > create trigger trigger_recursive after insert on trigger_recursive_fk
    >     for each row execute function trigger_recursive_fn();
    >
    > insert into trigger_recursive_fk values (1);
    > --
    >
    > The attached patch fixes the reported issue by recomputing qs
    > immediately before calling FireAfterTriggerBatchCallbacks().
    
    
    Thanks Amul for the report. I'll look at this on Thursday when I'm back at
    work.
    
    - Amit
    
    >