]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
AUDIT: Clean up user message filtering
authorDavid Woodhouse <dwmw2@shinybook.infradead.org>
Fri, 24 Jun 2005 13:14:05 +0000 (14:14 +0100)
committerDavid Woodhouse <dwmw2@shinybook.infradead.org>
Fri, 24 Jun 2005 13:14:05 +0000 (14:14 +0100)
Don't look up the task by its pid and then use the syscall filtering
helper. Just implement our own filter helper which operates solely on
the information in the netlink_skb_parms.

Signed-off-by: David Woodhouse <dwmw2@infradead.org>
include/linux/audit.h
kernel/audit.c
kernel/auditsc.c

index 2f56546eb248ecbe674000b433a212bb0f889b96..38999f827a36ffcaf1ea87ee4fe242b211cc42c6 100644 (file)
@@ -205,6 +205,7 @@ struct audit_sig_info {
 struct audit_buffer;
 struct audit_context;
 struct inode;
+struct netlink_skb_parms;
 
 #define AUDITSC_INVALID 0
 #define AUDITSC_SUCCESS 1
@@ -236,7 +237,7 @@ extern int audit_socketcall(int nargs, unsigned long *args);
 extern int audit_sockaddr(int len, void *addr);
 extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt);
 extern void audit_signal_info(int sig, struct task_struct *t);
-extern int audit_filter_user(int pid, int type);
+extern int audit_filter_user(struct netlink_skb_parms *cb, int type);
 #else
 #define audit_alloc(t) ({ 0; })
 #define audit_free(t) do { ; } while (0)
@@ -253,7 +254,7 @@ extern int audit_filter_user(int pid, int type);
 #define audit_sockaddr(len, addr) ({ 0; })
 #define audit_avc_path(dentry, mnt) ({ 0; })
 #define audit_signal_info(s,t) do { ; } while (0)
-#define audit_filter_user(p,t) ({ 1; })
+#define audit_filter_user(cb,t) ({ 1; })
 #endif
 
 #ifdef CONFIG_AUDIT
index 9af947a63ed1a2e77d1e49f6594013dd1e44dd4d..6f1784dd80afe917e233167d4b1886ba8b4da031 100644 (file)
@@ -434,7 +434,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                if (!audit_enabled && msg_type != AUDIT_USER_AVC)
                        return 0;
 
-               err = audit_filter_user(pid, msg_type);
+               err = audit_filter_user(&NETLINK_CB(skb), msg_type);
                if (err == 1) {
                        err = 0;
                        ab = audit_log_start(NULL, GFP_KERNEL, msg_type);
index 7b123f0a94816bce96dd5865169924eaaa175d56..34a990223c9e4e2d61ab870518cde04dc9767c63 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/personality.h>
 #include <linux/time.h>
 #include <linux/kthread.h>
+#include <linux/netlink.h>
 #include <asm/unistd.h>
 
 /* 0 = no checking
@@ -530,35 +531,62 @@ static enum audit_state audit_filter_syscall(struct task_struct *tsk,
        return AUDIT_BUILD_CONTEXT;
 }
 
-int audit_filter_user(int pid, int type)
+static int audit_filter_user_rules(struct netlink_skb_parms *cb,
+                             struct audit_rule *rule,
+                             enum audit_state *state)
+{
+       int i;
+
+       for (i = 0; i < rule->field_count; i++) {
+               u32 field  = rule->fields[i] & ~AUDIT_NEGATE;
+               u32 value  = rule->values[i];
+               int result = 0;
+
+               switch (field) {
+               case AUDIT_PID:
+                       result = (cb->creds.pid == value);
+                       break;
+               case AUDIT_UID:
+                       result = (cb->creds.uid == value);
+                       break;
+               case AUDIT_GID:
+                       result = (cb->creds.gid == value);
+                       break;
+               case AUDIT_LOGINUID:
+                       result = (cb->loginuid == value);
+                       break;
+               }
+
+               if (rule->fields[i] & AUDIT_NEGATE)
+                       result = !result;
+               if (!result)
+                       return 0;
+       }
+       switch (rule->action) {
+       case AUDIT_NEVER:    *state = AUDIT_DISABLED;       break;
+       case AUDIT_POSSIBLE: *state = AUDIT_BUILD_CONTEXT;  break;
+       case AUDIT_ALWAYS:   *state = AUDIT_RECORD_CONTEXT; break;
+       }
+       return 1;
+}
+
+int audit_filter_user(struct netlink_skb_parms *cb, int type)
 {
-       struct task_struct *tsk;
        struct audit_entry *e;
        enum audit_state   state;
        int ret = 1;
 
-       read_lock(&tasklist_lock);
-       tsk = find_task_by_pid(pid);
-       if (tsk)
-               get_task_struct(tsk);
-       read_unlock(&tasklist_lock);
-
-       if (!tsk)
-               return -ESRCH;
-
        rcu_read_lock();
        list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_USER], list) {
-               if (audit_filter_rules(tsk, &e->rule, NULL, &state)) {
+               if (audit_filter_user_rules(cb, &e->rule, &state)) {
                        if (state == AUDIT_DISABLED)
                                ret = 0;
                        break;
                }
        }
        rcu_read_unlock();
-       put_task_struct(tsk);
 
        return ret; /* Audit by default */
-
 }
 
 /* This should be called with task_lock() held. */