mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-23 14:15:28 +00:00
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:
parent
9e8b7c1523
commit
95eaf7ba7f
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user