]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
audit: audit qemu pci and usb device passthrough
authorEric Blake <eblake@redhat.com>
Wed, 23 Feb 2011 23:15:23 +0000 (16:15 -0700)
committerEric Blake <eblake@redhat.com>
Thu, 24 Feb 2011 20:32:17 +0000 (13:32 -0700)
* 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.

src/qemu/qemu_audit.c
src/qemu/qemu_audit.h
src/qemu/qemu_hotplug.c

index 4e24e9aefdf66ce4bb86366392d5bd7d736541d0..b1948c802875f183abb4be33fa6ff409a436379c 100644 (file)
@@ -102,6 +102,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
@@ -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);
 
index fa429f3c322d7a3266242bff405228460e92ebcf..247eddea4dbeb20e81d3ea351b1c656def1c1980 100644 (file)
@@ -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,
index 8090b9022a28be736045d860d33919ac9af88034..da07c2952bf98abf1bf1a1e02ad9c22dda455416 100644 (file)
@@ -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,