Fix crash when reporting CREATE INDEX progress
authorAlvaro Herrera
Wed, 16 Oct 2019 12:51:34 +0000 (14:51 +0200)
committerAlvaro Herrera
Wed, 16 Oct 2019 12:51:34 +0000 (14:51 +0200)
A race condition can make us try to dereference a NULL pointer to the
PGPROC struct of a process that's already finished.  That results in
crashes during REINDEX CONCURRENTLY and CREATE INDEX CONCURRENTLY.

This was introduced in ab0dfc961b6a, so backpatch to pg12.

Reported by: Justin Pryzby
Reviewed-by: Michaël Paquier
Discussion: https://postgr.es/m/20191012004446[email protected]

src/backend/commands/indexcmds.c
src/backend/storage/lmgr/lmgr.c

index 70f9b6729a7d0165927eab706352b1bf57e76d73..589b8816a4d6293f5a4bd403fa91f304a018350e 100644 (file)
@@ -384,12 +384,14 @@ WaitForOlderSnapshots(TransactionId limitXmin, bool progress)
 
        if (VirtualTransactionIdIsValid(old_snapshots[i]))
        {
+           /* If requested, publish who we're going to wait for. */
            if (progress)
            {
                PGPROC     *holder = BackendIdGetProc(old_snapshots[i].backendId);
 
-               pgstat_progress_update_param(PROGRESS_WAITFOR_CURRENT_PID,
-                                            holder->pid);
+               if (holder)
+                   pgstat_progress_update_param(PROGRESS_WAITFOR_CURRENT_PID,
+                                                holder->pid);
            }
            VirtualXactLock(old_snapshots[i], true);
        }
index 4682438114655ae3104ad4ad96943a227bf5b870..1dd0e5e957687d644c71a1a187e73d876691df4f 100644 (file)
@@ -900,16 +900,14 @@ WaitForLockersMultiple(List *locktags, LOCKMODE lockmode, bool progress)
 
        while (VirtualTransactionIdIsValid(*lockholders))
        {
-           /*
-            * If requested, publish who we're going to wait for.  This is not
-            * 100% accurate if they're already gone, but we don't care.
-            */
+           /* If requested, publish who we're going to wait for. */
            if (progress)
            {
                PGPROC     *holder = BackendIdGetProc(lockholders->backendId);
 
-               pgstat_progress_update_param(PROGRESS_WAITFOR_CURRENT_PID,
-                                            holder->pid);
+               if (holder)
+                   pgstat_progress_update_param(PROGRESS_WAITFOR_CURRENT_PID,
+                                                holder->pid);
            }
            VirtualXactLock(*lockholders, true);
            lockholders++;