dpif-linux: Recheck the socket pointer existence before getting its pid.
authorAlex Wang <alexw@nicira.com>
Tue, 8 Jul 2014 04:58:33 +0000 (21:58 -0700)
committerAlex Wang <alexw@nicira.com>
Tue, 8 Jul 2014 05:12:22 +0000 (22:12 -0700)
This commit fixes a race between port deletion and flow miss handling.
More specifically, a port could be removed by main thread while
the handler thread is handling the flow miss from it.  If the flow
requires slow path action, the handler thread will try querying a pid
from port's socket.  Since the port has been deleted, the query will
cause a dereference of NULL socket pointer.

This commit makes the handler thread recheck the socket pointer before
dereferencing it.

VMware-BZ: 1251981

Reported-by: Pratap Reddy <preddy@nicira.com>
Signed-off-by: Alex Wang <alexw@nicira.com>
Acked-by: Joe Stringer <joestringer@nicira.com>
lib/dpif-linux.c

index 93154a3..a10be60 100644 (file)
@@ -825,7 +825,13 @@ dpif_linux_port_get_pid__(const struct dpif_linux *dpif, odp_port_t port_no,
         uint32_t idx = port_idx >= dpif->uc_array_size ? 0 : port_idx;
         struct dpif_handler *h = &dpif->handlers[hash % dpif->n_handlers];
 
-        pid = nl_sock_pid(h->channels[idx].sock);
+        /* Needs to check in case the socket pointer is changed in between
+         * the holding of upcall_lock.  A known case happens when the main
+         * thread deletes the vport while the handler thread is handling
+         * the upcall from that port. */
+        if (h->channels[idx].sock) {
+            pid = nl_sock_pid(h->channels[idx].sock);
+        }
     }
 
     return pid;