[libvirt] [PATCH] audit: Audit operations done by using VirtIO RNG

This patch adds auditing of resources used by the 'random' backend of virtio RNG. --- If there's desire to audit also use of the "egd" backend that uses a generic character device, a way how to audit this device will need to be introduced. We don't audit useage of chardevs right now. src/conf/domain_audit.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/src/conf/domain_audit.c b/src/conf/domain_audit.c index 8cd522a..c80bdb4 100644 --- a/src/conf/domain_audit.c +++ b/src/conf/domain_audit.c @@ -100,6 +100,79 @@ cleanup: } +static void +virDomainAuditRNG(virDomainObjPtr vm, + virDomainRNGDefPtr newDef, virDomainRNGDefPtr oldDef, + const char *reason, bool success) +{ + char uuidstr[VIR_UUID_STRING_BUFLEN]; + char *vmname; + 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 (newDef->backend) { + case VIR_DOMAIN_RNG_BACKEND_RANDOM: + if (!(newsrc = virAuditEncode("new-rng", VIR_AUDIT_STR(newDef->source.file)))) + goto no_memory; + break; + + case VIR_DOMAIN_RNG_BACKEND_EGD: + case VIR_DOMAIN_RNG_BACKEND_LAST: + if (!(newsrc = virAuditEncode("new-rng", "?"))) + goto no_memory; + break; + } + } else { + if (!(newsrc = virAuditEncode("new-rng", "?"))) + goto no_memory; + } + + if (oldDef) { + switch (oldDef->backend) { + case VIR_DOMAIN_RNG_BACKEND_RANDOM: + if (!(oldsrc = virAuditEncode("old-rng", VIR_AUDIT_STR(oldDef->source.file)))) + goto no_memory; + break; + + case VIR_DOMAIN_RNG_BACKEND_EGD: + case VIR_DOMAIN_RNG_BACKEND_LAST: + if (!(oldsrc = virAuditEncode("old-rng", "?"))) + goto no_memory; + break; + } + } else { + if (!(oldsrc = virAuditEncode("old-rng", "?"))) + 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 +714,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); -- 1.8.1.5

On Mon, Mar 11, 2013 at 05:19:36PM +0100, Peter Krempa wrote:
This patch adds auditing of resources used by the 'random' backend of virtio RNG. --- If there's desire to audit also use of the "egd" backend that uses a generic character device, a way how to audit this device will need to be introduced. We don't audit useage of chardevs right now.
src/conf/domain_audit.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+)
Can you update the commit message to give an example of the exact audit message that is generated from this. Also please Cc Steve Grubb when you re-post this, for sign-off from his position as audit tools maintainer.
+static void +virDomainAuditRNG(virDomainObjPtr vm, + virDomainRNGDefPtr newDef, virDomainRNGDefPtr oldDef, + const char *reason, bool success) +{ + char uuidstr[VIR_UUID_STRING_BUFLEN]; + char *vmname; + 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 (newDef->backend) { + case VIR_DOMAIN_RNG_BACKEND_RANDOM: + if (!(newsrc = virAuditEncode("new-rng", VIR_AUDIT_STR(newDef->source.file))))
Can't newDef->source.file be NULL ? In such a case we need to explicitly fill in the file that QEMU will default to in the audit record. We can't leave the filename blank
+ goto no_memory; + break; + + case VIR_DOMAIN_RNG_BACKEND_EGD: + case VIR_DOMAIN_RNG_BACKEND_LAST: + if (!(newsrc = virAuditEncode("new-rng", "?")))
We need to specify the EGD unix socket path we use too, not merely '?'.
+ goto no_memory; + break; + } + } else { + if (!(newsrc = virAuditEncode("new-rng", "?"))) + goto no_memory; + } + + if (oldDef) { + switch (oldDef->backend) { + case VIR_DOMAIN_RNG_BACKEND_RANDOM: + if (!(oldsrc = virAuditEncode("old-rng", VIR_AUDIT_STR(oldDef->source.file))))
Same point here
+ goto no_memory; + break; + + case VIR_DOMAIN_RNG_BACKEND_EGD: + case VIR_DOMAIN_RNG_BACKEND_LAST: + if (!(oldsrc = virAuditEncode("old-rng", "?"))) + goto no_memory; + break; + } + } else { + if (!(oldsrc = virAuditEncode("old-rng", "?"))) + 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 +714,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);
Regards, 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 :|

