pgsql: Prevent access to an unpinned buffer in BEFORE ROW UPDATE trigge - Mailing list pgsql-committers

From Tom Lane
Subject pgsql: Prevent access to an unpinned buffer in BEFORE ROW UPDATE trigge
Date
Msg-id E1rP4Rf-001Qkn-UD@gemulon.postgresql.org
Whole thread Raw
List pgsql-committers
Prevent access to an unpinned buffer in BEFORE ROW UPDATE triggers.

When ExecBRUpdateTriggers switches to a new target tuple as a result
of the EvalPlanQual logic, it must form a new proposed update tuple.
Since commit 86dc90056, that tuple (the result of
ExecGetUpdateNewTuple) has been a virtual tuple that might contain
pointers to by-ref fields of the new target tuple (in "oldslot").
However, immediately after that we materialize oldslot, causing it to
drop its buffer pin, whereupon the by-ref pointers are unsafe to use.
This is a live bug only when the new target tuple is in a different
page than the original target tuple, since we do still hold a pin on
the original one.  (Before 86dc90056, there was no bug because the
EPQ plantree would hold a pin on the new target tuple; but now that's
not assured.)  To fix, forcibly materialize the new tuple before we
materialize oldslot.  This costs nothing since we would have done that
shortly anyway.

The real-world impact of this is probably minimal.  A visible failure
could occur if the new target tuple's buffer were recycled for some
other page in the short interval before we materialize newslot within
the trigger-calling loop; but that's quite unlikely given that we'd
just touched that page.  There's a larger hazard that some other
process could prune and repack that page within the window.  We have
lock on the new target tuple, but that wouldn't prevent it being moved
on the page.

Alexander Lakhin and Tom Lane, per bug #17798 from Alexander Lakhin.
Back-patch to v14 where 86dc90056 came in.

Discussion: https://postgr.es/m/17798-0907404928dcf0dd@postgresql.org

Branch
------
master

Details
-------
https://git.postgresql.org/pg/commitdiff/6545ba96cb7a98506627554a33bc7e39c88f9b76

Modified Files
--------------
src/backend/commands/trigger.c | 28 +++++++++++++++++++++++-----
1 file changed, 23 insertions(+), 5 deletions(-)


pgsql-committers by date:

Previous
From: Peter Eisentraut
Date:
Subject: pgsql: pg_dump: Remove obsolete trigger support
Next
From: Michael Paquier
Date:
Subject: pgsql: Reduce dependency to money data type in main regression test sui