[PATCH] Add reentrancy guards in ri_triggers.c

Lucas Jeffrey <lucas.jeffrey@anachronics.com>

From: Lucas Jeffrey <lucas.jeffrey@anachronics.com>
To: pgsql-hackers@lists.postgresql.org
Cc: Rodolfo Campero <rodolfo.campero@anachronics.com>, Marcos Castedo <marcos.castedo@anachronics.com>, Andrés Krüger <andres.kruger@anachronics.com>
Date: 2026-05-20T13:14:36Z
Lists: pgsql-hackers

Attachments

Hi hackers,

We found a bug where executing a DELETE on a self-referential table that
fires triggers can cause a segmentation fault. This is due to a
*use-after-free* of a Postgres plan generated by the referential integrity
module (ri_triggers.c, RI_FKey_cascade_del). The crash occurs if the
Postgres plancache is invalidated (ResetPlanCache) during the execution of
a reentrant RI trigger.

A reentrant RI_FKey_cascade_del can occur if a table is self-referential
(i.e., it has a foreign key referencing its own primary key) and has BEFORE
DELETE triggers that delete rows from that same table.

   -

   *The first patch* adds a test case that reproduces the segmentation
   fault. The crash itself happens in _SPI_execute_plan, but the root cause
   is that the plan being executed was prematurely freed by the RI module.
   -

   *The second patch* fixes ri_triggers.c by introducing reentrancy guards,
   which maintain a reference count of plans in execution to prevent them from
   being freed while active.

Feedback and reviews are welcome.

Best regards,

Lucas Jeffrey