Merge tag 'trace-v4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux...
[deliverable/linux.git] / kernel / audit.c
index 2651e423b2dc5450da4bc3788c2a2688cc767ff6..22bb4f24f071df56dbddcb3f84fbf3ad2e8c63bc 100644 (file)
@@ -64,7 +64,6 @@
 #include <linux/security.h>
 #endif
 #include <linux/freezer.h>
-#include <linux/tty.h>
 #include <linux/pid_namespace.h>
 #include <net/netns/generic.h>
 
@@ -430,7 +429,6 @@ restart:
                                        attempts, audit_pid);
                                set_current_state(TASK_INTERRUPTIBLE);
                                schedule();
-                               __set_current_state(TASK_RUNNING);
                                goto restart;
                        }
                }
@@ -809,6 +807,16 @@ static int audit_set_feature(struct sk_buff *skb)
        return 0;
 }
 
+static int audit_replace(pid_t pid)
+{
+       struct sk_buff *skb = audit_make_reply(0, 0, AUDIT_REPLACE, 0, 0,
+                                              &pid, sizeof(pid));
+
+       if (!skb)
+               return -ENOMEM;
+       return netlink_unicast(audit_sock, skb, audit_nlk_portid, 0);
+}
+
 static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 {
        u32                     seq;
@@ -870,9 +878,17 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                }
                if (s.mask & AUDIT_STATUS_PID) {
                        int new_pid = s.pid;
+                       pid_t requesting_pid = task_tgid_vnr(current);
 
-                       if ((!new_pid) && (task_tgid_vnr(current) != audit_pid))
+                       if ((!new_pid) && (requesting_pid != audit_pid)) {
+                               audit_log_config_change("audit_pid", new_pid, audit_pid, 0);
                                return -EACCES;
+                       }
+                       if (audit_pid && new_pid &&
+                           audit_replace(requesting_pid) != -ECONNREFUSED) {
+                               audit_log_config_change("audit_pid", new_pid, audit_pid, 0);
+                               return -EEXIST;
+                       }
                        if (audit_enabled != AUDIT_OFF)
                                audit_log_config_change("audit_pid", new_pid, audit_pid, 1);
                        audit_pid = new_pid;
@@ -1323,15 +1339,14 @@ static inline void audit_get_stamp(struct audit_context *ctx,
 static long wait_for_auditd(long sleep_time)
 {
        DECLARE_WAITQUEUE(wait, current);
-       set_current_state(TASK_UNINTERRUPTIBLE);
-       add_wait_queue_exclusive(&audit_backlog_wait, &wait);
 
        if (audit_backlog_limit &&
-           skb_queue_len(&audit_skb_queue) > audit_backlog_limit)
+           skb_queue_len(&audit_skb_queue) > audit_backlog_limit) {
+               add_wait_queue_exclusive(&audit_backlog_wait, &wait);
+               set_current_state(TASK_UNINTERRUPTIBLE);
                sleep_time = schedule_timeout(sleep_time);
-
-       __set_current_state(TASK_RUNNING);
-       remove_wait_queue(&audit_backlog_wait, &wait);
+               remove_wait_queue(&audit_backlog_wait, &wait);
+       }
 
        return sleep_time;
 }
@@ -1872,21 +1887,14 @@ void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk)
 {
        const struct cred *cred;
        char comm[sizeof(tsk->comm)];
-       char *tty;
+       struct tty_struct *tty;
 
        if (!ab)
                return;
 
        /* tsk == current */
        cred = current_cred();
-
-       spin_lock_irq(&tsk->sighand->siglock);
-       if (tsk->signal && tsk->signal->tty && tsk->signal->tty->name)
-               tty = tsk->signal->tty->name;
-       else
-               tty = "(none)";
-       spin_unlock_irq(&tsk->sighand->siglock);
-
+       tty = audit_get_tty(tsk);
        audit_log_format(ab,
                         " ppid=%d pid=%d auid=%u uid=%u gid=%u"
                         " euid=%u suid=%u fsuid=%u"
@@ -1902,11 +1910,11 @@ void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk)
                         from_kgid(&init_user_ns, cred->egid),
                         from_kgid(&init_user_ns, cred->sgid),
                         from_kgid(&init_user_ns, cred->fsgid),
-                        tty, audit_get_sessionid(tsk));
-
+                        tty ? tty_name(tty) : "(none)",
+                        audit_get_sessionid(tsk));
+       audit_put_tty(tty);
        audit_log_format(ab, " comm=");
        audit_log_untrustedstring(ab, get_task_comm(comm, tsk));
-
        audit_log_d_path_exe(ab, tsk->mm);
        audit_log_task_context(ab);
 }
This page took 0.035369 seconds and 5 git commands to generate.