aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2022-09-28 11:23:14 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2022-09-28 11:23:27 -0400
commit4d2a844242dcfb34e05dd0d880b1a283a514b16b (patch)
treede19f6f2c55ebca0a91a7abd17d38f74b839236d /src/backend/access
parentd84a7b290f866b3f16cbefb0fca31b69ebace98a (diff)
downloadpostgresql-4d2a844242dcfb34e05dd0d880b1a283a514b16b.tar.gz
postgresql-4d2a844242dcfb34e05dd0d880b1a283a514b16b.zip
Allow callback functions to deregister themselves during a call.
Fetch the next-item pointer before the call not after, so that we aren't dereferencing a dangling pointer if the callback deregistered itself during the call. The risky coding pattern appears in CallXactCallbacks, CallSubXactCallbacks, and ResourceOwnerReleaseInternal. (There are some other places that might be at hazard if they offered deregistration functionality, but they don't.) I (tgl) considered back-patching this, but desisted because it wouldn't be very safe for extensions to rely on this working in pre-v16 branches. Hao Wu Discussion: https://postgr.es/m/CAH+9SWXTiERkmhRke+QCcc+jRH8d5fFHTxh8ZK0-Yn4BSpyaAg@mail.gmail.com
Diffstat (limited to 'src/backend/access')
-rw-r--r--src/backend/access/transam/xact.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index 2bb975943cf..c1ffbd89b88 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -3656,9 +3656,14 @@ static void
CallXactCallbacks(XactEvent event)
{
XactCallbackItem *item;
+ XactCallbackItem *next;
- for (item = Xact_callbacks; item; item = item->next)
+ for (item = Xact_callbacks; item; item = next)
+ {
+ /* allow callbacks to unregister themselves when called */
+ next = item->next;
item->callback(event, item->arg);
+ }
}
@@ -3713,9 +3718,14 @@ CallSubXactCallbacks(SubXactEvent event,
SubTransactionId parentSubid)
{
SubXactCallbackItem *item;
+ SubXactCallbackItem *next;
- for (item = SubXact_callbacks; item; item = item->next)
+ for (item = SubXact_callbacks; item; item = next)
+ {
+ /* allow callbacks to unregister themselves when called */
+ next = item->next;
item->callback(event, mySubid, parentSubid, item->arg);
+ }
}