From 43f45cd04cb0a4a653131934f433c4b07b38a9e1 Mon Sep 17 00:00:00 2001 Message-Id: <43f45cd04cb0a4a653131934f433c4b07b38a9e1.1288197060.git.jdenemar@redhat.com> From: Daniel P. Berrange <berrange@redhat.com> Date: Wed, 27 Oct 2010 15:15:28 +0100 Subject: [PATCH] Add disk/net resource auditing to QEMU driver Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=587280 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 (from 8dc136b5fce7dd9dbf943fcea9db926129bb9a4e) --- 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 80c5d61..9d5d95a 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -3396,6 +3396,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, @@ -3405,6 +3478,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; @@ -3418,6 +3492,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); } @@ -7196,6 +7283,8 @@ static int qemudDomainChangeEjectableMedia(struct qemud_driver *driver, } qemuDomainObjExitMonitorWithDriver(driver, vm); + qemuDomainDiskAudit(vm, origdisk, disk, "update", ret >= 0); + if (ret < 0) goto error; @@ -7295,6 +7384,8 @@ static int qemudDomainAttachPciDiskDevice(struct qemud_driver *driver, } qemuDomainObjExitMonitorWithDriver(driver, vm); + qemuDomainDiskAudit(vm, NULL, disk, "attach", ret >= 0); + if (ret < 0) goto error; @@ -7530,6 +7621,8 @@ static int qemudDomainAttachSCSIDisk(struct qemud_driver *driver, } qemuDomainObjExitMonitorWithDriver(driver, vm); + qemuDomainDiskAudit(vm, NULL, disk, "attach", ret >= 0); + if (ret < 0) goto error; @@ -7615,6 +7708,8 @@ static int qemudDomainAttachUsbMassstorageDevice(struct qemud_driver *driver, } qemuDomainObjExitMonitorWithDriver(driver, vm); + qemuDomainDiskAudit(vm, NULL, disk, "attach", ret >= 0); + if (ret < 0) goto error; @@ -7749,11 +7844,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; } } @@ -7781,12 +7878,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; @@ -7794,6 +7893,8 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn, } qemuDomainObjExitMonitorWithDriver(driver, vm); + qemuDomainNetAudit(vm, NULL, net, "attach", true); + ret = 0; vm->def->nets[vm->def->nnets++] = net; @@ -8507,6 +8608,8 @@ static int qemudDomainDetachPciDiskDevice(struct qemud_driver *driver, } qemuDomainObjExitMonitorWithDriver(driver, vm); + qemuDomainDiskAudit(vm, detach, NULL, "detach", ret >= 0); + qemudShrinkDisks(vm->def, i); virDomainDiskDefFree(detach); @@ -8571,6 +8674,8 @@ static int qemudDomainDetachSCSIDiskDevice(struct qemud_driver *driver, } qemuDomainObjExitMonitorWithDriver(driver, vm); + qemuDomainDiskAudit(vm, detach, NULL, "detach", ret >= 0); + qemudShrinkDisks(vm->def, i); virDomainDiskDefFree(detach); @@ -8724,12 +8829,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; } } @@ -8738,16 +8845,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); + virDomainConfNWFilterTeardown(detach); #if WITH_MACVTAP -- 1.7.3.2