]> Pileus Git - ~andy/linux/blobdiff - drivers/tty/tty_audit.c
audit: use spin_lock_irqsave/restore in audit tty code
[~andy/linux] / drivers / tty / tty_audit.c
index 6953dc82850cb278fd99da209e560021d4d0c1e8..755d418019c8850b2a3688d875fc042a9ceaad59 100644 (file)
@@ -60,24 +60,22 @@ static void tty_audit_buf_put(struct tty_audit_buf *buf)
                tty_audit_buf_free(buf);
 }
 
-static void tty_audit_log(const char *description, struct task_struct *tsk,
-                         kuid_t loginuid, unsigned sessionid, int major,
-                         int minor, unsigned char *data, size_t size)
+static void tty_audit_log(const char *description, int major, int minor,
+                         unsigned char *data, size_t size)
 {
        struct audit_buffer *ab;
+       struct task_struct *tsk = current;
+       uid_t uid = from_kuid(&init_user_ns, task_uid(tsk));
+       uid_t loginuid = from_kuid(&init_user_ns, audit_get_loginuid(tsk));
+       u32 sessionid = audit_get_sessionid(tsk);
 
        ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_TTY);
        if (ab) {
                char name[sizeof(tsk->comm)];
-               kuid_t uid = task_uid(tsk);
-
-               audit_log_format(ab, "%s pid=%u uid=%u auid=%u ses=%u "
-                                "major=%d minor=%d comm=", description,
-                                tsk->pid,
-                                from_kuid(&init_user_ns, uid),
-                                from_kuid(&init_user_ns, loginuid),
-                                sessionid,
-                                major, minor);
+
+               audit_log_format(ab, "%s pid=%u uid=%u auid=%u ses=%u major=%d"
+                                " minor=%d comm=", description, tsk->pid, uid,
+                                loginuid, sessionid, major, minor);
                get_task_comm(name, tsk);
                audit_log_untrustedstring(ab, name);
                audit_log_format(ab, " data=");
@@ -90,11 +88,9 @@ static void tty_audit_log(const char *description, struct task_struct *tsk,
  *     tty_audit_buf_push      -       Push buffered data out
  *
  *     Generate an audit message from the contents of @buf, which is owned by
- *     @tsk with @loginuid.  @buf->mutex must be locked.
+ *     the current task.  @buf->mutex must be locked.
  */
-static void tty_audit_buf_push(struct task_struct *tsk, kuid_t loginuid,
-                              unsigned int sessionid,
-                              struct tty_audit_buf *buf)
+static void tty_audit_buf_push(struct tty_audit_buf *buf)
 {
        if (buf->valid == 0)
                return;
@@ -102,24 +98,10 @@ static void tty_audit_buf_push(struct task_struct *tsk, kuid_t loginuid,
                buf->valid = 0;
                return;
        }
-       tty_audit_log("tty", tsk, loginuid, sessionid, buf->major, buf->minor,
-                     buf->data, buf->valid);
+       tty_audit_log("tty", buf->major, buf->minor, buf->data, buf->valid);
        buf->valid = 0;
 }
 
-/**
- *     tty_audit_buf_push_current      -       Push buffered data out
- *
- *     Generate an audit message from the contents of @buf, which is owned by
- *     the current task.  @buf->mutex must be locked.
- */
-static void tty_audit_buf_push_current(struct tty_audit_buf *buf)
-{
-       kuid_t auid = audit_get_loginuid(current);
-       unsigned int sessionid = audit_get_sessionid(current);
-       tty_audit_buf_push(current, auid, sessionid, buf);
-}
-
 /**
  *     tty_audit_exit  -       Handle a task exit
  *
@@ -129,16 +111,17 @@ static void tty_audit_buf_push_current(struct tty_audit_buf *buf)
 void tty_audit_exit(void)
 {
        struct tty_audit_buf *buf;
+       unsigned long flags;
 
-       spin_lock_irq(&current->sighand->siglock);
+       spin_lock_irqsave(&current->sighand->siglock, flags);
        buf = current->signal->tty_audit_buf;
        current->signal->tty_audit_buf = NULL;
-       spin_unlock_irq(&current->sighand->siglock);
+       spin_unlock_irqrestore(&current->sighand->siglock, flags);
        if (!buf)
                return;
 
        mutex_lock(&buf->mutex);
-       tty_audit_buf_push_current(buf);
+       tty_audit_buf_push(buf);
        mutex_unlock(&buf->mutex);
 
        tty_audit_buf_put(buf);
@@ -151,9 +134,11 @@ void tty_audit_exit(void)
  */
 void tty_audit_fork(struct signal_struct *sig)
 {
-       spin_lock_irq(&current->sighand->siglock);
+       unsigned long flags;
+
+       spin_lock_irqsave(&current->sighand->siglock, flags);
        sig->audit_tty = current->signal->audit_tty;
-       spin_unlock_irq(&current->sighand->siglock);
+       spin_unlock_irqrestore(&current->sighand->siglock, flags);
 }
 
 /**
@@ -163,20 +148,21 @@ void tty_audit_tiocsti(struct tty_struct *tty, char ch)
 {
        struct tty_audit_buf *buf;
        int major, minor, should_audit;
+       unsigned long flags;
 
-       spin_lock_irq(&current->sighand->siglock);
+       spin_lock_irqsave(&current->sighand->siglock, flags);
        should_audit = current->signal->audit_tty;
        buf = current->signal->tty_audit_buf;
        if (buf)
                atomic_inc(&buf->count);
-       spin_unlock_irq(&current->sighand->siglock);
+       spin_unlock_irqrestore(&current->sighand->siglock, flags);
 
        major = tty->driver->major;
        minor = tty->driver->minor_start + tty->index;
        if (buf) {
                mutex_lock(&buf->mutex);
                if (buf->major == major && buf->minor == minor)
-                       tty_audit_buf_push_current(buf);
+                       tty_audit_buf_push(buf);
                mutex_unlock(&buf->mutex);
                tty_audit_buf_put(buf);
        }
@@ -187,24 +173,20 @@ void tty_audit_tiocsti(struct tty_struct *tty, char ch)
 
                auid = audit_get_loginuid(current);
                sessionid = audit_get_sessionid(current);
-               tty_audit_log("ioctl=TIOCSTI", current, auid, sessionid, major,
-                             minor, &ch, 1);
+               tty_audit_log("ioctl=TIOCSTI", major, minor, &ch, 1);
        }
 }
 
 /**
- * tty_audit_push_task -       Flush task's pending audit data
- * @tsk:               task pointer
- * @loginuid:          sender login uid
- * @sessionid:         sender session id
+ * tty_audit_push_current -    Flush current's pending audit data
  *
- * Called with a ref on @tsk held. Try to lock sighand and get a
- * reference to the tty audit buffer if available.
+ * Try to lock sighand and get a reference to the tty audit buffer if available.
  * Flush the buffer or return an appropriate error code.
  */
-int tty_audit_push_task(struct task_struct *tsk, kuid_t loginuid, u32 sessionid)
+int tty_audit_push_current(void)
 {
        struct tty_audit_buf *buf = ERR_PTR(-EPERM);
+       struct task_struct *tsk = current;
        unsigned long flags;
 
        if (!lock_task_sighand(tsk, &flags))
@@ -225,7 +207,7 @@ int tty_audit_push_task(struct task_struct *tsk, kuid_t loginuid, u32 sessionid)
                return PTR_ERR(buf);
 
        mutex_lock(&buf->mutex);
-       tty_audit_buf_push(tsk, loginuid, sessionid, buf);
+       tty_audit_buf_push(buf);
        mutex_unlock(&buf->mutex);
 
        tty_audit_buf_put(buf);
@@ -243,10 +225,11 @@ static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty,
                unsigned icanon)
 {
        struct tty_audit_buf *buf, *buf2;
+       unsigned long flags;
 
        buf = NULL;
        buf2 = NULL;
-       spin_lock_irq(&current->sighand->siglock);
+       spin_lock_irqsave(&current->sighand->siglock, flags);
        if (likely(!current->signal->audit_tty))
                goto out;
        buf = current->signal->tty_audit_buf;
@@ -254,7 +237,7 @@ static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty,
                atomic_inc(&buf->count);
                goto out;
        }
-       spin_unlock_irq(&current->sighand->siglock);
+       spin_unlock_irqrestore(&current->sighand->siglock, flags);
 
        buf2 = tty_audit_buf_alloc(tty->driver->major,
                                   tty->driver->minor_start + tty->index,
@@ -264,7 +247,7 @@ static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty,
                return NULL;
        }
 
-       spin_lock_irq(&current->sighand->siglock);
+       spin_lock_irqsave(&current->sighand->siglock, flags);
        if (!current->signal->audit_tty)
                goto out;
        buf = current->signal->tty_audit_buf;
@@ -276,7 +259,7 @@ static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty,
        atomic_inc(&buf->count);
        /* Fall through */
  out:
-       spin_unlock_irq(&current->sighand->siglock);
+       spin_unlock_irqrestore(&current->sighand->siglock, flags);
        if (buf2)
                tty_audit_buf_free(buf2);
        return buf;
@@ -309,7 +292,7 @@ void tty_audit_add_data(struct tty_struct *tty, unsigned char *data,
        minor = tty->driver->minor_start + tty->index;
        if (buf->major != major || buf->minor != minor
            || buf->icanon != icanon) {
-               tty_audit_buf_push_current(buf);
+               tty_audit_buf_push(buf);
                buf->major = major;
                buf->minor = minor;
                buf->icanon = icanon;
@@ -325,7 +308,7 @@ void tty_audit_add_data(struct tty_struct *tty, unsigned char *data,
                data += run;
                size -= run;
                if (buf->valid == N_TTY_BUF_SIZE)
-                       tty_audit_buf_push_current(buf);
+                       tty_audit_buf_push(buf);
        } while (size != 0);
        mutex_unlock(&buf->mutex);
        tty_audit_buf_put(buf);
@@ -339,16 +322,17 @@ void tty_audit_add_data(struct tty_struct *tty, unsigned char *data,
 void tty_audit_push(struct tty_struct *tty)
 {
        struct tty_audit_buf *buf;
+       unsigned long flags;
 
-       spin_lock_irq(&current->sighand->siglock);
+       spin_lock_irqsave(&current->sighand->siglock, flags);
        if (likely(!current->signal->audit_tty)) {
-               spin_unlock_irq(&current->sighand->siglock);
+               spin_unlock_irqrestore(&current->sighand->siglock, flags);
                return;
        }
        buf = current->signal->tty_audit_buf;
        if (buf)
                atomic_inc(&buf->count);
-       spin_unlock_irq(&current->sighand->siglock);
+       spin_unlock_irqrestore(&current->sighand->siglock, flags);
 
        if (buf) {
                int major, minor;
@@ -357,7 +341,7 @@ void tty_audit_push(struct tty_struct *tty)
                minor = tty->driver->minor_start + tty->index;
                mutex_lock(&buf->mutex);
                if (buf->major == major && buf->minor == minor)
-                       tty_audit_buf_push_current(buf);
+                       tty_audit_buf_push(buf);
                mutex_unlock(&buf->mutex);
                tty_audit_buf_put(buf);
        }