[libvirt] [PATCH] Include pid namespace inode in LXC audit messages

Daniel P. Berrange berrange at redhat.com
Wed Mar 6 15:10:11 UTC 2013


From: "Daniel P. Berrange" <berrange at redhat.com>

To allow the efficient correlation of container audit messages
with host hosts, include the pid namespace inode in audit
messages.

The resulting audit message will be

type=VIRT_CONTROL msg=audit(1362582468.378:50): pid=19284 uid=0 auid=0 ses=312 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 msg='virt=lxc op=init vm="demo" uuid=0770f019-2d4e-09e9-8e4a-719e12b3a18e vm-pid=19620 init-pid=19622 pid-ns=23434 exe="/home/berrange/src/virt/libvirt/daemon/.libs/lt-libvirtd" hostname=? addr=? terminal=pts/6 res=success'

Note the 'pid-ns' field showing the inode number of the PID
namespace of the container init process. Since /proc/PID/ns/pid
doesn't exist on older kernels, we keep the previous 'init-pid'
field too, showing the host PID of the init process.

---
 src/conf/domain_audit.c |  8 +++++---
 src/conf/domain_audit.h |  3 ++-
 src/lxc/lxc_process.c   | 44 +++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 50 insertions(+), 5 deletions(-)

diff --git a/src/conf/domain_audit.c b/src/conf/domain_audit.c
index c00bd11..8cd522a 100644
--- a/src/conf/domain_audit.c
+++ b/src/conf/domain_audit.c
@@ -649,7 +649,8 @@ virDomainAuditStart(virDomainObjPtr vm, const char *reason, bool success)
 
 void
 virDomainAuditInit(virDomainObjPtr vm,
-                   pid_t initpid)
+                   pid_t initpid,
+                   ino_t pidns)
 {
     char uuidstr[VIR_UUID_STRING_BUFLEN];
     char *vmname;
@@ -668,8 +669,9 @@ virDomainAuditInit(virDomainObjPtr vm,
     }
 
     VIR_AUDIT(VIR_AUDIT_RECORD_MACHINE_CONTROL, true,
-              "virt=%s op=init %s uuid=%s vm-pid=%lld init-pid=%lld",
-              virt, vmname, uuidstr, (long long)vm->pid, (long long)initpid);
+              "virt=%s op=init %s uuid=%s vm-pid=%lld init-pid=%lld pid-ns=%lld",
+              virt, vmname, uuidstr, (long long)vm->pid, (long long)initpid,
+              (long long)pidns);
 
     VIR_FREE(vmname);
 }
diff --git a/src/conf/domain_audit.h b/src/conf/domain_audit.h
index 381fe37..9486216 100644
--- a/src/conf/domain_audit.h
+++ b/src/conf/domain_audit.h
@@ -32,7 +32,8 @@ void virDomainAuditStart(virDomainObjPtr vm,
                          bool success)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
 void virDomainAuditInit(virDomainObjPtr vm,
-                        pid_t pid)
+                        pid_t pid,
+                        ino_t pidns)
     ATTRIBUTE_NONNULL(1);
 void virDomainAuditStop(virDomainObjPtr vm,
                         const char *reason)
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
index aaa81a7..5f4a3aa 100644
--- a/src/lxc/lxc_process.c
+++ b/src/lxc/lxc_process.c
@@ -630,6 +630,36 @@ static void virLXCProcessMonitorExitNotify(virLXCMonitorPtr mon ATTRIBUTE_UNUSED
               priv->stopReason, status);
 }
 
+static int
+virLXCProcessGetNsInode(pid_t pid,
+                        const char *nsname,
+                        ino_t *inode)
+{
+    char *path = NULL;
+    struct stat sb;
+    int ret = -1;
+
+    if (virAsprintf(&path, "/proc/%llu/ns/%s",
+                    (unsigned long long)pid, nsname) < 0) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    if (stat(path, &sb) < 0) {
+        virReportSystemError(errno,
+                             _("Unable to stat %s"), path);
+        goto cleanup;
+    }
+
+    *inode = sb.st_ino;
+    ret = 0;
+
+cleanup:
+    VIR_FREE(path);
+    return ret;
+}
+
+
 /* XXX a little evil */
 extern virLXCDriverPtr lxc_driver;
 static void virLXCProcessMonitorInitNotify(virLXCMonitorPtr mon ATTRIBUTE_UNUSED,
@@ -637,8 +667,20 @@ static void virLXCProcessMonitorInitNotify(virLXCMonitorPtr mon ATTRIBUTE_UNUSED
                                            virDomainObjPtr vm)
 {
     virLXCDomainObjPrivatePtr priv = vm->privateData;
+    ino_t inode;
+
     priv->initpid = initpid;
-    virDomainAuditInit(vm, initpid);
+
+    if (virLXCProcessGetNsInode(initpid, "pid", &inode) < 0) {
+        virErrorPtr err = virGetLastError();
+        VIR_WARN("Cannot obtain pid NS inode for %llu: %s",
+                 (unsigned long long)initpid,
+                 err && err->message ? err->message : "<unknown>");
+        virResetLastError();
+    } else {
+        inode = 0;
+    }
+    virDomainAuditInit(vm, initpid, inode);
 
     if (virDomainSaveStatus(lxc_driver->caps, lxc_driver->stateDir, vm) < 0)
         VIR_WARN("Cannot update XML with PID for LXC %s", vm->def->name);
-- 
1.8.1.4




More information about the libvir-list mailing list