AUDIT: Optimise the audit-disabled case for discarding user messages
David Woodhouse [Wed, 22 Jun 2005 13:56:47 +0000 (14:56 +0100)]
Also exempt USER_AVC message from being discarded to preserve
existing behaviour for SE Linux.

Signed-off-by: David Woodhouse <dwmw2@infradead.org>

include/linux/audit.h
kernel/audit.c
kernel/auditsc.c

index 5d1a9dd..77adef6 100644 (file)
@@ -51,7 +51,8 @@
 #define AUDIT_WATCH_LIST       1009    /* List all file/dir watches */
 #define AUDIT_SIGNAL_INFO      1010    /* Get info about sender of signal to auditd */
 
-#define AUDIT_FIRST_USER_MSG   1100    /* Userspace messages uninteresting to kernel */
+#define AUDIT_FIRST_USER_MSG   1100    /* Userspace messages mostly uninteresting to kernel */
+#define AUDIT_USER_AVC         1107    /* We filter this differently */
 #define AUDIT_LAST_USER_MSG    1199
  
 #define AUDIT_DAEMON_START      1200    /* Daemon startup record */
@@ -235,7 +236,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(struct task_struct *tsk, int type);
+extern int audit_filter_user(int pid, int type);
 #else
 #define audit_alloc(t) ({ 0; })
 #define audit_free(t) do { ; } while (0)
@@ -252,7 +253,7 @@ extern int audit_filter_user(struct task_struct *tsk, 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(struct ({ 1; })
+#define audit_filter_user(p,t) ({ 1; })
 #endif
 
 #ifdef CONFIG_AUDIT
index c1ab8db..09a3758 100644 (file)
@@ -429,25 +429,21 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                break;
        case AUDIT_USER:
        case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG:
-               read_lock(&tasklist_lock);
-               tsk = find_task_by_pid(pid);
-               if (tsk)
-                       get_task_struct(tsk);
-               read_unlock(&tasklist_lock);
-               if (!tsk)
-                       return -ESRCH;
-
-               if (audit_enabled && audit_filter_user(tsk, msg_type)) {
-                           ab = audit_log_start(NULL, msg_type);
-                           if (ab) {
-                                   audit_log_format(ab,
-                                                    "user pid=%d uid=%u auid=%u msg='%.1024s'",
-                                                    pid, uid, loginuid, (char *)data);
-                                   audit_set_pid(ab, pid);
-                                   audit_log_end(ab);
-                           }
+               if (!audit_enabled && msg_type != AUDIT_USER_AVC)
+                       return 0;
+
+               err = audit_filter_user(pid, msg_type);
+               if (err == 1) {
+                       err = 0;
+                       ab = audit_log_start(NULL, msg_type);
+                       if (ab) {
+                               audit_log_format(ab,
+                                                "user pid=%d uid=%u auid=%u msg='%.1024s'",
+                                                pid, uid, loginuid, (char *)data);
+                               audit_set_pid(ab, pid);
+                               audit_log_end(ab);
+                       }
                }
-               put_task_struct(tsk);
                break;
        case AUDIT_ADD:
        case AUDIT_DEL:
index cb8a449..fc858b0 100644 (file)
@@ -530,22 +530,33 @@ static enum audit_state audit_filter_syscall(struct task_struct *tsk,
        return AUDIT_BUILD_CONTEXT;
 }
 
-int audit_filter_user(struct task_struct *tsk, int type)
+int audit_filter_user(int pid, int type)
 {
+       struct task_struct *tsk;
        struct audit_entry *e;
        enum audit_state   state;
+       int ret = 1;
 
-       if (audit_pid && tsk->pid == audit_pid)
-               return AUDIT_DISABLED;
+       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)) {
-                       rcu_read_unlock();
-                       return state != AUDIT_DISABLED;
+                       if (state == AUDIT_DISABLED)
+                               ret = 0;
+                       break;
                }
        }
        rcu_read_unlock();
+       put_task_struct(tsk);
+
        return 1; /* Audit by default */
 
 }