On 08/02/2011 05:46 PM, Eric Blake wrote:
Quite a few leaks detected by coverity.  For chr, the leaks were
close enough to the allocations to plug in place; for disk, the
leaks were separated from the allocation by enough other lines with
intermediate failure cases that I refactored the cleanup instead.

Sorry, two more problems I didn't notice before:

1) instead of VIR_FREE(disk) down at the bottom, you should be calling virDomainDiskDefFree()

2) There are some places in that qemuParseCommandLine where virDomainDiskDefFree() is called right before goto no_memory (or goto error), but since virDomainDiskDefFree() doesn't/can't set disk to NULL, you'll end up with a double free.


* src/qemu/qemu_command.c (qemuParseCommandLine): Plug leaks.
---

v2: address review comments from v1

  src/qemu/qemu_command.c |   27 +++++++++++++++++----------
  1 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 6a2e2ae..194f3ff 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5938,6 +5938,7 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
      int video = VIR_DOMAIN_VIDEO_TYPE_CIRRUS;
      int nvirtiodisk = 0;
      qemuDomainCmdlineDefPtr cmd = NULL;
+    virDomainDiskDefPtr disk = NULL;

      if (pidfile)
          *pidfile = NULL;
@@ -6124,7 +6125,6 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
                     STRPREFIX(arg, "-fd") ||
                     STREQ(arg, "-cdrom")) {
              WANT_VALUE();
-            virDomainDiskDefPtr disk;
              if (VIR_ALLOC(disk)<  0)
                  goto no_memory;

@@ -6239,6 +6239,7 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
                  goto no_memory;
              }
              def->disks[def->ndisks++] = disk;
+            disk = NULL;
          } else if (STREQ(arg, "-no-acpi")) {
              def->features&= ~(1<<  VIR_DOMAIN_FEATURE_ACPI);
          } else if (STREQ(arg, "-no-reboot")) {
@@ -6307,8 +6308,10 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
                  if (!(chr = virDomainChrDefNew()))
                      goto error;

-                if (qemuParseCommandLineChr(&chr->source, val)<  0)
+                if (qemuParseCommandLineChr(&chr->source, val)<  0) {
+                    virDomainChrDefFree(chr);
                      goto error;
+                }
                  if (VIR_REALLOC_N(def->serials, def->nserials+1)<  0) {
                      virDomainChrDefFree(chr);
                      goto no_memory;
@@ -6325,8 +6328,10 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
                  if (!(chr = virDomainChrDefNew()))
                      goto error;

-                if (qemuParseCommandLineChr(&chr->source, val)<  0)
+                if (qemuParseCommandLineChr(&chr->source, val)<  0) {
+                    virDomainChrDefFree(chr);
                      goto error;
+                }
                  if (VIR_REALLOC_N(def->parallels, def->nparallels+1)<  0) {
                      virDomainChrDefFree(chr);
                      goto no_memory;
@@ -6353,7 +6358,6 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
                  }
                  def->inputs[def->ninputs++] = input;
              } else if (STRPREFIX(val, "disk:")) {
-                virDomainDiskDefPtr disk;
                  if (VIR_ALLOC(disk)<  0)
                      goto no_memory;
                  disk->src = strdup(val + strlen("disk:"));
@@ -6376,6 +6380,7 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
                      goto no_memory;
                  }
                  def->disks[def->ndisks++] = disk;
+                disk = NULL;
              } else {
                  virDomainHostdevDefPtr hostdev;
                  if (!(hostdev = qemuParseCommandLineUSB(val)))
@@ -6399,7 +6404,6 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
                  def->nets[def->nnets++] = net;
              }
          } else if (STREQ(arg, "-drive")) {
-            virDomainDiskDefPtr disk;
              WANT_VALUE();
              if (!(disk = qemuParseCommandLineDisk(caps, val, nvirtiodisk)))
                  goto error;
@@ -6408,6 +6412,7 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
                  goto no_memory;
              }
              def->disks[def->ndisks++] = disk;
+            disk = NULL;

              if (disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO)
                  nvirtiodisk++;
@@ -6516,8 +6521,10 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
                  if (VIR_ALLOC(chr)<  0)
                      goto no_memory;

-                if (qemuParseCommandLineChr(chr, val)<  0)
+                if (qemuParseCommandLineChr(chr, val)<  0) {
+                    virDomainChrSourceDefFree(chr);
                      goto error;
+                }

                  *monConfig = chr;
              }
@@ -6545,10 +6552,9 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
              char *hosts, *port, *saveptr = NULL, *token;
              virDomainDiskDefPtr first_rbd_disk = NULL;
              for (i = 0 ; i<  def->ndisks ; i++) {
-                virDomainDiskDefPtr disk = def->disks[i];
-                if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK&&
-                    disk->protocol == VIR_DOMAIN_DISK_PROTOCOL_RBD) {
-                    first_rbd_disk = disk;
+                if (def->disks[i]->type == VIR_DOMAIN_DISK_TYPE_NETWORK&&
+                    def->disks[i]->protocol == VIR_DOMAIN_DISK_PROTOCOL_RBD) {
+                    first_rbd_disk = def->disks[i];
                      break;
                  }
              }
@@ -6676,6 +6682,7 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
  no_memory:
      virReportOOMError();
  error:
+    VIR_FREE(disk);
      VIR_FREE(cmd);
      virDomainDefFree(def);
      VIR_FREE(nics);

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to