Merge branch 'stable-4.7' of git://git.infradead.org/users/pcmoore/audit
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 29 Jun 2016 22:18:47 +0000 (15:18 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 29 Jun 2016 22:18:47 +0000 (15:18 -0700)
Pull audit fixes from Paul Moore:
 "Two small patches to fix audit problems in 4.7-rcX: the first fixes a
  potential kref leak, the second removes some header file noise.

  The first is an important bug fix that really should go in before 4.7
  is released, the second is not critical, but falls into the very-nice-
  to-have category so I'm including in the pull request.

  Both patches are straightforward, self-contained, and pass our
  testsuite without problem"

* 'stable-4.7' of git://git.infradead.org/users/pcmoore/audit:
  audit: move audit_get_tty to reduce scope and kabi changes
  audit: move calcs after alloc and check when logging set loginuid

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

diff --combined include/linux/audit.h
index 961a417d641e5221264e75b4d987fc3015607d41,b40ed5df5542f5049a28106353e909304831816f..e38e3fc13ea8764a66d4c84a6dea1bee3f4e630b
@@@ -26,7 -26,6 +26,6 @@@
  #include <linux/sched.h>
  #include <linux/ptrace.h>
  #include <uapi/linux/audit.h>
- #include <linux/tty.h>
  
  #define AUDIT_INO_UNSET ((unsigned long)-1)
  #define AUDIT_DEV_UNSET ((dev_t)-1)
@@@ -110,10 -109,6 +109,10 @@@ extern int audit_classify_compat_syscal
  /* maximized args number that audit_socketcall can process */
  #define AUDITSC_ARGS          6
  
 +/* bit values for ->signal->audit_tty */
 +#define AUDIT_TTY_ENABLE      BIT(0)
 +#define AUDIT_TTY_LOG_PASSWD  BIT(1)
 +
  struct filename;
  
  extern void audit_log_session_info(struct audit_buffer *ab);
@@@ -348,23 -343,6 +347,6 @@@ static inline unsigned int audit_get_se
        return tsk->sessionid;
  }
  
- static inline struct tty_struct *audit_get_tty(struct task_struct *tsk)
- {
-       struct tty_struct *tty = NULL;
-       unsigned long flags;
-       spin_lock_irqsave(&tsk->sighand->siglock, flags);
-       if (tsk->signal)
-               tty = tty_kref_get(tsk->signal->tty);
-       spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
-       return tty;
- }
- static inline void audit_put_tty(struct tty_struct *tty)
- {
-       tty_kref_put(tty);
- }
  extern void __audit_ipc_obj(struct kern_ipc_perm *ipcp);
  extern void __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, umode_t mode);
  extern void __audit_bprm(struct linux_binprm *bprm);
@@@ -522,12 -500,6 +504,6 @@@ static inline unsigned int audit_get_se
  {
        return -1;
  }
