diff --git a/docs/auditlog.html.in b/docs/auditlog.html.in index 24cd8e910e..8528b5295e 100644 --- a/docs/auditlog.html.in +++ b/docs/auditlog.html.in @@ -285,6 +285,21 @@
+ The msg
field will include the following sub-fields
+
chardev
diff --git a/src/conf/domain_audit.c b/src/conf/domain_audit.c index 6e11f39146..23bb4a7e82 100644 --- a/src/conf/domain_audit.c +++ b/src/conf/domain_audit.c @@ -154,6 +154,29 @@ virDomainAuditGenericDev(virDomainObjPtr vm, } +void +virDomainAuditChardev(virDomainObjPtr vm, + virDomainChrDefPtr oldDef, + virDomainChrDefPtr newDef, + const char *reason, + bool success) +{ + virDomainChrSourceDefPtr oldsrc = NULL; + virDomainChrSourceDefPtr newsrc = NULL; + + if (oldDef) + oldsrc = &oldDef->source; + + if (newDef) + newsrc = &newDef->source; + + virDomainAuditGenericDev(vm, "chardev", + virDomainAuditChardevPath(oldsrc), + virDomainAuditChardevPath(newsrc), + reason, success); +} + + void virDomainAuditDisk(virDomainObjPtr vm, virStorageSourcePtr oldDef, @@ -772,6 +795,25 @@ virDomainAuditStart(virDomainObjPtr vm, const char *reason, bool success) virDomainAuditRedirdev(vm, redirdev, "start", true); } + for (i = 0; i < vm->def->nserials; i++) + virDomainAuditChardev(vm, NULL, vm->def->serials[i], "start", true); + + for (i = 0; i < vm->def->nparallels; i++) + virDomainAuditChardev(vm, NULL, vm->def->parallels[i], "start", true); + + for (i = 0; i < vm->def->nchannels; i++) + virDomainAuditChardev(vm, NULL, vm->def->channels[i], "start", true); + + for (i = 0; i < vm->def->nconsoles; i++) { + if (i == 0 && + (vm->def->consoles[i]->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL || + vm->def->consoles[i]->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_NONE) && + STREQ_NULLABLE(vm->def->os.type, "hvm")) + continue; + + virDomainAuditChardev(vm, NULL, vm->def->consoles[i], "start", true); + } + if (vm->def->rng) virDomainAuditRNG(vm, NULL, vm->def->rng, "start", true); diff --git a/src/conf/domain_audit.h b/src/conf/domain_audit.h index 58d25a494c..3434febe64 100644 --- a/src/conf/domain_audit.h +++ b/src/conf/domain_audit.h @@ -111,4 +111,11 @@ void virDomainAuditRedirdev(virDomainObjPtr vm, bool success) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); +void virDomainAuditChardev(virDomainObjPtr vm, + virDomainChrDefPtr oldDef, + virDomainChrDefPtr newDef, + const char *reason, + bool success) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(4); + #endif /* __VIR_DOMAIN_AUDIT_H__ */ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 29e9db930e..18d5f28c4a 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -116,6 +116,7 @@ virDomainPCIAddressValidate; virDomainAuditCgroup; virDomainAuditCgroupMajor; virDomainAuditCgroupPath; +virDomainAuditChardev; virDomainAuditDisk; virDomainAuditFS; virDomainAuditHostdev; diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index b6033df065..1fc28b8f21 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1458,18 +1458,20 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver, qemuDomainObjEnterMonitor(driver, vm); if (qemuMonitorAttachCharDev(priv->mon, charAlias, &chr->source) < 0) { qemuDomainObjExitMonitor(driver, vm); - goto cleanup; + goto audit; } if (devstr && qemuMonitorAddDevice(priv->mon, devstr) < 0) { /* detach associated chardev on error */ qemuMonitorDetachCharDev(priv->mon, charAlias); qemuDomainObjExitMonitor(driver, vm); - goto cleanup; + goto audit; } qemuDomainObjExitMonitor(driver, vm); ret = 0; + audit: + virDomainAuditChardev(vm, NULL, chr, "attach", ret == 0); cleanup: if (ret < 0 && need_remove) qemuDomainChrRemove(vmdef, chr); @@ -2749,6 +2751,7 @@ qemuDomainRemoveChrDevice(virQEMUDriverPtr driver, char *charAlias = NULL; qemuDomainObjPrivatePtr priv = vm->privateData; int ret = -1; + int rc; VIR_DEBUG("Removing character device %s from domain %p %s", chr->info.alias, vm, vm->def->name); @@ -2757,12 +2760,14 @@ qemuDomainRemoveChrDevice(virQEMUDriverPtr driver, goto cleanup; qemuDomainObjEnterMonitor(driver, vm); - if (qemuMonitorDetachCharDev(priv->mon, charAlias) < 0) { - qemuDomainObjExitMonitor(driver, vm); - goto cleanup; - } + rc = qemuMonitorDetachCharDev(priv->mon, charAlias); qemuDomainObjExitMonitor(driver, vm); + virDomainAuditChardev(vm, chr, NULL, "detach", rc == 0); + + if (rc < 0) + goto cleanup; + event = virDomainEventDeviceRemovedNewFromObj(vm, chr->info.alias); if (event) qemuDomainEventQueue(driver, event);