mirror of
https://github.com/postgres/postgres.git
synced 2025-07-05 07:21:24 +03:00
Fix unsafe coding in ReorderBufferCommit().
"iterstate" must be marked volatile since it's changed inside the PG_TRY block and then used in the PG_CATCH stanza. Noted by Mark Wilding of Salesforce. (We really need to see if we can't get the C compiler to warn about this.) Also, reset iterstate to NULL after the mainline ReorderBufferIterTXNFinish call, to ensure the PG_CATCH block doesn't try to do that a second time.
This commit is contained in:
@ -1258,7 +1258,7 @@ ReorderBufferCommit(ReorderBuffer *rb, TransactionId xid,
|
|||||||
TimestampTz commit_time)
|
TimestampTz commit_time)
|
||||||
{
|
{
|
||||||
ReorderBufferTXN *txn;
|
ReorderBufferTXN *txn;
|
||||||
ReorderBufferIterTXNState *iterstate = NULL;
|
ReorderBufferIterTXNState *volatile iterstate = NULL;
|
||||||
ReorderBufferChange *change;
|
ReorderBufferChange *change;
|
||||||
|
|
||||||
volatile CommandId command_id = FirstCommandId;
|
volatile CommandId command_id = FirstCommandId;
|
||||||
@ -1303,7 +1303,6 @@ ReorderBufferCommit(ReorderBuffer *rb, TransactionId xid,
|
|||||||
|
|
||||||
PG_TRY();
|
PG_TRY();
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Decoding needs access to syscaches et al., which in turn use
|
* Decoding needs access to syscaches et al., which in turn use
|
||||||
* heavyweight locks and such. Thus we need to have enough state
|
* heavyweight locks and such. Thus we need to have enough state
|
||||||
@ -1472,7 +1471,9 @@ ReorderBufferCommit(ReorderBuffer *rb, TransactionId xid,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* clean up the iterator */
|
||||||
ReorderBufferIterTXNFinish(rb, iterstate);
|
ReorderBufferIterTXNFinish(rb, iterstate);
|
||||||
|
iterstate = NULL;
|
||||||
|
|
||||||
/* call commit callback */
|
/* call commit callback */
|
||||||
rb->commit(rb, txn, commit_lsn);
|
rb->commit(rb, txn, commit_lsn);
|
||||||
@ -1639,7 +1640,7 @@ ReorderBufferForget(ReorderBuffer *rb, TransactionId xid, XLogRecPtr lsn)
|
|||||||
*/
|
*/
|
||||||
if (txn->base_snapshot != NULL && txn->ninvalidations > 0)
|
if (txn->base_snapshot != NULL && txn->ninvalidations > 0)
|
||||||
{
|
{
|
||||||
bool use_subtxn = IsTransactionOrTransactionBlock();
|
bool use_subtxn = IsTransactionOrTransactionBlock();
|
||||||
|
|
||||||
if (use_subtxn)
|
if (use_subtxn)
|
||||||
BeginInternalSubTransaction("replay");
|
BeginInternalSubTransaction("replay");
|
||||||
|
Reference in New Issue
Block a user