Fix NULL pointer access in logical replication workers
authorPeter Eisentraut <peter_e@gmx.net>
Mon, 23 Jan 2017 17:33:27 +0000 (12:33 -0500)
committerPeter Eisentraut <peter_e@gmx.net>
Mon, 23 Jan 2017 17:33:27 +0000 (12:33 -0500)
From: Petr Jelinek <pjmodos@pjmodos.net>

src/backend/replication/logical/launcher.c
src/backend/replication/logical/worker.c

index b5240dcedeba6ddd302543f9ec96a86d54ac913f..18919724af4a0c018e88d1405c6b4fc074a0a496 100644 (file)
@@ -349,10 +349,21 @@ logicalrep_worker_stop(Oid subid)
 
        ResetLatch(&MyProc->procLatch);
 
-       /* Check if the worker has started. */
+       /* Check worker status. */
        LWLockAcquire(LogicalRepWorkerLock, LW_SHARED);
-       worker = logicalrep_worker_find(subid);
-       if (!worker || worker->proc)
+
+       /*
+        * Worker is no longer associated with subscription.  It must have
+        * exited, nothing more for us to do.
+        */
+       if (worker->subid == InvalidOid)
+       {
+           LWLockRelease(LogicalRepWorkerLock);
+           return;
+       }
+
+       /* Worker has assigned proc, so it has started. */
+       if (worker->proc)
            break;
    }
 
index 7d86736444b9125e243e206d238147d26d5843f3..3ee9cc12df04db69c2780198419258fa242ec97e 100644 (file)
@@ -1219,14 +1219,15 @@ reread_subscription(void)
    newsub = GetSubscription(MyLogicalRepWorker->subid, true);
 
    /*
-    * Exit if connection string was changed. The launcher will start
-    * new worker.
+    * Exit if the subscription was removed.
+    * This normally should not happen as the worker gets killed
+    * during DROP SUBSCRIPTION.
     */
-   if (strcmp(newsub->conninfo, MySubscription->conninfo) != 0)
+   if (!newsub)
    {
        ereport(LOG,
                (errmsg("logical replication worker for subscription \"%s\" will "
-                       "restart because the connection information was changed",
+                       "stop because the subscription was removed",
                        MySubscription->name)));
 
        walrcv_disconnect(wrconn);
@@ -1234,14 +1235,14 @@ reread_subscription(void)
    }
 
    /*
-    * Exit if publication list was changed. The launcher will start
+    * Exit if connection string was changed. The launcher will start
     * new worker.
     */
-   if (!equal(newsub->publications, MySubscription->publications))
+   if (strcmp(newsub->conninfo, MySubscription->conninfo) != 0)
    {
        ereport(LOG,
                (errmsg("logical replication worker for subscription \"%s\" will "
-                       "restart because subscription's publications were changed",
+                       "restart because the connection information was changed",
                        MySubscription->name)));
 
        walrcv_disconnect(wrconn);
@@ -1249,15 +1250,14 @@ reread_subscription(void)
    }
 
    /*
-    * Exit if the subscription was removed.
-    * This normally should not happen as the worker gets killed
-    * during DROP SUBSCRIPTION.
+    * Exit if publication list was changed. The launcher will start
+    * new worker.
     */
-   if (!newsub)
+   if (!equal(newsub->publications, MySubscription->publications))
    {
        ereport(LOG,
                (errmsg("logical replication worker for subscription \"%s\" will "
-                       "stop because the subscription was removed",
+                       "restart because subscription's publications were changed",
                        MySubscription->name)));
 
        walrcv_disconnect(wrconn);