Log the creation and deletion of namespace instances in all 6 types of
namespaces.

Two new audit message types have been introduced:
        AUDIT_NS_INIT   1329
        AUDIT_NS_DEL    1330

The output format should look roughly:

type=NS_INIT msg=audit(1400217435.706:94): pid=524 uid=0 auid=4294967295 
ses=4294967295 subj=system_u:system_r:mount_t:s0 type=20000 old_snum=0 snum=a 
res=1
type=NS_DEL msg=audit(1400217435.730:95): pid=524 uid=0 auid=4294967295 
ses=4294967295 subj=system_u:system_r:mount_t:s0 type=20000 snum=a res=1

If non-zero, old_snum lists the namespace from which it was cloned.
The types are CLONE_NEW* listed in include/uapi/linux/sched.h.

Signed-off-by: Richard Guy Briggs <r...@redhat.com>
---
 fs/namespace.c             |    4 ++++
 include/linux/audit.h      |    8 ++++++++
 include/uapi/linux/audit.h |    2 ++
 ipc/namespace.c            |   10 ++++++++++
 kernel/audit.c             |   32 ++++++++++++++++++++++++++++++++
 kernel/pid_namespace.c     |   10 ++++++++++
 kernel/user_namespace.c    |    9 +++++++++
 kernel/utsname.c           |   10 ++++++++++
 net/core/net_namespace.c   |    5 +++++
 9 files changed, 90 insertions(+), 0 deletions(-)

diff --git a/fs/namespace.c b/fs/namespace.c
index 74348c4..f33efb3 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -24,6 +24,7 @@
 #include <linux/proc_ns.h>
 #include <linux/magic.h>
 #include <linux/bootmem.h>
+#include <linux/audit.h>
 #include "pnode.h"
 #include "internal.h"
 
@@ -2445,6 +2446,7 @@ dput_out:
 
 static void free_mnt_ns(struct mnt_namespace *ns)
 {
+       audit_log_ns_del(CLONE_NEWNS, ns->serial_num);
        proc_free_inum(ns->proc_inum);
        put_user_ns(ns->user_ns);
        kfree(ns);
@@ -2505,6 +2507,7 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, 
struct mnt_namespace *ns,
        new_ns = alloc_mnt_ns(user_ns);
        if (IS_ERR(new_ns))
                return new_ns;
+       audit_log_ns_init(CLONE_NEWNS, ns->serial_num, new_ns->serial_num);
 
        namespace_lock();
        /* First pass: copy the tree topology */
@@ -2568,6 +2571,7 @@ static struct mnt_namespace *create_mnt_ns(struct 
vfsmount *m)
                mnt->mnt_ns = new_ns;
                new_ns->root = mnt;
                list_add(&mnt->mnt_list, &new_ns->list);
+               audit_log_ns_init(CLONE_NEWNS, 0, new_ns->serial_num);
        } else {
                mntput(m);
        }
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 0ef404a..3ba8216 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -466,6 +466,9 @@ extern void             audit_log_key(struct audit_buffer 
*ab,
                                          char *key);
 extern void                audit_log_link_denied(const char *operation,
                                                  struct path *link);
+extern int                 audit_log_ns_init(int type, long long old_snum,
+                                             long long snum);
+extern int                 audit_log_ns_del(int type, long long snum);
 extern void                audit_log_lost(const char *message);
 #ifdef CONFIG_SECURITY
 extern void                audit_log_secctx(struct audit_buffer *ab, u32 
secid);
@@ -524,6 +527,11 @@ static inline void audit_log_key(struct audit_buffer *ab, 
char *key)
 static inline void audit_log_link_denied(const char *string,
                                         const struct path *link)
 { }
+static inline int audit_log_ns_init(int type, long long old_snum,
+                                   long long snum)
+{ }
+static inline int audit_log_ns_del(int type, long long snum)
+{ }
 static inline void audit_log_secctx(struct audit_buffer *ab, u32 secid)
 { }
 static inline int audit_log_task_context(struct audit_buffer *ab)
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index 573dc36..ac177fd 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -110,6 +110,8 @@
 #define AUDIT_SECCOMP          1326    /* Secure Computing event */
 #define AUDIT_PROCTITLE                1327    /* Proctitle emit event */
 #define AUDIT_FEATURE_CHANGE   1328    /* audit log listing feature changes */
+#define AUDIT_NS_INIT          1329    /* Record namespace instance creation */
+#define AUDIT_NS_DEL           1330    /* Record namespace instance deletion */
 
 #define AUDIT_AVC              1400    /* SE Linux avc denial or grant */
 #define AUDIT_SELINUX_ERR      1401    /* Internal SE Linux Errors */
