]> granicus.if.org Git - postgresql/commitdiff
Fix crash when reporting CREATE INDEX progress
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Wed, 16 Oct 2019 12:51:23 +0000 (14:51 +0200)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Wed, 16 Oct 2019 12:51:23 +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.GT10470@telsasoft.com

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

index a528241131061081f57a2e0ab1c9bd5927e35423..646b209b2cb0fbc7a87ef4b81b68fd45b81e597a 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 f838b0f758a33dc95d2b726e7bb10d56f529d009..889841f4cc55ae38ae50b47bf6216da22a5761e3 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++;