agora inbox for pgsql-committers@postgresql.org
help / color / mirror / Atom feedFrom: Amit Langote <amitlan@postgresql.org>
To: pgsql-committers@lists.postgresql.org
Subject: pgsql: Fix out-of-bounds write in RI fast-path batch on re-entry
Date: Fri, 12 Jun 2026 01:37:53 +0000
Message-ID: <E1wXqqH-0025Ye-21@gemulon.postgresql.org> (raw)
Fix out-of-bounds write in RI fast-path batch on re-entry
The FK fast-path batching added in b7b27eb41a5 wrote the incoming row
into the batch array before checking whether the array was full:
fpentry->batch[fpentry->batch_count] = ExecCopySlotHeapTuple(newslot);
fpentry->batch_count++;
if (fpentry->batch_count >= RI_FASTPATH_BATCH_SIZE)
ri_FastPathBatchFlush(fpentry, fk_rel, riinfo);
batch_count is reset to zero only at the end of ri_FastPathBatchFlush(),
so it remains at RI_FASTPATH_BATCH_SIZE throughout a full-batch flush.
A flush runs user-defined cast functions and equality operators; if that
user code performs DML on the same FK table, ri_FastPathBatchAdd()
re-enters with batch_count == RI_FASTPATH_BATCH_SIZE and writes one past
the end of the array, corrupting the adjacent batch_count field. This
is reachable by an unprivileged table owner via an implicit cast with a
PL/pgSQL function and causes a SIGSEGV in assert-enabled builds.
Fix by bounds-checking the write into the batch array so a re-entrant
add can never write past the end, and by adding a "flushing" flag to
RI_FastPathEntry that routes re-entrant ri_FastPathBatchAdd() calls on
a busy entry to the per-row path (ri_FastPathCheck) instead of touching
the mid-flush batch array. The flag is set around the probe in
ri_FastPathBatchFlush() and cleared in a PG_FINALLY, which also resets
batch_count, so the entry is left empty and reusable if a flush error
(including a reported FK violation) is caught by a savepoint.
Add regression tests for both the re-entrant flush and reuse of an entry
after a flush error caught by a savepoint.
Reported-by: Nikolay Samokhvalov <nik@postgres.ai>
Reviewed-by: Nikolay Samokhvalov <nik@postgres.ai>
Reviewed-by: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
Reviewed-by: Junwang Zhao <zhjwpku@gmail.com>
Discussion: https://postgr.es/m/CAM527d9exRCdWrhJOnAxk_vACg7sr_yPoaJp_+uCFY0qP8v=aw@mail.gmail.com
Branch
------
master
Details
-------
https://git.postgresql.org/pg/commitdiff/0e47bb5fbeec64d776d49dee242bac39d4616f8b
Modified Files
--------------
src/backend/utils/adt/ri_triggers.c | 80 ++++++++++++++++++++++++-------
src/test/regress/expected/foreign_key.out | 56 ++++++++++++++++++++++
src/test/regress/sql/foreign_key.sql | 46 ++++++++++++++++++
3 files changed, 165 insertions(+), 17 deletions(-)
Message-ID: <E1wXqqH-0025Ye-21@gemulon.postgresql.org>
Permalink: ../E1wXqqH-0025Ye-21@gemulon.postgresql.org/
Also on: postgresql.org/message-id/E1wXqqH-0025Ye-21@gemulon.postgresql.org
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-committers@postgresql.org
Cc: amitlan@postgresql.org, pgsql-committers@lists.postgresql.org
Subject: Re: pgsql: Fix out-of-bounds write in RI fast-path batch on re-entry
In-Reply-To: <E1wXqqH-0025Ye-21@gemulon.postgresql.org>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox