From: Peter Krempa <[email protected]> A special case in qemuDomainAttachDeviceDiskLive causes disk media to be changed. This code has different semantics than the real hotplug code where the hotplugged device definition is absorbed into the domain definition and thus the pointer is still valid. On media change we just use the disk source and discard everything else from the disk definition.
Later in qemuDomainAttachDeviceLive we then attempt to extract the alias of the attached device for emiting an event. Since in case of media change the main definition was freed this causes an use-after-free on the disk data pointer. To address this the media change code will clear the disk definition pointer from the device wrapper and the caller will extract the device alias only when the disk definition pointer is non-NULL. The semantics of the event will not change because the device alias wouldn't be assigned for the media change code at all. The use-after-free is observable via valgrind when attempting a media change via 'virsh attach-device', as otherwise in most cases it doesn't cause any ill efect as only the pointer to a NULL string is accessed: ==2763495== Invalid read of size 8 ==2763495== at 0xEA4102A: qemuDomainAttachDeviceLive (qemu_hotplug.c:3455) ==2763495== by 0xEA28ECD: qemuDomainAttachDeviceLiveAndConfig (qemu_driver.c:7408) ==2763495== by 0xEA28ECD: qemuDomainAttachDeviceFlags (qemu_driver.c:7456) ==2763495== by 0x4BC5BE6: virDomainAttachDevice (libvirt-domain.c:8951) ==2763495== by 0x402579D: remoteDispatchDomainAttachDevice (remote_daemon_dispatch_stubs.h:3763) [snip] ==2763495== Address 0x6df57c8 is 360 bytes inside a block of size 608 free'd ==2763495== at 0x48F7E43: free (vg_replace_malloc.c:990) ==2763495== by 0x4EC7EC4: g_free (in /usr/lib64/libglib-2.0.so.0.8600.3) ==2763495== by 0xEA4101E: qemuDomainAttachDeviceDiskLive (qemu_hotplug.c:1150) ==2763495== by 0xEA4101E: qemuDomainAttachDeviceLive (qemu_hotplug.c:3453) ==2763495== by 0xEA28ECD: qemuDomainAttachDeviceLiveAndConfig (qemu_driver.c:7408) ==2763495== by 0xEA28ECD: qemuDomainAttachDeviceFlags (qemu_driver.c:7456) ==2763495== by 0x4BC5BE6: virDomainAttachDevice (libvirt-domain.c:8951) [snip] Closes: https://gitlab.com/libvirt/libvirt/-/issues/859 Signed-off-by: Peter Krempa <[email protected]> --- src/qemu/qemu_hotplug.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 6235f6c27c..df4bb49af7 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1146,7 +1146,7 @@ qemuDomainAttachDeviceDiskLive(virQEMUDriver *driver, return -1; dev->data.disk->src = NULL; - virDomainDiskDefFree(dev->data.disk); + g_clear_pointer(&dev->data.disk, virDomainDiskDefFree); return 0; } @@ -3450,7 +3450,7 @@ qemuDomainAttachDeviceLive(virDomainObj *vm, case VIR_DOMAIN_DEVICE_DISK: qemuDomainObjCheckDiskTaint(driver, vm, dev->data.disk, NULL); ret = qemuDomainAttachDeviceDiskLive(driver, vm, dev); - if (!ret) { + if (ret == 0 && dev->data.disk) { alias = dev->data.disk->info.alias; dev->data.disk = NULL; } -- 2.53.0
