Skip to content

Commit 8e6bfc9

Browse files
committed
Clear MyProc and MyProcSignalState before they become invalid.
Evidence from buildfarm member crake suggests that the new test_shm_mq module is routinely crashing the server due to the arrival of a SIGUSR1 after the shared memory segment has been unmapped. Although processes using the new dynamic background worker facilities are more likely to receive a SIGUSR1 around this time, the problem is also possible on older branches, so I'm back-patching the parts of this change that apply to older branches as far as they apply. It's already generally the case that code checks whether these pointers are NULL before deferencing them, so the important thing is mostly to make sure that they do get set to NULL before they become invalid. But in master, there's one case in procsignal_sigusr1_handler that lacks a NULL guard, so add that. Patch by me; review by Tom Lane.
1 parent af259c6 commit 8e6bfc9

File tree

2 files changed

+30
-15
lines changed

2 files changed

+30
-15
lines changed

src/backend/storage/ipc/procsignal.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,13 @@ CleanupProcSignalState(int status, Datum arg)
143143
slot = &ProcSignalSlots[pss_idx - 1];
144144
Assert(slot == MyProcSignalSlot);
145145

146+
/*
147+
* Clear MyProcSignalSlot, so that a SIGUSR1 received after this point
148+
* won't try to access it after it's no longer ours (and perhaps even
149+
* after we've unmapped the shared memory segment).
150+
*/
151+
MyProcSignalSlot = NULL;
152+
146153
/* sanity check */
147154
if (slot->pss_pid != MyProcPid)
148155
{

src/backend/storage/lmgr/proc.c

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,7 @@ ProcKill(int code, Datum arg)
701701
{
702702
/* use volatile pointer to prevent code rearrangement */
703703
volatile PROC_HDR *procglobal = ProcGlobal;
704+
PGPROC *proc;
704705

705706
Assert(MyProc != NULL);
706707

@@ -714,26 +715,29 @@ ProcKill(int code, Datum arg)
714715
*/
715716
LWLockReleaseAll();
716717

717-
/* Release ownership of the process's latch, too */
718-
DisownLatch(&MyProc->procLatch);
718+
/*
719+
* Clear MyProc first; then disown the process latch. This is so that
720+
* signal handlers won't try to clear the process latch after it's no
721+
* longer ours.
722+
*/
723+
proc = MyProc;
724+
MyProc = NULL;
725+
DisownLatch(&proc->procLatch);
719726

720727
SpinLockAcquire(ProcStructLock);
721728

722729
/* Return PGPROC structure (and semaphore) to appropriate freelist */
723730
if (IsAnyAutoVacuumProcess())
724731
{
725-
MyProc->links.next = (SHM_QUEUE *) procglobal->autovacFreeProcs;
726-
procglobal->autovacFreeProcs = MyProc;
732+
proc->links.next = (SHM_QUEUE *) procglobal->autovacFreeProcs;
733+
procglobal->autovacFreeProcs = proc;
727734
}
728735
else
729736
{
730-
MyProc->links.next = (SHM_QUEUE *) procglobal->freeProcs;
731-
procglobal->freeProcs = MyProc;
737+
proc->links.next = (SHM_QUEUE *) procglobal->freeProcs;
738+
procglobal->freeProcs = proc;
732739
}
733740

734-
/* PGPROC struct isn't mine anymore */
735-
MyProc = NULL;
736-
737741
/* Update shared estimate of spins_per_delay */
738742
procglobal->spins_per_delay = update_spins_per_delay(procglobal->spins_per_delay);
739743

@@ -762,6 +766,7 @@ AuxiliaryProcKill(int code, Datum arg)
762766
{
763767
int proctype = DatumGetInt32(arg);
764768
PGPROC *auxproc;
769+
PGPROC *proc;
765770

766771
Assert(proctype >= 0 && proctype < NUM_AUXILIARY_PROCS);
767772

@@ -772,16 +777,19 @@ AuxiliaryProcKill(int code, Datum arg)
772777
/* Release any LW locks I am holding (see notes above) */
773778
LWLockReleaseAll();
774779

775-
/* Release ownership of the process's latch, too */
776-
DisownLatch(&MyProc->procLatch);
780+
/*
781+
* Clear MyProc first; then disown the process latch. This is so that
782+
* signal handlers won't try to clear the process latch after it's no
783+
* longer ours.
784+
*/
785+
proc = MyProc;
786+
MyProc = NULL;
787+
DisownLatch(&proc->procLatch);
777788

778789
SpinLockAcquire(ProcStructLock);
779790

780791
/* Mark auxiliary proc no longer in use */
781-
MyProc->pid = 0;
782-
783-
/* PGPROC struct isn't mine anymore */
784-
MyProc = NULL;
792+
proc->pid = 0;
785793

786794
/* Update shared estimate of spins_per_delay */
787795
ProcGlobal->spins_per_delay = update_spins_per_delay(ProcGlobal->spins_per_delay);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy