This patch just make the audit filter list per user namespace.

Signed-off-by: Gao feng <gaof...@cn.fujitsu.com>
---
 include/linux/user_namespace.h |  2 ++
 kernel/audit.c                 |  4 ++++
 kernel/auditfilter.c           | 23 +++++++----------------
 kernel/auditsc.c               | 12 +++++++++---
 kernel/user.c                  | 19 +++++++++++++++++++
 5 files changed, 41 insertions(+), 19 deletions(-)

diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
index c870e28..d1dd5b9 100644
--- a/include/linux/user_namespace.h
+++ b/include/linux/user_namespace.h
@@ -6,6 +6,7 @@
 #include <linux/sched.h>
 #include <linux/err.h>
 #include <linux/skbuff.h>
+#include <uapi/linux/audit.h>
 
 #define UID_GID_MAP_MAX_EXTENTS 5
 
@@ -33,6 +34,7 @@ struct audit_ctrl {
 #define AUDIT_INODE_BUCKETS    32
        struct list_head        inode_hash[AUDIT_INODE_BUCKETS];
        struct list_head        tree_list;
+       struct list_head        filter_list[AUDIT_NR_FILTERS];
        bool                    ever_enabled;
 };
 #endif
diff --git a/kernel/audit.c b/kernel/audit.c
index a0544b1..1ca1714 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1609,6 +1609,10 @@ void audit_set_user_ns(struct user_namespace *ns)
        for (i = 0; i < AUDIT_INODE_BUCKETS; i++)
                INIT_LIST_HEAD(&ns->audit.inode_hash[i]);
 
+       if (ns != &init_user_ns)
+               for (i = 0; i < AUDIT_NR_FILTERS; i++)
+                       INIT_LIST_HEAD(&ns->audit.filter_list[i]);
+
        INIT_LIST_HEAD(&ns->audit.tree_list);
 
        ns->audit.initialized = AUDIT_INITIALIZED;
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index 3c8fb2e..dbf05a9 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -44,18 +44,6 @@
  *             be written directly provided audit_filter_mutex is held.
  */
 
-/* Audit filter lists, defined in <linux/audit.h> */
-struct list_head audit_filter_list[AUDIT_NR_FILTERS] = {
-       LIST_HEAD_INIT(audit_filter_list[0]),
-       LIST_HEAD_INIT(audit_filter_list[1]),
-       LIST_HEAD_INIT(audit_filter_list[2]),
-       LIST_HEAD_INIT(audit_filter_list[3]),
-       LIST_HEAD_INIT(audit_filter_list[4]),
-       LIST_HEAD_INIT(audit_filter_list[5]),
-#if AUDIT_NR_FILTERS != 6
-#error Fix audit_filter_list initialiser
-#endif
-};
 static struct list_head audit_rules_list[AUDIT_NR_FILTERS] = {
        LIST_HEAD_INIT(audit_rules_list[0]),
        LIST_HEAD_INIT(audit_rules_list[1]),
@@ -908,7 +896,7 @@ static struct audit_entry *audit_find_rule(struct 
user_namespace *ns,
                }
                goto out;
        } else {
-               *p = list = &audit_filter_list[entry->rule.listnr];
+               *p = list = &ns->audit.filter_list[entry->rule.listnr];
        }
 
        list_for_each_entry(e, list, list)
@@ -1416,10 +1404,12 @@ int audit_filter_user(void)
 {
        enum audit_state state = AUDIT_DISABLED;
        struct audit_entry *e;
+       struct user_namespace *ns = current_user_ns();
        int ret = 1;
 
        rcu_read_lock();
-       list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_USER], list) 
{
+       list_for_each_entry_rcu(e, &ns->audit.filter_list[AUDIT_FILTER_USER],
+                               list) {
                if (audit_filter_user_rules(&e->rule, &state)) {
                        if (state == AUDIT_DISABLED)
                                ret = 0;
@@ -1434,13 +1424,14 @@ int audit_filter_user(void)
 int audit_filter_type(int type)
 {
        struct audit_entry *e;
+       struct user_namespace *ns = current_user_ns();
        int result = 0;
 
        rcu_read_lock();
-       if (list_empty(&audit_filter_list[AUDIT_FILTER_TYPE]))
+       if (list_empty(&ns->audit.filter_list[AUDIT_FILTER_TYPE]))
                goto unlock_and_return;
 
-       list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TYPE],
+       list_for_each_entry_rcu(e, &ns->audit.filter_list[AUDIT_FILTER_TYPE],
                                list) {
                int i;
                for (i = 0; i < e->rule.field_count; i++) {
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 55bd99e..29c3e05 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -844,9 +844,11 @@ static enum audit_state audit_filter_task(struct 
task_struct *tsk, char **key)
 {
        struct audit_entry *e;
        enum audit_state   state;
+       struct user_namespace *ns = current_user_ns();
 
        rcu_read_lock();
-       list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TASK], list) 
{
+       list_for_each_entry_rcu(e, &ns->audit.filter_list[AUDIT_FILTER_TASK],
+                               list) {
                if (audit_filter_rules(tsk, &e->rule, NULL, NULL,
                                       &state, true)) {
                        if (state == AUDIT_RECORD_CONTEXT)
@@ -949,6 +951,7 @@ static inline struct audit_context 
*audit_get_context(struct task_struct *tsk,
                                                      long return_code)
 {
        struct audit_context *context = tsk->audit_context;
+       struct user_namespace *ns = task_cred_xxx(tsk, user_ns);
 
        if (!context)
                return NULL;
@@ -973,7 +976,8 @@ static inline struct audit_context 
*audit_get_context(struct task_struct *tsk,
                context->return_code  = return_code;
 
        if (context->in_syscall && !context->dummy) {
-               audit_filter_syscall(tsk, context, 
&audit_filter_list[AUDIT_FILTER_EXIT]);
+               audit_filter_syscall(tsk, context,
+                               &ns->audit.filter_list[AUDIT_FILTER_EXIT]);
                audit_filter_inodes(tsk, context);
        }
 
@@ -1759,6 +1763,7 @@ void __audit_syscall_entry(int arch, int major,
        struct task_struct *tsk = current;
        struct audit_context *context = tsk->audit_context;
        enum audit_state     state;
+       struct user_namespace *ns = current_user_ns();
 
        if (!context)
                return;
@@ -1779,7 +1784,8 @@ void __audit_syscall_entry(int arch, int major,
        context->dummy = !audit_n_rules;
        if (!context->dummy && state == AUDIT_BUILD_CONTEXT) {
                context->prio = 0;
-               state = audit_filter_syscall(tsk, context, 
&audit_filter_list[AUDIT_FILTER_ENTRY]);
+               state = audit_filter_syscall(tsk, context,
+                       &ns->audit.filter_list[AUDIT_FILTER_ENTRY]);
        }
        if (state == AUDIT_DISABLED)
                return;
diff --git a/kernel/user.c b/kernel/user.c
index 69b4c3d..637bd39 100644
--- a/kernel/user.c
+++ b/kernel/user.c
@@ -51,6 +51,25 @@ struct user_namespace init_user_ns = {
        .owner = GLOBAL_ROOT_UID,
        .group = GLOBAL_ROOT_GID,
        .proc_inum = PROC_USER_INIT_INO,
+#ifdef CONFIG_AUDIT
+       .audit = {
+               .filter_list[0] =
+                       LIST_HEAD_INIT(init_user_ns.audit.filter_list[0]),
+               .filter_list[1] =
+                       LIST_HEAD_INIT(init_user_ns.audit.filter_list[1]),
+               .filter_list[2] =
+                       LIST_HEAD_INIT(init_user_ns.audit.filter_list[2]),
+               .filter_list[3] =
+                       LIST_HEAD_INIT(init_user_ns.audit.filter_list[3]),
+               .filter_list[4] =
+                       LIST_HEAD_INIT(init_user_ns.audit.filter_list[4]),
+               .filter_list[5] =
+                       LIST_HEAD_INIT(init_user_ns.audit.filter_list[5]),
+#if AUDIT_NR_FILTERS != 6
+#error Fix audit_filter_list of init_user_ns initialiser
+#endif
+       },
+#endif
        .may_mount_sysfs = true,
        .may_mount_proc = true,
 };
-- 
1.8.1.4

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