- static inline struct tty_struct *audit_get_tty(struct task_struct *tsk)
- {
-       return NULL;
- }
- static inline void audit_put_tty(struct tty_struct *tty)
- { }
  static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp)
  { }
  static inline void audit_ipc_set_perm(unsigned long qbytes, uid_t uid,
diff --combined kernel/audit.c
index 22bb4f24f071df56dbddcb3f84fbf3ad2e8c63bc,d5971010e44a2616c1f59c703425a91e6b8f67ed..8d528f9930dad639c22c797da715545db717ce6e
@@@ -807,16 -807,6 +807,16 @@@ static int audit_set_feature(struct sk_
        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;
                }
                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;
                if (err == 1) { /* match or error */
                        err = 0;
                        if (msg_type == AUDIT_USER_TTY) {
 -                              err = tty_audit_push_current();
 +                              err = tty_audit_push();
                                if (err)
                                        break;
                        }
                break;
        case AUDIT_TTY_GET: {
                struct audit_tty_status s;
 -              struct task_struct *tsk = current;
 +              unsigned int t;
  
 -              spin_lock(&tsk->sighand->siglock);
 -              s.enabled = tsk->signal->audit_tty;
 -              s.log_passwd = tsk->signal->audit_tty_log_passwd;
 -              spin_unlock(&tsk->sighand->siglock);
 +              t = READ_ONCE(current->signal->audit_tty);
 +              s.enabled = t & AUDIT_TTY_ENABLE;
 +              s.log_passwd = !!(t & AUDIT_TTY_LOG_PASSWD);
  
                audit_send_reply(skb, seq, AUDIT_TTY_GET, 0, 0, &s, sizeof(s));
                break;
        }
        case AUDIT_TTY_SET: {
                struct audit_tty_status s, old;
 -              struct task_struct *tsk = current;
                struct audit_buffer     *ab;
 +              unsigned int t;
  
                memset(&s, 0, sizeof(s));
                /* guard against past and future API changes */
                    (s.log_passwd != 0 && s.log_passwd != 1))
                        err = -EINVAL;
  
 -              spin_lock(&tsk->sighand->siglock);
 -              old.enabled = tsk->signal->audit_tty;
 -              old.log_passwd = tsk->signal->audit_tty_log_passwd;
 -              if (!err) {
 -                      tsk->signal->audit_tty = s.enabled;
 -                      tsk->signal->audit_tty_log_passwd = s.log_passwd;
 +              if (err)
 +                      t = READ_ONCE(current->signal->audit_tty);
 +              else {
 +                      t = s.enabled | (-s.log_passwd & AUDIT_TTY_LOG_PASSWD);
 +                      t = xchg(&current->signal->audit_tty, t);
                }
 -              spin_unlock(&tsk->sighand->siglock);
 +              old.enabled = t & AUDIT_TTY_ENABLE;
 +              old.log_passwd = !!(t & AUDIT_TTY_LOG_PASSWD);
  
                audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE);
                audit_log_format(ab, " op=tty_set old-enabled=%d new-enabled=%d"
@@@ -1883,6 -1866,23 +1883,23 @@@ out_null
        audit_log_format(ab, " exe=(null)");
  }
  
+ struct tty_struct *audit_get_tty(struct task_struct *tsk)
+ {
+       struct tty_struct *tty = NULL;
+       unsigned long flags;
+       spin_lock_irqsave(&tsk->sighand->siglock, flags);
+       if (tsk->signal)
+               tty = tty_kref_get(tsk->signal->tty);
+       spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
+       return tty;
+ }
+ void audit_put_tty(struct tty_struct *tty)
+ {
+       tty_kref_put(tty);
+ }
  void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk)
  {
        const struct cred *cred;
diff --combined kernel/auditsc.c
index 62ab53d7619cfb249154276e40a38d1e69a906f6,60a354eed2fa246a18c4c139de25e20e3291b32e..2672d105cffcdaf7703d9f655e7338dd0b102cc0
@@@ -63,7 -63,6 +63,6 @@@
  #include <asm/unistd.h>
  #include <linux/security.h>
  #include <linux/list.h>
- #include <linux/tty.h>
  #include <linux/binfmts.h>
  #include <linux/highmem.h>
  #include <linux/syscalls.h>
@@@ -1985,14 -1984,15 +1984,15 @@@ static void audit_log_set_loginuid(kuid
        if (!audit_enabled)
                return;
  
+       ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOGIN);
+       if (!ab)
+               return;
        uid = from_kuid(&init_user_ns, task_uid(current));
        oldloginuid = from_kuid(&init_user_ns, koldloginuid);
        loginuid = from_kuid(&init_user_ns, kloginuid),
        tty = audit_get_tty(current);
  
-       ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOGIN);
-       if (!ab)
-               return;
        audit_log_format(ab, "pid=%d uid=%u", task_pid_nr(current), uid);
        audit_log_task_context(ab);
        audit_log_format(ab, " old-auid=%u auid=%u tty=%s old-ses=%u ses=%u res=%d",
@@@ -2416,8 -2416,8 +2416,8 @@@ void __audit_seccomp(unsigned long sysc
                return;
        audit_log_task(ab);
        audit_log_format(ab, " sig=%ld arch=%x syscall=%ld compat=%d ip=0x%lx code=0x%x",
 -                       signr, syscall_get_arch(), syscall, is_compat_task(),
 -                       KSTK_EIP(current), code);
 +                       signr, syscall_get_arch(), syscall,
 +                       in_compat_syscall(), KSTK_EIP(current), code);
        audit_log_end(ab);
  }
  
This page took 0.138232 seconds and 5 git commands to generate.