On Tue, Mar 12, 2013 at 04:11:15PM +0100, Peter Krempa wrote:
This patch adds auditing of resources used by Virtio RNG devices.
Only
resources on the local filesystems are audited properly. For remote
character device sources "remote" is logged as the path and "none"
is logged for character device backends that don't have a source.
The audit logs look like:
For the 'random' backend:
type=VIRT_RESOURCE msg=audit(1363099126.643:31): pid=995252 uid=0 auid=4294967295
ses=4294967295 msg='virt=kvm resrc=rng reason=start vm="qcow-test"
uuid=118733ed-b658-3e22-a2cb-4fe5cb3ddf79 old-rng="?"
new-rng="/dev/random": exe="/home/pipo/libvirt/daemon/.libs/libvirtd"
hostname=? addr=? terminal=pts/0 res=success'
For local character device source:
type=VIRT_RESOURCE msg=audit(1363100164.240:96): pid=995252 uid=0 auid=4294967295
ses=4294967295 msg='virt=kvm resrc=rng reason=start vm="qcow-test"
uuid=118733ed-b658-3e22-a2cb-4fe5cb3ddf79 old-rng="?"
new-rng="/tmp/unix.sock":
exe="/home/pipo/libvirt/daemon/.libs/libvirtd" hostname=? addr=? terminal=pts/0
res=success'
For a remote character device source:
type=VIRT_RESOURCE msg=audit(1363100291.450:127): pid=995252 uid=0 auid=4294967295
ses=4294967295 msg='virt=kvm resrc=rng reason=start vm="qcow-test"
uuid=118733ed-b658-3e22-a2cb-4fe5cb3ddf79 old-rng="?"
new-rng="remote": exe="/home/pipo/libvirt/daemon/.libs/libvirtd"
hostname=? addr=? terminal=pts/0 res=success'
And for character backends that don't have a source:
type=VIRT_RESOURCE msg=audit(1363100520.513:158): pid=995252 uid=0 auid=4294967295
ses=4294967295 msg='virt=kvm resrc=rng reason=start vm="qcow-test"
uuid=118733ed-b658-3e22-a2cb-4fe5cb3ddf79 old-rng="?" new-rng="none":
exe="/home/pipo/libvirt/daemon/.libs/libvirtd" hostname=? addr=? terminal=pts/0
res=success'
For devices which don't touch any local resource, we should simply not emit any
audit record at all. So these last two examples should simply not exist.
diff --git a/src/conf/domain_audit.c b/src/conf/domain_audit.c
index 8cd522a..0f2cf4f 100644
--- a/src/conf/domain_audit.c
+++ b/src/conf/domain_audit.c
@@ -57,6 +57,37 @@ virDomainAuditGetRdev(const char *path ATTRIBUTE_UNUSED)
}
#endif
+static const char *
+virDomainAuditChardev(virDomainChrSourceDefPtr chr)
+{
+ if (!chr)
+ return "?";
+
+ switch ((enum virDomainChrType) chr->type) {
+ case VIR_DOMAIN_CHR_TYPE_PTY:
+ case VIR_DOMAIN_CHR_TYPE_DEV:
+ case VIR_DOMAIN_CHR_TYPE_FILE:
+ case VIR_DOMAIN_CHR_TYPE_PIPE:
+ return chr->data.file.path;
+
+ case VIR_DOMAIN_CHR_TYPE_UNIX:
+ return chr->data.nix.path;
+
+ case VIR_DOMAIN_CHR_TYPE_TCP:
+ case VIR_DOMAIN_CHR_TYPE_UDP:
+ return "remote";
So return NULL here
+
+ case VIR_DOMAIN_CHR_TYPE_NULL:
+ case VIR_DOMAIN_CHR_TYPE_VC:
+ case VIR_DOMAIN_CHR_TYPE_STDIO:
+ case VIR_DOMAIN_CHR_TYPE_SPICEVMC:
+ case VIR_DOMAIN_CHR_TYPE_LAST:
+ return "none";
and return NULL here
+ }
+
+ return "?";
+}
+
void
virDomainAuditDisk(virDomainObjPtr vm,
const char *oldDef, const char *newDef,
@@ -100,6 +131,89 @@ cleanup:
}
+static void
+virDomainAuditRNG(virDomainObjPtr vm,
+ virDomainRNGDefPtr newDef, virDomainRNGDefPtr oldDef,
+ const char *reason, bool success)
+{
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ char *vmname;
+ const char *newsrcpath = NULL;
+ const char *oldsrcpath = NULL;
+ char *oldsrc = NULL;
+ char *newsrc = NULL;
+ const char *virt;
+
+ virUUIDFormat(vm->def->uuid, uuidstr);
+ if (!(vmname = virAuditEncode("vm", vm->def->name)))
+ goto no_memory;
+
+ if (!(virt = virDomainVirtTypeToString(vm->def->virtType))) {
+ VIR_WARN("Unexpected virt type %d while encoding audit message",
+ vm->def->virtType);
+ virt = "?";
+ }
+
+ if (newDef) {
+ switch ((enum virDomainRNGBackend) newDef->backend) {
+ case VIR_DOMAIN_RNG_BACKEND_RANDOM:
+ if (newDef->source.file)
+ newsrcpath = newDef->source.file;
+ else
+ newsrcpath = "/dev/random";
+ break;
+
+ case VIR_DOMAIN_RNG_BACKEND_EGD:
+ newsrcpath = virDomainAuditChardev(newDef->source.chardev);
+ break;
+
+ case VIR_DOMAIN_RNG_BACKEND_LAST:
+ break;
+ }
+ }
+
+ if (!(newsrc = virAuditEncode("new-rng", VIR_AUDIT_STR(newsrcpath))))
+ goto no_memory;
+
+
+ if (oldDef) {
+ switch ((enum virDomainRNGBackend) oldDef->backend) {
+ case VIR_DOMAIN_RNG_BACKEND_RANDOM:
+ if (oldDef->source.file)
+ oldsrcpath = oldDef->source.file;
+ else
+ oldsrcpath = "/dev/random";
+ break;
+
+ case VIR_DOMAIN_RNG_BACKEND_EGD:
+ oldsrcpath = virDomainAuditChardev(oldDef->source.chardev);
+ break;
+
+ case VIR_DOMAIN_RNG_BACKEND_LAST:
+ break;
+ }
+ }
And if both newsrcpath and oldsrcpath are NULL at this point, then jump
to the cleanup label
+
+ if (!(oldsrc = virAuditEncode("old-rng", VIR_AUDIT_STR(oldsrcpath))))
+ goto no_memory;
+
+ VIR_AUDIT(VIR_AUDIT_RECORD_RESOURCE, success,
+ "virt=%s resrc=rng reason=%s %s uuid=%s %s %s",
+ virt, reason, vmname, uuidstr,
+ oldsrc, newsrc);
+
+cleanup:
+ VIR_FREE(vmname);
+ VIR_FREE(oldsrc);
+ VIR_FREE(newsrc);
+ return;
+
+no_memory:
+ VIR_WARN("OOM while encoding audit message");
+ goto cleanup;
+}
+
+
void
virDomainAuditFS(virDomainObjPtr vm,
virDomainFSDefPtr oldDef, virDomainFSDefPtr newDef,
@@ -641,6 +755,9 @@ virDomainAuditStart(virDomainObjPtr vm, const char *reason, bool
success)
virDomainAuditRedirdev(vm, redirdev, "start", true);
}
+ if (vm->def->rng)
+ virDomainAuditRNG(vm, vm->def->rng, NULL, "start", true);
+
virDomainAuditMemory(vm, 0, vm->def->mem.cur_balloon, "start",
true);
virDomainAuditVcpu(vm, 0, vm->def->vcpus, "start", true);
Daniel
--
|:
http://berrange.com -o-
http://www.flickr.com/photos/dberrange/ :|
|:
http://libvirt.org -o-
http://virt-manager.org :|
|:
http://autobuild.org -o-
http://search.cpan.org/~danberr/ :|
|:
http://entangle-photo.org -o-
http://live.gnome.org/gtk-vnc :|