From c6a4d268af848cb8e4b1772a616c8c7221bcc1e5 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Tue, 22 Jul 2014 22:38:30 -0600 Subject: [PATCH] nodedev: fix pci express memory leak Leak introduced in commit 16ebf10f (v1.2.6), detected by valgrind: ==9816== 216 (96 direct, 120 indirect) bytes in 6 blocks are definitely lost in loss record 665 of 821 ==9816== at 0x4A081D4: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) ==9816== by 0x50836FB: virAlloc (viralloc.c:144) ==9816== by 0x1DBDBE27: udevProcessPCI (node_device_udev.c:546) ==9816== by 0x1DBDD79D: udevGetDeviceDetails (node_device_udev.c:1293) * src/util/virpci.h (virPCIEDeviceInfoFree): New prototype. * src/util/virpci.c (virPCIEDeviceInfoFree): New function. * src/conf/node_device_conf.c (virNodeDevCapsDefFree): Clear pci_express under pci case. (virNodeDevCapPCIDevParseXML): Avoid leak. * src/node_device/node_device_udev.c (udevProcessPCI): Likewise. * src/libvirt_private.syms (virpci.h): Export it. Signed-off-by: Eric Blake --- src/conf/node_device_conf.c | 3 ++- src/libvirt_private.syms | 1 + src/node_device/node_device_udev.c | 2 +- src/util/virpci.c | 12 ++++++++++++ src/util/virpci.h | 3 +++ 5 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index b244a1f0c8..78bc63f13d 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -1291,7 +1291,7 @@ virNodeDevCapPCIDevParseXML(xmlXPathContextPtr ctxt, ret = 0; out: - VIR_FREE(pci_express); + virPCIEDeviceInfoFree(pci_express); ctxt->node = orignode; return ret; } @@ -1664,6 +1664,7 @@ void virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps) VIR_FREE(data->pci_dev.iommuGroupDevices[i]); } VIR_FREE(data->pci_dev.iommuGroupDevices); + virPCIEDeviceInfoFree(data->pci_dev.pci_express); break; case VIR_NODE_DEV_CAP_USB_DEV: VIR_FREE(data->usb_dev.product_name); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index b1fb7c9443..cafe86689d 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1753,6 +1753,7 @@ virPCIDeviceSetUnbindFromStub; virPCIDeviceSetUsedBy; virPCIDeviceUnbind; virPCIDeviceWaitForCleanup; +virPCIEDeviceInfoFree; virPCIGetNetName; virPCIGetPhysicalFunction; virPCIGetVirtualFunctionIndex; diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c index 28d2953e66..0fe474d4e3 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -570,7 +570,7 @@ static int udevProcessPCI(struct udev_device *device, out: virPCIDeviceFree(pciDev); - VIR_FREE(pci_express); + virPCIEDeviceInfoFree(pci_express); return ret; } diff --git a/src/util/virpci.c b/src/util/virpci.c index b7400e994f..0098d6c472 100644 --- a/src/util/virpci.c +++ b/src/util/virpci.c @@ -2847,3 +2847,15 @@ virPCIDeviceGetLinkCapSta(virPCIDevicePtr dev, virPCIDeviceConfigClose(dev, fd); return ret; } + + +void +virPCIEDeviceInfoFree(virPCIEDeviceInfoPtr dev) +{ + if (!dev) + return; + + VIR_FREE(dev->link_cap); + VIR_FREE(dev->link_sta); + VIR_FREE(dev); +} diff --git a/src/util/virpci.h b/src/util/virpci.h index 3d274878e1..1ce9821e00 100644 --- a/src/util/virpci.h +++ b/src/util/virpci.h @@ -212,4 +212,7 @@ int virPCIDeviceGetLinkCapSta(virPCIDevicePtr dev, unsigned int *cap_width, unsigned int *sta_speed, unsigned int *sta_width); + +void virPCIEDeviceInfoFree(virPCIEDeviceInfoPtr dev); + #endif /* __VIR_PCI_H__ */