Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit df923be

Browse files
committed
Fix volatile-safety issue in asyncQueueReadAllNotifications().
The "pos" variable is modified within PG_TRY and then referenced within PG_CATCH, so for strict POSIX conformance it must be marked volatile. Superficially the code looked safe because pos's address was taken, which was sufficient to force it into memory ... but it's not sufficient to ensure that the compiler applies updates exactly where the program text says to. The volatility marking has to extend into a couple of subroutines too, but I think that's probably a good thing because the risk of out-of-order updates is mostly in those subroutines not asyncQueueReadAllNotifications() itself. In principle the compiler could have re-ordered operations such that an error could be thrown while "pos" had an incorrect value. It's unclear how real the risk is here, but for safety back-patch to all active branches.
1 parent f86a895 commit df923be

File tree

1 file changed

+5
-5
lines changed

1 file changed

+5
-5
lines changed

src/backend/commands/async.c

+5-5
Original file line numberDiff line numberDiff line change
@@ -369,13 +369,13 @@ static void Exec_UnlistenAllCommit(void);
369369
static bool IsListeningOn(const char *channel);
370370
static void asyncQueueUnregister(void);
371371
static bool asyncQueueIsFull(void);
372-
static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
372+
static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
373373
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
374374
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
375375
static void asyncQueueFillWarning(void);
376376
static bool SignalBackends(void);
377377
static void asyncQueueReadAllNotifications(void);
378-
static bool asyncQueueProcessPageEntries(QueuePosition *current,
378+
static bool asyncQueueProcessPageEntries(volatile QueuePosition *current,
379379
QueuePosition stop,
380380
char *page_buffer);
381381
static void asyncQueueAdvanceTail(void);
@@ -1202,7 +1202,7 @@ asyncQueueIsFull(void)
12021202
* returns true, else false.
12031203
*/
12041204
static bool
1205-
asyncQueueAdvance(QueuePosition *position, int entryLength)
1205+
asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
12061206
{
12071207
int pageno = QUEUE_POS_PAGE(*position);
12081208
int offset = QUEUE_POS_OFFSET(*position);
@@ -1792,7 +1792,7 @@ DisableNotifyInterrupt(void)
17921792
static void
17931793
asyncQueueReadAllNotifications(void)
17941794
{
1795-
QueuePosition pos;
1795+
volatile QueuePosition pos;
17961796
QueuePosition oldpos;
17971797
QueuePosition head;
17981798
bool advanceTail;
@@ -1952,7 +1952,7 @@ asyncQueueReadAllNotifications(void)
19521952
* The QueuePosition *current is advanced past all processed messages.
19531953
*/
19541954
static bool
1955-
asyncQueueProcessPageEntries(QueuePosition *current,
1955+
asyncQueueProcessPageEntries(volatile QueuePosition *current,
19561956
QueuePosition stop,
19571957
char *page_buffer)
19581958
{

0 commit comments

Comments
 (0)