diff --git a/ipc/namespace.c b/ipc/namespace.c
index 36ce7ff..5b2b897 100644
--- a/ipc/namespace.c
+++ b/ipc/namespace.c
@@ -13,6 +13,7 @@
 #include <linux/mount.h>
 #include <linux/user_namespace.h>
 #include <linux/proc_ns.h>
+#include <linux/audit.h>
 
 #include "util.h"
 
@@ -42,6 +43,7 @@ static struct ipc_namespace *create_ipc_ns(struct 
user_namespace *user_ns,
        atomic_inc(&nr_ipc_ns);
 
        ns->serial_num = ns_serial();
+       audit_log_ns_init(CLONE_NEWIPC, old_ns->serial_num, ns->serial_num);
 
        sem_init_ns(ns);
        msg_init_ns(ns);
@@ -121,6 +123,7 @@ static void free_ipc_ns(struct ipc_namespace *ns)
         */
        ipcns_notify(IPCNS_REMOVED);
        put_user_ns(ns->user_ns);
+       audit_log_ns_del(CLONE_NEWIPC, ns->serial_num);
        proc_free_inum(ns->proc_inum);
        kfree(ns);
 }
@@ -207,3 +210,10 @@ const struct proc_ns_operations ipcns_operations = {
        .inum           = ipcns_inum,
        .snum           = ipcns_snum,
 };
+
+static int __init ipc_namespaces_init(void)
+{
+       return audit_log_ns_init(CLONE_NEWIPC, 0, init_ipc_ns.serial_num);
+}
+
+late_initcall(ipc_namespaces_init);
diff --git a/kernel/audit.c b/kernel/audit.c
index 6452278..820e9f0 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1917,6 +1917,38 @@ out:
 }
 
 /**
+ * audit_log_ns_init - report a namespace instance creation
+ * @type: type of namespace instance created
+ * @old_snum: the serial number of the cloned namespace instance
+ * @snum: the serial number of the new namespace instance
+ */
+int audit_log_ns_init(int type, long long old_snum, long long snum)
+{
+       struct audit_buffer *ab;
+
+       audit_log_common_recv_msg(&ab, AUDIT_NS_INIT);
+       audit_log_format(ab, " type=%x old_snum=%llx snum=%llx res=1",
+                        type, old_snum, snum);
+       audit_log_end(ab);
+       return 0;
+}
+
+/**
+ * audit_log_ns_del - report a namespace instance deleted
+ * @type: type of namespace instance deleted
+ * @snum: the serial number of the namespace instance
+ */
+int audit_log_ns_del(int type, long long snum)
+{
+       struct audit_buffer *ab;
+
+       audit_log_common_recv_msg(&ab, AUDIT_NS_DEL);
+       audit_log_format(ab, " type=%x snum=%llx res=1", type, snum);
+       audit_log_end(ab);
+       return 0;
+}
+
+/**
  * audit_log_end - end one audit record
  * @ab: the audit_buffer
  *
diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c
index 5473364..d765b8d 100644
--- a/kernel/pid_namespace.c
+++ b/kernel/pid_namespace.c
@@ -18,6 +18,7 @@
 #include <linux/proc_ns.h>
 #include <linux/reboot.h>
 #include <linux/export.h>
+#include <linux/audit.h>
 
 struct pid_cache {
        int nr_ids;
@@ -110,6 +111,8 @@ static struct pid_namespace *create_pid_namespace(struct 
user_namespace *user_ns
                goto out_free_map;
 
        ns->serial_num = ns_serial();
+       audit_log_ns_init(CLONE_NEWPID, parent_pid_ns->serial_num,
+                         ns->serial_num);
 
        kref_init(&ns->kref);
        ns->level = level;
@@ -144,6 +147,7 @@ static void destroy_pid_namespace(struct pid_namespace *ns)
 {
        int i;
 
+       audit_log_ns_del(CLONE_NEWPID, ns->serial_num);
        proc_free_inum(ns->proc_inum);
        for (i = 0; i < PIDMAP_ENTRIES; i++)
                kfree(ns->pidmap[i].page);
@@ -395,3 +399,9 @@ static __init int pid_namespaces_init(void)
 }
 
 __initcall(pid_namespaces_init);
+
+static __init int pid_namespaces_late_init(void)
+{
+       return audit_log_ns_init(CLONE_NEWPID, 0, init_pid_ns.serial_num);
+}
+late_initcall(pid_namespaces_late_init);
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index d2e9365..d0927a0 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -22,6 +22,7 @@
 #include <linux/ctype.h>
 #include <linux/projid.h>
 #include <linux/fs_struct.h>
+#include <linux/audit.h>
 
 static struct kmem_cache *user_ns_cachep __read_mostly;
 
@@ -93,6 +94,7 @@ int create_user_ns(struct cred *new)
        }
 
        ns->serial_num = ns_serial();
+       audit_log_ns_init(CLONE_NEWUSER, parent_ns->serial_num, ns->serial_num);
 
        atomic_set(&ns->count, 1);
        /* Leave the new->user_ns reference with the new user namespace. */
