tty: audit: Simplify first-use allocation
authorPeter Hurley <peter@hurleysoftware.com>
Sun, 10 Jan 2016 06:55:36 +0000 (22:55 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 28 Jan 2016 00:41:04 +0000 (16:41 -0800)
The first-use tty audit buffer allocation is a potential race
amongst multiple attempts at 'first-use'; only one 'winner' is
acceptable.

The successful buffer assignment occurs if tty_audit_buf == NULL
(which will also be the return from cmpxchg()); otherwise, another
racer 'won' and this buffer allocation is freed.

Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/tty_audit.c

index 71ba8baee14d4a85079a4661659186a506105bbb..6e33e41ec74d5cbdeba3700f8aac4d087c615edb 100644 (file)
@@ -181,30 +181,22 @@ int tty_audit_push(void)
  */
 static struct tty_audit_buf *tty_audit_buf_get(void)
 {
-       struct tty_audit_buf *buf, *buf2;
-       unsigned long flags;
+       struct tty_audit_buf *buf;
 
        buf = current->signal->tty_audit_buf;
        if (buf)
                return buf;
 
-       buf2 = tty_audit_buf_alloc();
-       if (buf2 == NULL) {
+       buf = tty_audit_buf_alloc();
+       if (buf == NULL) {
                audit_log_lost("out of memory in TTY auditing");
                return NULL;
        }
 
-       spin_lock_irqsave(&current->sighand->siglock, flags);
-       buf = current->signal->tty_audit_buf;
-       if (!buf) {
-               current->signal->tty_audit_buf = buf2;
-               buf = buf2;
-               buf2 = NULL;
-       }
-       spin_unlock_irqrestore(&current->sighand->siglock, flags);
-       if (buf2)
-               tty_audit_buf_free(buf2);
-       return buf;
+       /* Race to use this buffer, free it if another wins */
+       if (cmpxchg(&current->signal->tty_audit_buf, NULL, buf) != NULL)
+               tty_audit_buf_free(buf);
+       return current->signal->tty_audit_buf;
 }
 
 /**