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.
This commit is contained in:
Eric Blake 2011-06-30 17:35:46 -06:00
parent 9e8b7c1523
commit 95eaf7ba7f

View File

@ -1294,7 +1294,8 @@ pciGetDevice(unsigned domain,
unsigned function) unsigned function)
{ {
pciDevice *dev; pciDevice *dev;
char *vendor, *product; char *vendor = NULL;
char *product = NULL;
if (VIR_ALLOC(dev) < 0) { if (VIR_ALLOC(dev) < 0) {
virReportOOMError(); virReportOOMError();
@ -1313,22 +1314,19 @@ pciGetDevice(unsigned domain,
pciReportError(VIR_ERR_INTERNAL_ERROR, pciReportError(VIR_ERR_INTERNAL_ERROR,
_("dev->name buffer overflow: %.4x:%.2x:%.2x.%.1x"), _("dev->name buffer overflow: %.4x:%.2x:%.2x.%.1x"),
dev->domain, dev->bus, dev->slot, dev->function); dev->domain, dev->bus, dev->slot, dev->function);
pciFreeDevice(dev); goto error;
return NULL;
} }
if (virAsprintf(&dev->path, PCI_SYSFS "devices/%s/config", if (virAsprintf(&dev->path, PCI_SYSFS "devices/%s/config",
dev->name) < 0) { dev->name) < 0) {
virReportOOMError(); virReportOOMError();
pciFreeDevice(dev); goto error;
return NULL;
} }
if (access(dev->path, F_OK) != 0) { if (access(dev->path, F_OK) != 0) {
virReportSystemError(errno, virReportSystemError(errno,
_("Device %s not found: could not access %s"), _("Device %s not found: could not access %s"),
dev->name, dev->path); dev->name, dev->path);
pciFreeDevice(dev); goto error;
return NULL;
} }
vendor = pciReadDeviceID(dev, "vendor"); vendor = pciReadDeviceID(dev, "vendor");
@ -1338,10 +1336,7 @@ pciGetDevice(unsigned domain,
pciReportError(VIR_ERR_INTERNAL_ERROR, pciReportError(VIR_ERR_INTERNAL_ERROR,
_("Failed to read product/vendor ID for %s"), _("Failed to read product/vendor ID for %s"),
dev->name); dev->name);
VIR_FREE(product); goto error;
VIR_FREE(vendor);
pciFreeDevice(dev);
return NULL;
} }
/* strings contain '0x' prefix */ /* strings contain '0x' prefix */
@ -1350,16 +1345,20 @@ pciGetDevice(unsigned domain,
pciReportError(VIR_ERR_INTERNAL_ERROR, pciReportError(VIR_ERR_INTERNAL_ERROR,
_("dev->id buffer overflow: %s %s"), _("dev->id buffer overflow: %s %s"),
&vendor[2], &product[2]); &vendor[2], &product[2]);
pciFreeDevice(dev); goto error;
return NULL;
} }
VIR_FREE(product);
VIR_FREE(vendor);
VIR_DEBUG("%s %s: initialized", dev->id, dev->name); VIR_DEBUG("%s %s: initialized", dev->id, dev->name);
cleanup:
VIR_FREE(product);
VIR_FREE(vendor);
return dev; return dev;
error:
pciFreeDevice(dev);
dev = NULL;
goto cleanup;
} }
void void