@@ -138,6 +140,7 @@ void free_user_ns(struct user_namespace *ns)
 #ifdef CONFIG_PERSISTENT_KEYRINGS
                key_put(ns->persistent_keyring_register);
 #endif
+               audit_log_ns_del(CLONE_NEWUSER, ns->serial_num);
                proc_free_inum(ns->proc_inum);
                kmem_cache_free(user_ns_cachep, ns);
                ns = parent;
@@ -912,3 +915,9 @@ static __init int user_namespaces_init(void)
        return 0;
 }
 module_init(user_namespaces_init);
+
+static __init int user_namespaces_late_init(void)
+{
+       return audit_log_ns_init(CLONE_NEWUSER, 0, init_user_ns.serial_num);
+}
+late_initcall(user_namespaces_late_init);
diff --git a/kernel/utsname.c b/kernel/utsname.c
index ffeac1b..c6709b8 100644
--- a/kernel/utsname.c
+++ b/kernel/utsname.c
@@ -16,6 +16,7 @@
 #include <linux/slab.h>
 #include <linux/user_namespace.h>
 #include <linux/proc_ns.h>
+#include <linux/audit.h>
 
 static struct uts_namespace *create_uts_ns(void)
 {
@@ -49,6 +50,7 @@ static struct uts_namespace *clone_uts_ns(struct 
user_namespace *user_ns,
        }
 
        ns->serial_num = ns_serial();
+       audit_log_ns_init(CLONE_NEWUTS, old_ns->serial_num, ns->serial_num);
 
        down_read(&uts_sem);
        memcpy(&ns->name, &old_ns->name, sizeof(ns->name));
@@ -86,6 +88,7 @@ void free_uts_ns(struct kref *kref)
 
        ns = container_of(kref, struct uts_namespace, kref);
        put_user_ns(ns->user_ns);
+       audit_log_ns_del(CLONE_NEWUTS, ns->serial_num);
        proc_free_inum(ns->proc_inum);
        kfree(ns);
 }
@@ -148,3 +151,10 @@ const struct proc_ns_operations utsns_operations = {
        .inum           = utsns_inum,
        .snum           = utsns_snum,
 };
+
+static int __init uts_namespaces_init(void)
+{
+       return audit_log_ns_init(CLONE_NEWUTS, 0, init_uts_ns.serial_num);
+}
+
+late_initcall(uts_namespaces_init);
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index dd7c085..d508993 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -17,6 +17,7 @@
 #include <linux/user_namespace.h>
 #include <net/net_namespace.h>
 #include <net/netns/generic.h>
+#include <linux/audit.h>
 
 /*
  *     Our network namespace constructor/destructor lists
@@ -253,6 +254,8 @@ struct net *copy_net_ns(unsigned long flags,
        mutex_lock(&net_mutex);
        rv = setup_net(net, user_ns);
        if (rv == 0) {
+               audit_log_ns_init(CLONE_NEWNET, old_net->serial_num,
+                                 net->serial_num);
                rtnl_lock();
                list_add_tail_rcu(&net->list, &net_namespace_list);
                rtnl_unlock();
@@ -395,6 +398,7 @@ static __net_init int net_ns_net_init(struct net *net)
 
 static __net_exit void net_ns_net_exit(struct net *net)
 {
+       audit_log_ns_del(CLONE_NEWNET, net->serial_num);
        proc_free_inum(net->proc_inum);
 }
 
@@ -428,6 +432,7 @@ static int __init net_ns_init(void)
        if (setup_net(&init_net, &init_user_ns))
                panic("Could not setup the initial network namespace");
 
+       audit_log_ns_init(CLONE_NEWNET, 0, init_net.serial_num);
        rtnl_lock();
        list_add_tail_rcu(&init_net.list, &net_namespace_list);
        rtnl_unlock();
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to