Commit f8a4dd2e authored by Tom Lane's avatar Tom Lane

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.
parent 586dd5d6
...@@ -1258,7 +1258,7 @@ ReorderBufferCommit(ReorderBuffer *rb, TransactionId xid, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment