Add auditing of all initial disk/net assignments to QEMU guests at startup. Add auditing for all hotplug & unplug events and disk media changes. * src/qemu/qemu_driver.c: Add disk/net resource auditing --- src/qemu/qemu_driver.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 111 insertions(+), 0 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 8db5e7a..b119ca1 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -3668,6 +3668,79 @@ static int qemuDomainSnapshotSetActive(virDomainObjPtr vm, static int qemuDomainSnapshotSetInactive(virDomainObjPtr vm, char *snapshotDir); +static void qemuDomainDiskAudit(virDomainObjPtr vm, + virDomainDiskDefPtr oldDef, + virDomainDiskDefPtr newDef, + const char *reason, + bool success) +{ + char uuidstr[VIR_UUID_STRING_BUFLEN]; + char *vmname; + char *oldsrc = NULL; + char *newsrc = NULL; + + virUUIDFormat(vm->def->uuid, uuidstr); + if (!(vmname = virAuditEncode("vm", vm->def->name))) { + VIR_WARN0("OOM while encoding audit message"); + return; + } + + if (!(oldsrc = virAuditEncode("old-disk", + oldDef && oldDef->src ? + oldDef->src : "?"))) { + VIR_WARN0("OOM while encoding audit message"); + goto cleanup; + } + if (!(newsrc = virAuditEncode("new-disk", + newDef && newDef->src ? + newDef->src : "?"))) { + VIR_WARN0("OOM while encoding audit message"); + goto cleanup; + } + + VIR_AUDIT(VIR_AUDIT_RECORD_RESOURCE, success, + "resrc=disk reason=%s %s uuid=%s %s %s", + reason, vmname, uuidstr, + oldsrc, newsrc); + +cleanup: + VIR_FREE(vmname); + VIR_FREE(oldsrc); + VIR_FREE(newsrc); +} + + +static void qemuDomainNetAudit(virDomainObjPtr vm, + virDomainNetDefPtr oldDef, + virDomainNetDefPtr newDef, + const char *reason, + bool success) +{ + char uuidstr[VIR_UUID_STRING_BUFLEN]; + char newMacstr[VIR_MAC_STRING_BUFLEN]; + char oldMacstr[VIR_MAC_STRING_BUFLEN]; + char *vmname; + + virUUIDFormat(vm->def->uuid, uuidstr); + if (oldDef) + virFormatMacAddr(oldDef->mac, oldMacstr); + if (newDef) + virFormatMacAddr(newDef->mac, newMacstr); + if (!(vmname = virAuditEncode("vm", vm->def->name))) { + VIR_WARN0("OOM while encoding audit message"); + return; + } + + VIR_AUDIT(VIR_AUDIT_RECORD_RESOURCE, success, + "resrc=net reason=%s %s uuid=%s old-net='%s' new-net='%s'", + reason, vmname, uuidstr, + oldDef ? oldMacstr : "?", + newDef ? newMacstr : "?"); + + VIR_FREE(vmname); +} + + static void qemuDomainLifecycleAudit(virDomainObjPtr vm, const char *op, const char *reason, @@ -3677,6 +3750,7 @@ static void qemuDomainLifecycleAudit(virDomainObjPtr vm, char *vmname; virUUIDFormat(vm->def->uuid, uuidstr); + if (!(vmname = virAuditEncode("vm", vm->def->name))) { VIR_WARN0("OOM while encoding audit message"); return; @@ -3690,6 +3764,19 @@ static void qemuDomainLifecycleAudit(virDomainObjPtr vm, static void qemuDomainStartAudit(virDomainObjPtr vm, const char *reason, bool success) { + int i; + + for (i = 0 ; i < vm->def->ndisks ; i++) { + virDomainDiskDefPtr disk = vm->def->disks[i]; + if (disk->src) /* Skips CDROM without media initially inserted */ + qemuDomainDiskAudit(vm, NULL, disk, "start", true); + } + + for (i = 0 ; i < vm->def->nnets ; i++) { + virDomainNetDefPtr net = vm->def->nets[i]; + qemuDomainNetAudit(vm, NULL, net, "start", true); + } + qemuDomainLifecycleAudit(vm, "start", reason, success); } @@ -7565,6 +7652,8 @@ static int qemudDomainChangeEjectableMedia(struct qemud_driver *driver, } qemuDomainObjExitMonitorWithDriver(driver, vm); + qemuDomainDiskAudit(vm, origdisk, disk, "update", ret >= 0); + if (ret < 0) goto error; @@ -7664,6 +7753,8 @@ static int qemudDomainAttachPciDiskDevice(struct qemud_driver *driver, } qemuDomainObjExitMonitorWithDriver(driver, vm); + qemuDomainDiskAudit(vm, NULL, disk, "attach", ret >= 0); + if (ret < 0) goto error; @@ -7899,6 +7990,8 @@ static int qemudDomainAttachSCSIDisk(struct qemud_driver *driver, } qemuDomainObjExitMonitorWithDriver(driver, vm); + qemuDomainDiskAudit(vm, NULL, disk, "attach", ret >= 0); + if (ret < 0) goto error; @@ -7984,6 +8077,8 @@ static int qemudDomainAttachUsbMassstorageDevice(struct qemud_driver *driver, } qemuDomainObjExitMonitorWithDriver(driver, vm); + qemuDomainDiskAudit(vm, NULL, disk, "attach", ret >= 0); + if (ret < 0) goto error; @@ -8118,11 +8213,13 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn, (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) { if (qemuMonitorAddNetdev(priv->mon, netstr) < 0) { qemuDomainObjExitMonitorWithDriver(driver, vm); + qemuDomainNetAudit(vm, NULL, net, "attach", false); goto try_tapfd_close; } } else { if (qemuMonitorAddHostNetwork(priv->mon, netstr) < 0) { qemuDomainObjExitMonitorWithDriver(driver, vm); + qemuDomainNetAudit(vm, NULL, net, "attach", false); goto try_tapfd_close; } } @@ -8150,12 +8247,14 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn, if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) { if (qemuMonitorAddDevice(priv->mon, nicstr) < 0) { qemuDomainObjExitMonitorWithDriver(driver, vm); + qemuDomainNetAudit(vm, NULL, net, "attach", false); goto try_remove; } } else { if (qemuMonitorAddPCINetwork(priv->mon, nicstr, &guestAddr) < 0) { qemuDomainObjExitMonitorWithDriver(driver, vm); + qemuDomainNetAudit(vm, NULL, net, "attach", false); goto try_remove; } net->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; @@ -8163,6 +8262,8 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn, } qemuDomainObjExitMonitorWithDriver(driver, vm); + qemuDomainNetAudit(vm, NULL, net, "attach", true); + ret = 0; vm->def->nets[vm->def->nnets++] = net; @@ -8860,6 +8961,8 @@ static int qemudDomainDetachPciDiskDevice(struct qemud_driver *driver, } qemuDomainObjExitMonitorWithDriver(driver, vm); + qemuDomainDiskAudit(vm, detach, NULL, "detach", ret >= 0); + if ((qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) && qemuDomainPCIAddressReleaseAddr(priv->pciaddrs, &detach->info) < 0) VIR_WARN("Unable to release PCI address on %s", dev->data.disk->src); @@ -8928,6 +9031,8 @@ static int qemudDomainDetachSCSIDiskDevice(struct qemud_driver *driver, } qemuDomainObjExitMonitorWithDriver(driver, vm); + qemuDomainDiskAudit(vm, detach, NULL, "detach", ret >= 0); + virDomainDiskRemove(vm->def, i); virDomainDiskDefFree(detach); @@ -9081,12 +9186,14 @@ qemudDomainDetachNetDevice(struct qemud_driver *driver, if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) { if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) { qemuDomainObjExitMonitor(vm); + qemuDomainNetAudit(vm, detach, NULL, "detach", false); goto cleanup; } } else { if (qemuMonitorRemovePCIDevice(priv->mon, &detach->info.addr.pci) < 0) { qemuDomainObjExitMonitorWithDriver(driver, vm); + qemuDomainNetAudit(vm, detach, NULL, "detach", false); goto cleanup; } } @@ -9095,16 +9202,20 @@ qemudDomainDetachNetDevice(struct qemud_driver *driver, (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) { if (qemuMonitorRemoveNetdev(priv->mon, hostnet_name) < 0) { qemuDomainObjExitMonitorWithDriver(driver, vm); + qemuDomainNetAudit(vm, detach, NULL, "detach", false); goto cleanup; } } else { if (qemuMonitorRemoveHostNetwork(priv->mon, vlan, hostnet_name) < 0) { qemuDomainObjExitMonitorWithDriver(driver, vm); + qemuDomainNetAudit(vm, detach, NULL, "detach", false); goto cleanup; } } qemuDomainObjExitMonitorWithDriver(driver, vm); + qemuDomainNetAudit(vm, detach, NULL, "detach", true); + if ((qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) && qemuDomainPCIAddressReleaseAddr(priv->pciaddrs, &detach->info) < 0) VIR_WARN0("Unable to release PCI address on NIC"); -- 1.7.2.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list