tty: audit: Simplify first-use allocation
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>
This commit is contained in:
Родитель
5493090fc2
Коммит
fbaa122718
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Загрузка…
Ссылка в новой задаче