From: wangjian Date: Fri, 26 Mar 2021 03:21:16 +0000 (+0800) Subject: node_device_udev: Serialize access to pci_get_strings)_ X-Git-Tag: v7.2.0-rc1~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=59788a5caea5f292c86e07a31ee2b853d68db87e;p=thirdparty%2Flibvirt.git node_device_udev: Serialize access to pci_get_strings)_ Since the functions provided by libpciaccess are not thread-safe, when the udev-event and nodedev-init threads of libvirt call the pci_get_strings function provided by libpaciaccess at the same time the following can happen: nodedev-init thread: nodeStateInitializeEnumerate -> udevEnumerateDevices-> udevProcessDeviceListEntry -> udevAddOneDevice -> udevGetDeviceDetails-> udevProcessPCI -> udevTranslatePCIIds -> pci_get_strings -> (libpciaccess) find_device_name -> populate_vendor -> d = realloc( vend->devices, (vend->num_devices + 1), * sizeof( struct pci_device_leaf ) ); vend->num_devices++; udev-event thread: udevEventHandleThread -> udevHandleOneDevice -> udevAddOneDevice-> udevGetDeviceDetails-> udevProcessPCI -> udevTranslatePCIIds -> pci_get_strings -> (libpciaccess) find_device_name -> populate_vendor -> d = realloc( vend->devices, (vend->num_devices + 1), * sizeof( struct pci_device_leaf ) ); vend->num_devices++; Signed-off-by: WangJian Signed-off-by: Michal Privoznik Reviewed-by: Michal Privoznik --- diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c index 3f288589db..3daa5c90ad 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -331,6 +331,7 @@ udevGenerateDeviceName(struct udev_device *device, return 0; } +static virMutex pciaccessMutex = VIR_MUTEX_INITIALIZER; static int udevTranslatePCIIds(unsigned int vendor, @@ -349,12 +350,14 @@ udevTranslatePCIIds(unsigned int vendor, m.device_class_mask = 0; m.match_data = 0; - /* pci_get_strings returns void */ + /* pci_get_strings returns void and unfortunately is not thread safe. */ + virMutexLock(&pciaccessMutex); pci_get_strings(&m, &device_name, &vendor_name, NULL, NULL); + virMutexUnlock(&pciaccessMutex); *vendor_string = g_strdup(vendor_name); *product_string = g_strdup(device_name);