ovs-ofctl: Fix use-after-free error.
authorBen Pfaff <blp@nicira.com>
Mon, 16 Jul 2012 17:23:58 +0000 (10:23 -0700)
committerBen Pfaff <blp@nicira.com>
Mon, 16 Jul 2012 20:58:35 +0000 (13:58 -0700)
Commit 4ce9c31573 (ovs-ofctl: Factor code out of read_flows_from_switch().)
introduced a use-after-free error, fixed by this change.

Also adds a unit test for "ovs-ofctl diff-flows" that would have found the
problem.  (The bug report cited "diff-flows" but this bug was present in
dump-flows as well because they share common code.)

Bug #12461.
Reported-by: James Schmidt <jschmidt@nicira.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
tests/ovs-ofctl.at
utilities/ovs-ofctl.c

index d456734b6b36094ed28324b44b85e8a2e35ff327..7233a66932a7712e7ddcaafddce1136219e6fc9a 100644 (file)
@@ -1446,3 +1446,35 @@ AT_CHECK(
 ])
 OVS_VSWITCHD_STOP
 AT_CLEANUP
+
+AT_SETUP([ovs-ofctl diff-flows])
+OVS_VSWITCHD_START
+
+# Prints the integers from $1 to $2, increasing by $3 (default 1) on stdout.
+seq () {
+    while test $1 -le $2; do
+        echo $1
+        set `expr $1 + ${3-1}` $2 $3
+    done
+}
+
+# Add tons of flows to br0.
+for i in `seq 0 1023`; do echo "dl_vlan=$i,actions=drop"; done > add-flows.txt
+AT_CHECK([ovs-ofctl add-flows br0 add-flows.txt])
+
+# Dump them and compare against what we expect by hand, then with diff-flows.
+for i in `seq 0 1023`; do echo " dl_vlan=$i actions=drop"; done | sort > expout
+AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sed '/NXST_FLOW/d' | sort],
+  [0], [expout])
+AT_CHECK([ovs-ofctl diff-flows br0 add-flows.txt])
+
+# Remove even-numbered flows, compare again.
+for i in `seq 0 1023 2`; do echo "dl_vlan=$i"; done > del-flows.txt
+AT_CHECK([ovs-ofctl del-flows br0 - < del-flows.txt])
+for i in `seq 0 1023 2`; do echo "+dl_vlan=$i actions=drop"; done | sort > expout
+AT_CHECK([ovs-ofctl diff-flows br0 add-flows.txt | sort], [0], [expout])
+for i in `seq 0 1023 2`; do echo "-dl_vlan=$i actions=drop"; done | sort > expout
+AT_CHECK([ovs-ofctl diff-flows add-flows.txt br0 | sort], [0], [expout])
+
+OVS_VSWITCHD_STOP
+AT_CLEANUP
index f925d846fab3bc66374c1a518de4bb99a14252c2..4ad1acb4d499c4cd99fba794149bfafe41e4d837 100644 (file)
@@ -1903,6 +1903,7 @@ recv_flow_stats_reply(struct vconn *vconn, ovs_be32 send_xid,
         case EOF:
             flags = ((const struct ofp_stats_msg *) reply->l2)->flags;
             ofpbuf_delete(reply);
+            reply = NULL;
             if (!(flags & htons(OFPSF_REPLY_MORE))) {
                 *replyp = NULL;
                 return false;