Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > ebe084c140192657f9094e135a84202c > files > 103

libvirt-0.8.2-29.el5.src.rpm

From 325cadbffb832b0c50b10f79646191609cbfe916 Mon Sep 17 00:00:00 2001
From: Michal Privoznik <mprivozn@redhat.com>
Date: Wed, 27 Jun 2012 22:20:57 +0800
Subject: [PATCH] qemu: Delete USB devices used by domain on stop
To: libvir-list@redhat.com

https://bugzilla.redhat.com/show_bug.cgi?id=816601
CVE-2012-2693

To prevent assigning one USB device to two domains,
we keep a list of assigned USB devices. On domain
startup - qemudStartup() - we insert devices
used by domain into the list but remove them only
on detach-device. Devices are, however, released
on qemudShutdownVMDaemon.() as well.
(cherry picked from commit e2f5dd6134ebeb6846450c7d7782273d3d274859)

Conflicts:

	src/qemu/qemu_hostdev.c

Signed-off-by: Daniel Veillard <veillard@redhat.com>
---
 src/qemu/qemu_driver.c |   60 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 60 insertions(+), 0 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 30f8c9b..68f97ac 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -765,6 +765,63 @@ qemuHandleMonitorEOF(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
     }
 }
 
+static void
+qemuDomainReAttachHostUsbDevices(struct qemud_driver *driver,
+                                 const char *name,
+                                 virDomainHostdevDefPtr *hostdevs,
+                                 int nhostdevs)
+{
+    int i;
+
+    for (i = 0; i < nhostdevs; i++) {
+        virDomainHostdevDefPtr hostdev = hostdevs[i];
+        usbDevice *usb, *tmp;
+        const char *used_by = NULL;
+
+        if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
+            continue;
+        if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
+            continue;
+
+        usb = usbGetDevice(hostdev->source.subsys.u.usb.bus,
+                           hostdev->source.subsys.u.usb.device);
+
+        if (!usb) {
+            VIR_WARN("Unable to reattach USB device %03d.%03d on domain %s",
+                     hostdev->source.subsys.u.usb.bus,
+                     hostdev->source.subsys.u.usb.device,
+                     name);
+            continue;
+        }
+
+        /* Delete only those USB devices which belongs
+         * to domain @name because qemuProcessStart() might
+         * have failed because USB device is already taken.
+         * Therefore we want to steal only those devices from
+         * the list which were taken by @name */
+
+        tmp = usbDeviceListFind(driver->activeUsbHostdevs, usb);
+        usbFreeDevice(usb);
+
+        if (!tmp) {
+            VIR_WARN("Unable to find device %03d.%03d "
+                     "in list of active USB devices",
+                     hostdev->source.subsys.u.usb.bus,
+                     hostdev->source.subsys.u.usb.device);
+            continue;
+        }
+
+        used_by = usbDeviceGetUsedBy(tmp);
+        if (STREQ_NULLABLE(used_by, name)) {
+            VIR_DEBUG("Removing %03d.%03d dom=%s from activeUsbHostdevs",
+                      hostdev->source.subsys.u.usb.bus,
+                      hostdev->source.subsys.u.usb.device,
+                      name);
+
+            usbDeviceListDel(driver->activeUsbHostdevs, tmp);
+        }
+    }
+}
 
 static virDomainDiskDefPtr
 findDomainDiskByPath(virDomainObjPtr vm,
@@ -3203,6 +3260,9 @@ qemuDomainReAttachHostDevices(struct qemud_driver *driver,
         return;
 
     qemuDomainReAttachHostdevDevices(driver, def->hostdevs, def->nhostdevs);
+
+    qemuDomainReAttachHostUsbDevices(driver, def->name, def->hostdevs,
+                                     def->nhostdevs);
 }
 
 static const char *const defaultDeviceACL[] = {
-- 
1.7.7.4