From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932518AbcAJFAi (ORCPT ); Sun, 10 Jan 2016 00:00:38 -0500 Received: from mail-pa0-f43.google.com ([209.85.220.43]:35159 "EHLO mail-pa0-f43.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756857AbcAJE7Z (ORCPT ); Sat, 9 Jan 2016 23:59:25 -0500 From: Peter Hurley To: Greg Kroah-Hartman Cc: Jiri Slaby , linux-audit@redhat.com, linux-kernel@vger.kernel.org, Peter Hurley Subject: [RESEND][PATCH 12/15] tty: audit: Simplify first-use allocation Date: Sat, 9 Jan 2016 20:59:05 -0800 Message-Id: <1452401948-30790-13-git-send-email-peter@hurleysoftware.com> X-Mailer: git-send-email 2.7.0 In-Reply-To: <1452401948-30790-1-git-send-email-peter@hurleysoftware.com> References: <1447207560-16410-1-git-send-email-peter@hurleysoftware.com> <1452401948-30790-1-git-send-email-peter@hurleysoftware.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- drivers/tty/tty_audit.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/drivers/tty/tty_audit.c b/drivers/tty/tty_audit.c index 71ba8ba..6e33e41 100644 --- a/drivers/tty/tty_audit.c +++ b/drivers/tty/tty_audit.c @@ -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(¤t->sighand->siglock, flags); - buf = current->signal->tty_audit_buf; - if (!buf) { - current->signal->tty_audit_buf = buf2; - buf = buf2; - buf2 = NULL; - } - spin_unlock_irqrestore(¤t->sighand->siglock, flags); - if (buf2) - tty_audit_buf_free(buf2); - return buf; + /* Race to use this buffer, free it if another wins */ + if (cmpxchg(¤t->signal->tty_audit_buf, NULL, buf) != NULL) + tty_audit_buf_free(buf); + return current->signal->tty_audit_buf; } /** -- 2.7.0