bridge: Avoid use-after-free with VLAN splinters and multiple bridges.
authorBen Pfaff <blp@nicira.com>
Fri, 9 Dec 2011 23:57:55 +0000 (15:57 -0800)
committerBen Pfaff <blp@nicira.com>
Sat, 10 Dec 2011 04:47:27 +0000 (20:47 -0800)
The VLAN splinters feature uses a "pool" to track and free allocated
blocks.  There's only one pool, but the implementation was freeing all of
the blocks in it for every bridge during reconfiguration, not just once for
each reconfiguration, so caused a use-after-free when there was more than
one bridge and a bridge other than the last one in the list of bridges had
a VLAN splinter port.

Bug #8671.
Reported-by: Michael Mao <mmao@nicira.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
vswitchd/bridge.c

index f79b69cdef0b70bf3705a1027d7ffff607f8ff5b..adf01f7fe87a3e19556309e900c32d0ca6dc05ce 100644 (file)
@@ -3405,6 +3405,10 @@ collect_splinter_vlans(const struct ovsrec_open_vswitch *ovs_cfg)
     struct bridge *br;
     size_t i;
 
+    /* Free space allocated for synthesized ports and interfaces, since we're
+     * in the process of reconstructing all of them. */
+    free_registered_blocks();
+
     splinter_vlans = NULL;
     sset_init(&splinter_ifaces);
     for (i = 0; i < ovs_cfg->n_bridges; i++) {
@@ -3572,8 +3576,6 @@ add_vlan_splinter_ports(struct bridge *br,
 {
     size_t i;
 
-    free_registered_blocks();
-
     /* We iterate through 'br->cfg->ports' instead of 'ports' here because
      * we're modifying 'ports'. */
     for (i = 0; i < br->cfg->n_ports; i++) {