Skip to content

Commit 780a7dc

Browse files
committed
Fix possible corruption of AfterTriggerEventLists in subtransaction rollback.
afterTriggerInvokeEvents failed to adjust events->tailfree when truncating the last chunk of an event list. This could result in the data being "de-truncated" by afterTriggerRestoreEventList during a subsequent subtransaction abort. Even that wouldn't kill us, because the re-added data would just be events marked DONE --- unless the data had been partially overwritten by new events. Then we might crash, or in any case misbehave (perhaps fire triggers twice, or fire triggers with the wrong event data). Per bug #5622 from Thue Janus Kristensen. Back-patch to 8.4 where the current trigger list representation was introduced.
1 parent 205fc92 commit 780a7dc

File tree

1 file changed

+11
-1
lines changed

1 file changed

+11
-1
lines changed

src/backend/commands/trigger.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.262 2010/02/26 02:00:39 momjian Exp $
10+
* $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.262.4.1 2010/08/19 15:46:24 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -2928,6 +2928,7 @@ afterTriggerAddEvent(AfterTriggerEventList *events,
29282928
else
29292929
events->tail->next = chunk;
29302930
events->tail = chunk;
2931+
/* events->tailfree is now out of sync, but we'll fix it below */
29312932
}
29322933

29332934
/*
@@ -3329,6 +3330,15 @@ afterTriggerInvokeEvents(AfterTriggerEventList *events,
33293330
{
33303331
chunk->freeptr = CHUNK_DATA_START(chunk);
33313332
chunk->endfree = chunk->endptr;
3333+
3334+
/*
3335+
* If it's last chunk, must sync event list's tailfree too. Note
3336+
* that delete_ok must NOT be passed as true if there could be
3337+
* stacked AfterTriggerEventList values pointing at this event
3338+
* list, since we'd fail to fix their copies of tailfree.
3339+
*/
3340+
if (chunk == events->tail)
3341+
events->tailfree = chunk->freeptr;
33323342
}
33333343
}
33343344

0 commit comments

Comments
 (0)