Since update_lsm_rules will update all audit_krule, we still
have to make audit_rules_list global. this patch add a field
user_ns to struct audit_krule to point out which user namespace
this audit rule belongs to.

Signed-off-by: Gao feng <gaof...@cn.fujitsu.com>
---
 include/linux/audit.h |  1 +
 kernel/auditfilter.c  | 19 +++++++++++++++----
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index f16db07..885e842 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -59,6 +59,7 @@ struct audit_krule {
        struct audit_field      *inode_f; /* quick access to an inode field */
        struct audit_watch      *watch; /* associated watch */
        struct audit_tree       *tree;  /* associated watched tree */
+       struct user_namespace   *user_ns; /* belongs to this user namespace */
        struct list_head        rlist;  /* entry in audit_{watch,tree}.rules 
list */
        struct list_head        list;   /* for AUDIT_LIST* purposes only */
        u64                     prio;
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index dbf05a9..cf7fe98 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -822,6 +822,7 @@ struct audit_entry *audit_dupe_rule(struct audit_krule *old)
        new->buflen = old->buflen;
        new->inode_f = old->inode_f;
        new->field_count = old->field_count;
+       new->user_ns = old->user_ns;
 
        /*
         * note that we are OK with not refcounting here; audit_match_tree()
@@ -965,6 +966,7 @@ static inline int audit_add_rule(struct user_namespace *ns,
                        entry->rule.prio = --prio_low;
        }
 
+       entry->rule.user_ns = get_user_ns(ns);
        if (entry->rule.flags & AUDIT_FILTER_PREPEND) {
                list_add(&entry->rule.list,
                         &audit_rules_list[entry->rule.listnr]);
@@ -1026,6 +1028,7 @@ static inline int audit_del_rule(struct user_namespace 
*ns,
 
        list_del_rcu(&e->list);
        list_del(&e->rule.list);
+       put_user_ns(e->rule.user_ns);
        call_rcu(&e->rcu, audit_free_rule_rcu);
 
 #ifdef CONFIG_AUDITSYSCALL
@@ -1048,7 +1051,8 @@ out:
 
 /* List rules using struct audit_rule.  Exists for backward
  * compatibility with userspace. */
-static void audit_list(int pid, int seq, struct sk_buff_head *q)
+static void audit_list(struct user_namespace *ns,
+                      int pid, int seq, struct sk_buff_head *q)
 {
        struct sk_buff *skb;
        struct audit_krule *r;
@@ -1060,6 +1064,9 @@ static void audit_list(int pid, int seq, struct 
sk_buff_head *q)
                list_for_each_entry(r, &audit_rules_list[i], list) {
                        struct audit_rule *rule;
 
+                       if (r->user_ns != ns)
+                               continue;
+
                        rule = audit_krule_to_rule(r);
                        if (unlikely(!rule))
                                break;
@@ -1076,7 +1083,8 @@ static void audit_list(int pid, int seq, struct 
sk_buff_head *q)
 }
 
 /* List rules using struct audit_rule_data. */
-static void audit_list_rules(int pid, int seq, struct sk_buff_head *q)
+static void audit_list_rules(struct user_namespace *ns,
+                            int pid, int seq, struct sk_buff_head *q)
 {
        struct sk_buff *skb;
        struct audit_krule *r;
@@ -1088,6 +1096,9 @@ static void audit_list_rules(int pid, int seq, struct 
sk_buff_head *q)
                list_for_each_entry(r, &audit_rules_list[i], list) {
                        struct audit_rule_data *data;
 
+                       if (r->user_ns != ns)
+                               continue;
+
                        data = audit_krule_to_data(r);
                        if (unlikely(!data))
                                break;
@@ -1172,9 +1183,9 @@ int audit_receive_filter(int type, int pid, int seq, void 
*data,
 
                mutex_lock(&audit_filter_mutex);
                if (type == AUDIT_LIST)
-                       audit_list(pid, seq, &dest->q);
+                       audit_list(ns, pid, seq, &dest->q);
                else
-                       audit_list_rules(pid, seq, &dest->q);
+                       audit_list_rules(ns, pid, seq, &dest->q);
                mutex_unlock(&audit_filter_mutex);
 
                tsk = kthread_run(audit_send_list, dest, "audit_send_list");
-- 
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