]> Pileus Git - ~andy/linux/blobdiff - kernel/audit.c
audit: rework AUDIT_TTY_SET to only grab spin_lock once
[~andy/linux] / kernel / audit.c
index ab2e3d8288f2a1b23a238b68efa41acf164a6afd..b1d24a035ec998c24f27ac192c5a448823fd65a3 100644 (file)
@@ -991,19 +991,24 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                struct audit_tty_status s, old;
                struct task_struct *tsk = current;
                struct audit_buffer     *ab;
-               int res = 0;
+
+               memset(&s, 0, sizeof(s));
+               /* guard against past and future API changes */
+               memcpy(&s, data, min_t(size_t, sizeof(s), nlmsg_len(nlh)));
+               /* check if new data is valid */
+               if ((s.enabled != 0 && s.enabled != 1) ||
+                   (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;
+               }
                spin_unlock(&tsk->sighand->siglock);
 
-               memset(&s, 0, sizeof(s));
-               /* guard against past and future API changes */
-               memcpy(&s, data, min_t(size_t, sizeof(s), nlmsg_len(nlh)));
-               if ((s.enabled == 0 || s.enabled == 1) &&
-                   (s.log_passwd == 0 || s.log_passwd == 1))
-                       res = 1;
                audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE);
                audit_log_format(ab, " op=tty_set"
                                 " old-enabled=%d old-log_passwd=%d"
@@ -1011,15 +1016,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                                 " res=%d",
                                 old.enabled, old.log_passwd,
                                 s.enabled, s.log_passwd,
-                                res);
+                                !err);
                audit_log_end(ab);
-               if (res) {
-                       spin_lock(&tsk->sighand->siglock);
-                       tsk->signal->audit_tty = s.enabled;
-                       tsk->signal->audit_tty_log_passwd = s.log_passwd;
-                       spin_unlock(&tsk->sighand->siglock);
-               } else
-                       return -EINVAL;
                break;
        }
        default: