Switch memory contexts in ReinitializeParallelDSM. REL_17_STABLE github/REL_17_STABLE
authorRobert Haas <[email protected]>
Tue, 16 Dec 2025 15:40:53 +0000 (10:40 -0500)
committerRobert Haas <[email protected]>
Tue, 16 Dec 2025 15:59:04 +0000 (10:59 -0500)
We already do this in CreateParallelContext, InitializeParallelDSM, and
LaunchParallelWorkers. I suspect the reason why the matching logic was
omitted from ReinitializeParallelDSM is that I failed to realize that
any memory allocation was happening here -- but shm_mq_attach does
allocate, which could result in a shm_mq_handle being allocated in a
shorter-lived context than the ParallelContext which points to it.

That could result in a crash if the shorter-lived context is freed
before the parallel context is destroyed. As far as I am currently
aware, there is no way to reach a crash using only code that is
present in core PostgreSQL, but extensions could potentially trip
over this. Fixing this in the back-branches appears low-risk, so
back-patch to all supported versions.

Author: Jakub Wartak <[email protected]>
Co-authored-by: Jeevan Chalke <[email protected]>
Backpatch-through: 14
Discussion: http://postgr.es/m/CAKZiRmwfVripa3FGo06=5D1EddpsLu9JY2iJOTgbsxUQ339ogQ@mail.gmail.com

src/backend/access/transam/parallel.c

index d0ad0bd4280cd77c328218224078611dfa4282d4..2c07621d5cd90fa8ddc6f384b813ee77046a951b 100644 (file)
@@ -503,8 +503,12 @@ InitializeParallelDSM(ParallelContext *pcxt)
 void
 ReinitializeParallelDSM(ParallelContext *pcxt)
 {
+   MemoryContext oldcontext;
    FixedParallelState *fps;
 
+   /* We might be running in a very short-lived memory context. */
+   oldcontext = MemoryContextSwitchTo(TopTransactionContext);
+
    /* Wait for any old workers to exit. */
    if (pcxt->nworkers_launched > 0)
    {
@@ -542,6 +546,9 @@ ReinitializeParallelDSM(ParallelContext *pcxt)
            pcxt->worker[i].error_mqh = shm_mq_attach(mq, pcxt->seg, NULL);
        }
    }
+
+   /* Restore previous memory context. */
+   MemoryContextSwitchTo(oldcontext);
 }
 
 /*