Fix rare core dump in BackendIdGetTransactionIds().
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 30 Mar 2015 17:05:27 +0000 (13:05 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 30 Mar 2015 17:05:27 +0000 (13:05 -0400)
BackendIdGetTransactionIds() neglected the possibility that the PROC
pointer in a ProcState array entry is null.  In current usage, this could
only crash if the other backend had exited since pgstat_read_current_status
saw it as active, which is a pretty narrow window.  But it's reachable in
the field, per bug #12918 from Vladimir Borodin.

Back-patch to 9.4 where the faulty code was introduced.

src/backend/storage/ipc/sinvaladt.c

index 81b85c0e42009b51ae5628a8ceaca5d919fe8f97..a2fde89b526b96e926b23f34a1092d77a3bb155b 100644 (file)
@@ -403,9 +403,7 @@ BackendIdGetProc(int backendID)
 void
 BackendIdGetTransactionIds(int backendID, TransactionId *xid, TransactionId *xmin)
 {
-       ProcState  *stateP;
        SISeg      *segP = shmInvalBuffer;
-       PGXACT     *xact;
 
        *xid = InvalidTransactionId;
        *xmin = InvalidTransactionId;
@@ -415,11 +413,16 @@ BackendIdGetTransactionIds(int backendID, TransactionId *xid, TransactionId *xmi
 
        if (backendID > 0 && backendID <= segP->lastBackend)
        {
-               stateP = &segP->procState[backendID - 1];
-               xact = &ProcGlobal->allPgXact[stateP->proc->pgprocno];
+               ProcState  *stateP = &segP->procState[backendID - 1];
+               PGPROC     *proc = stateP->proc;
 
-               *xid = xact->xid;
-               *xmin = xact->xmin;
+               if (proc != NULL)
+               {
+                       PGXACT     *xact = &ProcGlobal->allPgXact[proc->pgprocno];
+
+                       *xid = xact->xid;
+                       *xmin = xact->xmin;
+               }
        }
 
        LWLockRelease(SInvalWriteLock);