This patch adds auditing of resources used by Virtio RNG devices. Only
resources on the local filesystems are audited.

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'
---

Notes:
    Version 3:
    - don't log non-local resources for EGD backend
    - change order of blocks of code to optimize
    
    Version 2:
    - log also EGD backends
    - add example of audit message to commit message

 src/conf/domain_audit.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 120 insertions(+)

diff --git a/src/conf/domain_audit.c b/src/conf/domain_audit.c
index 8cd522a..a776058 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 *
+virDomainAuditChardevPath(virDomainChrSourceDefPtr chr)
+{
+    if (!chr)
+        return NULL;
+
+    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:
+    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 NULL;
+    }
+
+    return NULL;
+}
+
+
 void
 virDomainAuditDisk(virDomainObjPtr vm,
                    const char *oldDef, const char *newDef,
@@ -100,6 +131,92 @@ 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;
+
+    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 = virDomainAuditChardevPath(newDef->source.chardev);
+            break;
+
+        case VIR_DOMAIN_RNG_BACKEND_LAST:
+            break;
+        }
+    }
+
+    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 = virDomainAuditChardevPath(oldDef->source.chardev);
+            break;
+
+        case VIR_DOMAIN_RNG_BACKEND_LAST:
+            break;
+        }
+    }
+
+    /* don't audit the RNG device if it doesn't use local resources */
+    if (!oldsrcpath && !newsrcpath)
+        return;
+
+    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 (!(newsrc = virAuditEncode("new-rng", VIR_AUDIT_STR(newsrcpath))))
+        goto no_memory;
+
+    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 +758,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

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to