ofproto: Fix bad memory access sending large numbers of port stats replies.
authorBen Pfaff <blp@nicira.com>
Mon, 26 Apr 2010 22:39:52 +0000 (15:39 -0700)
committerBen Pfaff <blp@nicira.com>
Mon, 26 Apr 2010 23:19:34 +0000 (16:19 -0700)
The append_stats_reply() function can modify its pointer argument, but
append_port_stat() was failing to propagate this change back to its own
caller.  So when append_stats_reply() did in fact modify it (which happens
when the 64 kB maximum OpenFlow message length was exceeded), the
handle_port_stats_request() function would then access freed memory on the
next call to append_port_stat().

Bug #2714.
Reported-by: Ram Jothikumar <rjothikumar@nicira.com>
Debugging help by Justin Pettit <jpettit@nicira.com>

ofproto/ofproto.c

index 3f9cc90..6c93aea 100644 (file)
@@ -2760,7 +2760,7 @@ handle_table_stats_request(struct ofproto *p, struct ofconn *ofconn,
 
 static void
 append_port_stat(struct ofport *port, uint16_t port_no, struct ofconn *ofconn, 
-                 struct ofpbuf *msg)
+                 struct ofpbuf **msgp)
 {
     struct netdev_stats stats;
     struct ofp_port_stats *ops;
@@ -2770,7 +2770,7 @@ append_port_stat(struct ofport *port, uint16_t port_no, struct ofconn *ofconn,
      * netdev_get_stats() will log errors. */
     netdev_get_stats(port->netdev, &stats);
 
-    ops = append_stats_reply(sizeof *ops, ofconn, &msg);
+    ops = append_stats_reply(sizeof *ops, ofconn, msgp);
     ops->port_no = htons(odp_port_to_ofp_port(port_no));
     memset(ops->pad, 0, sizeof ops->pad);
     ops->rx_packets = htonll(stats.rx_packets);
@@ -2808,11 +2808,11 @@ handle_port_stats_request(struct ofproto *p, struct ofconn *ofconn,
         port = port_array_get(&p->ports, 
                 ofp_port_to_odp_port(ntohs(psr->port_no)));
         if (port) {
-            append_port_stat(port, ntohs(psr->port_no), ofconn, msg);
+            append_port_stat(port, ntohs(psr->port_no), ofconn, &msg);
         }
     } else {
         PORT_ARRAY_FOR_EACH (port, &p->ports, port_no) {
-            append_port_stat(port, port_no, ofconn, msg);
+            append_port_stat(port, port_no, ofconn, &msg);
         }
     }