5544c1b
From 17df2130cd8be0cd6892b86103947746f95efc2c Mon Sep 17 00:00:00 2001
5544c1b
From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
5544c1b
Date: Mon, 20 Aug 2012 13:35:23 +0100
5544c1b
Subject: [PATCH] net: do not report queued packets as sent
5544c1b
5544c1b
Net send functions have a return value where 0 means the packet has not
5544c1b
been sent and will be queued.  A non-zero value means the packet was
5544c1b
sent or an error caused the packet to be dropped.
5544c1b
5544c1b
This patch fixes two instances where packets are queued but we return
5544c1b
their size.  This causes callers to believe the packets were sent.  When
5544c1b
the caller uses the async send interface this creates a real problem
5544c1b
because the callback will be invoked for a packet that the caller
5544c1b
believed to be already sent.  This bug can cause double-frees in the
5544c1b
caller.
5544c1b
5544c1b
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
5544c1b
(cherry picked from commit 06b5f36d052b540a59b52150582d65674199b2ce)
5544c1b
5544c1b
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
5544c1b
---
5544c1b
 net/queue.c | 35 ++++++++++++++++-------------------
5544c1b
 1 file changed, 16 insertions(+), 19 deletions(-)
5544c1b
5544c1b
diff --git a/net/queue.c b/net/queue.c
5544c1b
index 6e64091..254f280 100644
5544c1b
--- a/net/queue.c
5544c1b
+++ b/net/queue.c
5544c1b
@@ -83,12 +83,12 @@ void qemu_del_net_queue(NetQueue *queue)
5544c1b
     g_free(queue);
5544c1b
 }
5544c1b
 
5544c1b
-static ssize_t qemu_net_queue_append(NetQueue *queue,
5544c1b
-                                     NetClientState *sender,
5544c1b
-                                     unsigned flags,
5544c1b
-                                     const uint8_t *buf,
5544c1b
-                                     size_t size,
5544c1b
-                                     NetPacketSent *sent_cb)
5544c1b
+static void qemu_net_queue_append(NetQueue *queue,
5544c1b
+                                  NetClientState *sender,
5544c1b
+                                  unsigned flags,
5544c1b
+                                  const uint8_t *buf,
5544c1b
+                                  size_t size,
5544c1b
+                                  NetPacketSent *sent_cb)
5544c1b
 {
5544c1b
     NetPacket *packet;
5544c1b
 
5544c1b
@@ -100,16 +100,14 @@ static ssize_t qemu_net_queue_append(NetQueue *queue,
5544c1b
     memcpy(packet->data, buf, size);
5544c1b
 
5544c1b
     QTAILQ_INSERT_TAIL(&queue->packets, packet, entry);
5544c1b
-
5544c1b
-    return size;
5544c1b
 }
5544c1b
 
5544c1b
-static ssize_t qemu_net_queue_append_iov(NetQueue *queue,
5544c1b
-                                         NetClientState *sender,
5544c1b
-                                         unsigned flags,
5544c1b
-                                         const struct iovec *iov,
5544c1b
-                                         int iovcnt,
5544c1b
-                                         NetPacketSent *sent_cb)
5544c1b
+static void qemu_net_queue_append_iov(NetQueue *queue,
5544c1b
+                                      NetClientState *sender,
5544c1b
+                                      unsigned flags,
5544c1b
+                                      const struct iovec *iov,
5544c1b
+                                      int iovcnt,
5544c1b
+                                      NetPacketSent *sent_cb)
5544c1b
 {
5544c1b
     NetPacket *packet;
5544c1b
     size_t max_len = 0;
5544c1b
@@ -133,8 +131,6 @@ static ssize_t qemu_net_queue_append_iov(NetQueue *queue,
5544c1b
     }
5544c1b
 
5544c1b
     QTAILQ_INSERT_TAIL(&queue->packets, packet, entry);
5544c1b
-
5544c1b
-    return packet->size;
5544c1b
 }
5544c1b
 
5544c1b
 static ssize_t qemu_net_queue_deliver(NetQueue *queue,
5544c1b
@@ -177,7 +173,8 @@ ssize_t qemu_net_queue_send(NetQueue *queue,
5544c1b
     ssize_t ret;
5544c1b
 
5544c1b
     if (queue->delivering || !qemu_can_send_packet(sender)) {
5544c1b
-        return qemu_net_queue_append(queue, sender, flags, data, size, sent_cb);
5544c1b
+        qemu_net_queue_append(queue, sender, flags, data, size, sent_cb);
5544c1b
+        return 0;
5544c1b
     }
5544c1b
 
5544c1b
     ret = qemu_net_queue_deliver(queue, sender, flags, data, size);
5544c1b
@@ -201,8 +198,8 @@ ssize_t qemu_net_queue_send_iov(NetQueue *queue,
5544c1b
     ssize_t ret;
5544c1b
 
5544c1b
     if (queue->delivering || !qemu_can_send_packet(sender)) {
5544c1b
-        return qemu_net_queue_append_iov(queue, sender, flags,
5544c1b
-                                         iov, iovcnt, sent_cb);
5544c1b
+        qemu_net_queue_append_iov(queue, sender, flags, iov, iovcnt, sent_cb);
5544c1b
+        return 0;
5544c1b
     }
5544c1b
 
5544c1b
     ret = qemu_net_queue_deliver_iov(queue, sender, flags, iov, iovcnt);
5544c1b
-- 
f375e62
1.8.0.2
5544c1b