vport: Make dp_port->vport always valid.
authorJesse Gross <jesse@nicira.com>
Thu, 29 Jul 2010 22:59:31 +0000 (15:59 -0700)
committerJesse Gross <jesse@nicira.com>
Fri, 30 Jul 2010 20:42:26 +0000 (13:42 -0700)
When we detached a vport we would assign NULL to dp_port->vport
before calling synchronize_rcu().  However, since vports have a
longer lifetime than dp_ports there were no checks before
dereferencing dp_port->vport.  This changes the behavior to
match the assumption by not assigning NULL during detach.  This
avoids a potential NULL pointer dereference in do_output() among
other places.

datapath/datapath.c
datapath/vport.c

index 73f734801760d3fc491c9f9160371322d26c1d8a..d0db55078237ff8d7ececbbb5ab1703e9f9f415d 100644 (file)
@@ -377,6 +377,7 @@ static int new_dp_port(struct datapath *dp, struct odp_port *odp_port, int port_
 
        p->port_no = port_no;
        p->dp = dp;
+       p->vport = vport;
        atomic_set(&p->sflow_pool, 0);
 
        err = vport_attach(vport, p);
index 712c26e5d3ddae51386433bc437df41573aa9e07..2438590105c28b85d497159faa955f83dbf8b8c5 100644 (file)
@@ -798,9 +798,6 @@ int vport_attach(struct vport *vport, struct dp_port *dp_port)
 {
        ASSERT_RTNL();
 
-       if (dp_port->vport)
-               return -EBUSY;
-
        if (vport_get_dp_port(vport))
                return -EBUSY;
 
@@ -812,7 +809,6 @@ int vport_attach(struct vport *vport, struct dp_port *dp_port)
                        return err;
        }
 
-       dp_port->vport = vport;
        rcu_assign_pointer(vport->dp_port, dp_port);
 
        return 0;
@@ -836,7 +832,6 @@ int vport_detach(struct vport *vport)
        if (!dp_port)
                return -EINVAL;
 
-       dp_port->vport = NULL;
        rcu_assign_pointer(vport->dp_port, NULL);
 
        if (vport->ops->detach)