]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
Eliminate large stack buffer in doTunnelSendAll
authorLaine Stump <laine@laine.org>
Mon, 8 Mar 2010 14:01:52 +0000 (15:01 +0100)
committerDaniel Veillard <veillard@redhat.com>
Mon, 8 Mar 2010 14:01:52 +0000 (15:01 +0100)
doTunnelSendAll function (used by QEMU migration) uses a 64k buffer on
the stack, which could be problematic. This patch replaces that with a
buffer from the heap.

While in the neighborhood, this patch also improves error reporting in
the case that saferead fails - previously, virStreamAbort() was called
(resetting errno) before reporting the error. It's been changed to
report the error first.

* src/qemu/qemu_driver.c: fix doTunnelSendAll() to use a malloc'ed
  buffer

src/qemu/qemu_driver.c

index 79899e5b4ef984178abf03583a55afdcd9105e53..02068c46ede0d9884130a18768a7db4d55e0ccb9 100644 (file)
@@ -8654,19 +8654,28 @@ cleanup:
 }
 
 
+#define TUNNEL_SEND_BUF_SIZE 65536
+
 static int doTunnelSendAll(virStreamPtr st,
                            int sock)
 {
-    char buffer[65536];
-    int nbytes = sizeof(buffer);
+    char *buffer;
+    int nbytes = TUNNEL_SEND_BUF_SIZE;
+
+    if (VIR_ALLOC_N(buffer, TUNNEL_SEND_BUF_SIZE) < 0) {
+        virReportOOMError();
+        virStreamAbort(st);
+        return -1;
+    }
 
     /* XXX should honour the 'resource' parameter here */
     for (;;) {
         nbytes = saferead(sock, buffer, nbytes);
         if (nbytes < 0) {
-            virStreamAbort(st);
             virReportSystemError(errno, "%s",
                                  _("tunnelled migration failed to read from qemu"));
+            virStreamAbort(st);
+            VIR_FREE(buffer);
             return -1;
         }
         else if (nbytes == 0)
@@ -8676,10 +8685,13 @@ static int doTunnelSendAll(virStreamPtr st,
         if (virStreamSend(st, buffer, nbytes) < 0) {
             qemuReportError(VIR_ERR_OPERATION_FAILED, "%s",
                             _("Failed to write migration data to remote libvirtd"));
+            VIR_FREE(buffer);
             return -1;
         }
     }
 
+    VIR_FREE(buffer);
+
     if (virStreamFinish(st) < 0)
         /* virStreamFinish set the error for us */
         return -1;