From d0c7cf31a72278dceab554fb3ba60ff84cf7d8f0 Mon Sep 17 00:00:00 2001 From: "Chao Li (Evan)" Date: Fri, 24 Jul 2026 11:22:41 +0800 Subject: [PATCH v1] Protect PGPROC lookup when terminating background workers TerminateBackgroundWorkersForDatabase() used BackendPidGetProc() and accessed the returned PGPROC after ProcArrayLock had been released. The PGPROC could be recycled in the meantime, causing the database ID of another process to be examined. Hold ProcArrayLock while looking up the process with BackendPidGetProcWithLock() and checking its database ID. Also save the worker PID locally so that the lookup and log message use the same value if the postmaster updates the background worker slot concurrently. This issue was introduced by f1e251be8. Author: Chao Li --- src/backend/postmaster/bgworker.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/backend/postmaster/bgworker.c b/src/backend/postmaster/bgworker.c index f2cffce3ff6..230cec47818 100644 --- a/src/backend/postmaster/bgworker.c +++ b/src/backend/postmaster/bgworker.c @@ -1442,16 +1442,24 @@ TerminateBackgroundWorkersForDatabase(Oid databaseId) if (slot->in_use && (slot->worker.bgw_flags & BGWORKER_INTERRUPTIBLE)) { - PGPROC *proc = BackendPidGetProc(slot->pid); + PGPROC *proc; + pid_t pid; + bool terminate = false; + LWLockAcquire(ProcArrayLock, LW_SHARED); + pid = slot->pid; + proc = BackendPidGetProcWithLock(pid); if (proc && proc->databaseId == databaseId) { slot->terminate = true; signal_postmaster = true; + terminate = true; + } + LWLockRelease(ProcArrayLock); + if (terminate) elog(DEBUG1, "termination requested for worker (PID %d) on database %u", - (int) slot->pid, databaseId); - } + (int) pid, databaseId); } } -- 2.50.1 (Apple Git-155)