[libvirt] [PATCHv2 5/5] audit: audit qemu pci and usb device passthrough

Eric Blake eblake at redhat.com
Thu Feb 24 00:03:03 UTC 2011


* src/qemu/qemu_audit.h (qemuDomainHostdevAudit): New prototype.
* src/qemu/qemu_audit.c (qemuDomainHostdevAudit): New function.
(qemuDomainStartAudit): Call as appropriate.
* src/qemu/qemu_hotplug.c (qemuDomainAttachHostPciDevice)
(qemuDomainAttachHostUsbDevice, qemuDomainDetachHostPciDevice)
(qemuDomainDetachHostUsbDevice): Likewise.
---

v2: new patch; covers the case of pci and usb host device passthrough,
worth auditing since this can involve IOMMU mappings to have the guest
manage the device I/O.

 src/qemu/qemu_audit.c   |   74 +++++++++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_audit.h   |    4 ++
 src/qemu/qemu_hotplug.c |   28 +++++++-----------
 3 files changed, 89 insertions(+), 17 deletions(-)

diff --git a/src/qemu/qemu_audit.c b/src/qemu/qemu_audit.c
index 6ea31c9..26247a6 100644
--- a/src/qemu/qemu_audit.c
+++ b/src/qemu/qemu_audit.c
@@ -103,6 +103,75 @@ void qemuDomainNetAudit(virDomainObjPtr vm,


 /**
+ * qemuDomainHostdevAudit:
+ * @vm: domain making a change in pass-through host device
+ * @hostdev: device being attached or removed
+ * @reason: one of "start, "attach", or "detach"
+ * @success: true if the device passthrough operation succeeded
+ *
+ * Log an audit message about an attempted device passthrough change.
+ */
+void
+qemuDomainHostdevAudit(virDomainObjPtr vm,
+                       virDomainHostdevDefPtr hostdev,
+                       const char *reason,
+                       bool success)
+{
+    char uuidstr[VIR_UUID_STRING_BUFLEN];
+    char *vmname;
+    char *address;
+    char *device;
+
+    virUUIDFormat(vm->def->uuid, uuidstr);
+    if (!(vmname = virAuditEncode("vm", vm->def->name))) {
+        VIR_WARN0("OOM while encoding audit message");
+        return;
+    }
+
+    switch (hostdev->source.subsys.type) {
+    case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
+        if (virAsprintf(&address, "%.4x:%.2x:%.2x.%.1x",
+                        hostdev->source.subsys.u.pci.domain,
+                        hostdev->source.subsys.u.pci.bus,
+                        hostdev->source.subsys.u.pci.slot,
+                        hostdev->source.subsys.u.pci.function) < 0) {
+            VIR_WARN0("OOM while encoding audit message");
+            goto cleanup;
+        }
+        break;
+    case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
+        if (virAsprintf(&address, "%.3d.%.3d",
+                        hostdev->source.subsys.u.usb.bus,
+                        hostdev->source.subsys.u.usb.device) < 0) {
+            VIR_WARN0("OOM while encoding audit message");
+            goto cleanup;
+        }
+        break;
+    default:
+        VIR_WARN("Unexpected hostdev type while encoding audit message: %d",
+                 hostdev->source.subsys.type);
+        goto cleanup;
+    }
+
+    if (!(device = virAuditEncode("device", VIR_AUDIT_STR(address)))) {
+        VIR_WARN0("OOM while encoding audit message");
+        goto cleanup;
+    }
+
+    VIR_AUDIT(VIR_AUDIT_RECORD_RESOURCE, success,
+              "resrc=dev reason=%s %s uuid=%s type=%s %s",
+              reason, vmname, uuidstr,
+              virDomainHostdevSubsysTypeToString(hostdev->source.subsys.type),
+              device);
+
+cleanup:
+    VIR_FREE(vmname);
+    VIR_FREE(device);
+    VIR_FREE(address);
+}
+
+
+/**
  * qemuDomainCgroupAudit:
  * @vm: domain making the cgroups ACL change
  * @cgroup: cgroup that manages the devices
@@ -238,6 +307,11 @@ void qemuDomainStartAudit(virDomainObjPtr vm, const char *reason, bool success)
         qemuDomainNetAudit(vm, NULL, net, "start", true);
     }

+    for (i = 0 ; i < vm->def->nhostdevs ; i++) {
+        virDomainHostdevDefPtr hostdev = vm->def->hostdevs[i];
+        qemuDomainHostdevAudit(vm, hostdev, "start", true);
+    }
+
     qemuDomainMemoryAudit(vm, 0, vm->def->mem.cur_balloon, "start", true);
     qemuDomainVcpuAudit(vm, 0, vm->def->vcpus, "start", true);

diff --git a/src/qemu/qemu_audit.h b/src/qemu/qemu_audit.h
index cdbb957..2f901be 100644
--- a/src/qemu/qemu_audit.h
+++ b/src/qemu/qemu_audit.h
@@ -39,6 +39,10 @@ void qemuDomainNetAudit(virDomainObjPtr vm,
                         virDomainNetDefPtr newDef,
                         const char *reason,
                         bool success);
+void qemuDomainHostdevAudit(virDomainObjPtr vm,
+                            virDomainHostdevDefPtr def,
+                            const char *reason,
+                            bool success);
 void qemuDomainCgroupAudit(virDomainObjPtr vm,
                            virCgroupPtr group,
                            const char *reason,
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 8090b90..da07c29 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -842,6 +842,7 @@ int qemuDomainAttachHostPciDevice(struct qemud_driver *driver,
         hostdev->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
         memcpy(&hostdev->info.addr.pci, &guestAddr, sizeof(guestAddr));
     }
+    qemuDomainHostdevAudit(vm, hostdev, "attach", ret == 0);
     if (ret < 0)
         goto error;

@@ -918,6 +919,7 @@ int qemuDomainAttachHostUsbDevice(struct qemud_driver *driver,
                                            hostdev->source.subsys.u.usb.bus,
                                            hostdev->source.subsys.u.usb.device);
     qemuDomainObjExitMonitorWithDriver(driver, vm);
+    qemuDomainHostdevAudit(vm, hostdev, "attach", ret == 0);
     if (ret < 0)
         goto error;

@@ -1607,20 +1609,14 @@ int qemuDomainDetachHostPciDevice(struct qemud_driver *driver,

     qemuDomainObjEnterMonitorWithDriver(driver, vm);
     if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
-        if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
-            qemuDomainObjExitMonitor(vm);
-            return -1;
-        }
+        ret = qemuMonitorDelDevice(priv->mon, detach->info.alias);
     } else {
-        if (qemuMonitorRemovePCIDevice(priv->mon,
-                                       &detach->info.addr.pci) < 0) {
-            qemuDomainObjExitMonitorWithDriver(driver, vm);
-            return -1;
-        }
+        ret = qemuMonitorRemovePCIDevice(priv->mon, &detach->info.addr.pci);
     }
     qemuDomainObjExitMonitorWithDriver(driver, vm);
-
-    ret = 0;
+    qemuDomainHostdevAudit(vm, detach, "detach", ret == 0);
+    if (ret < 0)
+        return -1;

     pci = pciGetDevice(detach->source.subsys.u.pci.domain,
                        detach->source.subsys.u.pci.bus,
@@ -1715,13 +1711,11 @@ int qemuDomainDetachHostUsbDevice(struct qemud_driver *driver,
     }

     qemuDomainObjEnterMonitorWithDriver(driver, vm);
-    if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
-        qemuDomainObjExitMonitorWithDriver(driver, vm);
-        return -1;
-    }
+    ret = qemuMonitorDelDevice(priv->mon, detach->info.alias);
     qemuDomainObjExitMonitorWithDriver(driver, vm);
-
-    ret = 0;
+    qemuDomainHostdevAudit(vm, detach, "detach", ret == 0);
+    if (ret < 0)
+        return -1;

     if (vm->def->nhostdevs > 1) {
         memmove(vm->def->hostdevs + i,
-- 
1.7.4




More information about the libvir-list mailing list