aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Blake <eblake@redhat.com>2011-06-30 17:35:46 -0600
committerEric Blake <eblake@redhat.com>2011-07-01 16:46:20 -0600
commit95eaf7ba7f9e46c21e8e054d7ee3bb2dfe4fa26c (patch)
treee90417d18f8eb5ae67e6a18c5a5eaaefb1785ff7
parentinterface: avoid memory leak on parse error (diff)
downloadlibvirt-95eaf7ba7f9e46c21e8e054d7ee3bb2dfe4fa26c.tar.gz
libvirt-95eaf7ba7f9e46c21e8e054d7ee3bb2dfe4fa26c.tar.bz2
libvirt-95eaf7ba7f9e46c21e8e054d7ee3bb2dfe4fa26c.zip
pci: avoid memory leak on error
Detected by Coverity. Some, but not all, error paths were clean; but they were repetitive so I refactored them. * src/util/pci.c (pciGetDevice): Plug leak.
-rw-r--r--src/util/pci.c31
1 files changed, 15 insertions, 16 deletions
diff --git a/src/util/pci.c b/src/util/pci.c
index 46a3a835d..21c12b97b 100644
--- a/src/util/pci.c
+++ b/src/util/pci.c
@@ -1294,7 +1294,8 @@ pciGetDevice(unsigned domain,
unsigned function)
{
pciDevice *dev;
- char *vendor, *product;
+ char *vendor = NULL;
+ char *product = NULL;
if (VIR_ALLOC(dev) < 0) {
virReportOOMError();
@@ -1313,22 +1314,19 @@ pciGetDevice(unsigned domain,
pciReportError(VIR_ERR_INTERNAL_ERROR,
_("dev->name buffer overflow: %.4x:%.2x:%.2x.%.1x"),
dev->domain, dev->bus, dev->slot, dev->function);
- pciFreeDevice(dev);
- return NULL;
+ goto error;
}
if (virAsprintf(&dev->path, PCI_SYSFS "devices/%s/config",
dev->name) < 0) {
virReportOOMError();
- pciFreeDevice(dev);
- return NULL;
+ goto error;
}
if (access(dev->path, F_OK) != 0) {
virReportSystemError(errno,
_("Device %s not found: could not access %s"),
dev->name, dev->path);
- pciFreeDevice(dev);
- return NULL;
+ goto error;
}
vendor = pciReadDeviceID(dev, "vendor");
@@ -1338,10 +1336,7 @@ pciGetDevice(unsigned domain,
pciReportError(VIR_ERR_INTERNAL_ERROR,
_("Failed to read product/vendor ID for %s"),
dev->name);
- VIR_FREE(product);
- VIR_FREE(vendor);
- pciFreeDevice(dev);
- return NULL;
+ goto error;
}
/* strings contain '0x' prefix */
@@ -1350,16 +1345,20 @@ pciGetDevice(unsigned domain,
pciReportError(VIR_ERR_INTERNAL_ERROR,
_("dev->id buffer overflow: %s %s"),
&vendor[2], &product[2]);
- pciFreeDevice(dev);
- return NULL;
+ goto error;
}
- VIR_FREE(product);
- VIR_FREE(vendor);
-
VIR_DEBUG("%s %s: initialized", dev->id, dev->name);
+cleanup:
+ VIR_FREE(product);
+ VIR_FREE(vendor);
return dev;
+
+error:
+ pciFreeDevice(dev);
+ dev = NULL;
+ goto cleanup;
}
void