diff options
author | 2011-06-30 17:35:46 -0600 | |
---|---|---|
committer | 2011-07-01 16:46:20 -0600 | |
commit | 95eaf7ba7f9e46c21e8e054d7ee3bb2dfe4fa26c (patch) | |
tree | e90417d18f8eb5ae67e6a18c5a5eaaefb1785ff7 | |
parent | interface: avoid memory leak on parse error (diff) | |
download | libvirt-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.c | 31 |
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 |