On 03/12/13 12:19, Daniel P. Berrange wrote:
On Mon, Mar 11, 2013 at 05:19:36PM +0100, Peter Krempa wrote:
This patch adds auditing of resources used by the 'random' backend of virtio RNG. --- If there's desire to audit also use of the "egd" backend that uses a generic character device, a way how to audit this device will need to be introduced. We don't audit useage of chardevs right now.
src/conf/domain_audit.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+)
Can you update the commit message to give an example of the exact audit message that is generated from this. Also please Cc Steve Grubb when you re-post this, for sign-off from his position as audit tools maintainer.
Okay.
+static void +virDomainAuditRNG(virDomainObjPtr vm, + virDomainRNGDefPtr newDef, virDomainRNGDefPtr oldDef, + const char *reason, bool success) +{ + char uuidstr[VIR_UUID_STRING_BUFLEN]; + char *vmname; + 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 (newDef->backend) { + case VIR_DOMAIN_RNG_BACKEND_RANDOM: + if (!(newsrc = virAuditEncode("new-rng", VIR_AUDIT_STR(newDef->source.file))))
Can't newDef->source.file be NULL ? In such a case we need to explicitly fill in the file that QEMU will default to in the audit record. We can't leave the filename blank
Ah, yeah.
+ goto no_memory; + break; + + case VIR_DOMAIN_RNG_BACKEND_EGD: + case VIR_DOMAIN_RNG_BACKEND_LAST: + if (!(newsrc = virAuditEncode("new-rng", "?")))
We need to specify the EGD unix socket path we use too, not merely '?'.
This can be set to multiple things as the backend is a chardev from point of view of qemu: The data can be transported using: TCP, UDP, unix sockets and a ton of other stuff, and we don't have a precedent case for this. Is there a need to represend TCP backends? Or auditing is meant just for local stuff?
+ goto no_memory; + break; + } + } else { + if (!(newsrc = virAuditEncode("new-rng", "?"))) + goto no_memory; + } +
Peter

On Tue, Mar 12, 2013 at 12:25:14PM +0100, Peter Krempa wrote:
On 03/12/13 12:19, Daniel P. Berrange wrote:
On Mon, Mar 11, 2013 at 05:19:36PM +0100, Peter Krempa wrote:
This patch adds auditing of resources used by the 'random' backend of virtio RNG. --- If there's desire to audit also use of the "egd" backend that uses a generic character device, a way how to audit this device will need to be introduced. We don't audit useage of chardevs right now.
src/conf/domain_audit.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+)
Can you update the commit message to give an example of the exact audit message that is generated from this. Also please Cc Steve Grubb when you re-post this, for sign-off from his position as audit tools maintainer.
Okay.
+static void +virDomainAuditRNG(virDomainObjPtr vm, + virDomainRNGDefPtr newDef, virDomainRNGDefPtr oldDef, + const char *reason, bool success) +{ + char uuidstr[VIR_UUID_STRING_BUFLEN]; + char *vmname; + 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 (newDef->backend) { + case VIR_DOMAIN_RNG_BACKEND_RANDOM: + if (!(newsrc = virAuditEncode("new-rng", VIR_AUDIT_STR(newDef->source.file))))
Can't newDef->source.file be NULL ? In such a case we need to explicitly fill in the file that QEMU will default to in the audit record. We can't leave the filename blank
Ah, yeah.
+ goto no_memory; + break; + + case VIR_DOMAIN_RNG_BACKEND_EGD: + case VIR_DOMAIN_RNG_BACKEND_LAST: + if (!(newsrc = virAuditEncode("new-rng", "?")))
We need to specify the EGD unix socket path we use too, not merely '?'.
This can be set to multiple things as the backend is a chardev from point of view of qemu:
The data can be transported using: TCP, UDP, unix sockets and a ton of other stuff, and we don't have a precedent case for this. Is there a need to represend TCP backends? Or auditing is meant just for local stuff?
We don't have code for auditing serial/parallel/channel devices since it was out of scope for the original security certification. We need to fix that at some point, so yes, labelling chardevs is relevant. We don't need to worry about network cases, only where the chardev points to some resource that is visible in the host filesystem, so a plain file, device node, UNIX socket, etc Dnaiel -- |: 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 :|
participants (2)
-
Daniel P. Berrange
-
Peter Krempa