From b50819f437c094b4beb2e8684fbe12bbe79fb331 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sat, 9 Jan 2016 22:55:30 -0800 Subject: tty: audit: Ignore current association for audit push In canonical read mode, each line read and logged is pushed separately with tty_audit_push(). For all single-threaded processes and multi-threaded processes reading from only one tty, this patch has no effect; the last line read will still be the entry pushed to the audit log because the tty association cannot have changed between tty_audit_add_data() and tty_audit_push(). For multi-threaded processes reading from different ttys concurrently, the audit log will have mixed log entries anyway. Consider two ttys audited concurrently: CPU0 CPU1 ---------- ------------ tty_audit_add_data(ttyA) tty_audit_add_data(ttyB) tty_audit_push() tty_audit_add_data(ttyB) tty_audit_push() This patch will now cause the ttyB output to be split into separate audit log entries. However, this possibility is equally likely without this patch: CPU0 CPU1 ---------- ------------ tty_audit_add_data(ttyB) tty_audit_add_data(ttyA) tty_audit_push() tty_audit_add_data(ttyB) tty_audit_push() Mixed canonical and non-canonical reads have similar races. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 4fbc5de..8272069 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -2072,7 +2072,7 @@ static int canon_copy_from_read_buf(struct tty_struct *tty, ldata->line_start = ldata->read_tail; else ldata->push = 0; - tty_audit_push(tty); + tty_audit_push(); } return 0; } diff --git a/drivers/tty/tty_audit.c b/drivers/tty/tty_audit.c index 5f65653..5ae4839 100644 --- a/drivers/tty/tty_audit.c +++ b/drivers/tty/tty_audit.c @@ -313,9 +313,9 @@ void tty_audit_add_data(struct tty_struct *tty, const void *data, size_t size) /** * tty_audit_push - Push buffered data out * - * Make sure no audit data is pending for @tty on the current process. + * Make sure no audit data is pending on the current process. */ -void tty_audit_push(struct tty_struct *tty) +void tty_audit_push(void) { struct tty_audit_buf *buf; unsigned long flags; @@ -331,13 +331,8 @@ void tty_audit_push(struct tty_struct *tty) spin_unlock_irqrestore(¤t->sighand->siglock, flags); if (buf) { - int major, minor; - - major = tty->driver->major; - minor = tty->driver->minor_start + tty->index; mutex_lock(&buf->mutex); - if (buf->major == major && buf->minor == minor) - tty_audit_buf_push(buf); + tty_audit_buf_push(buf); mutex_unlock(&buf->mutex); tty_audit_buf_put(buf); } diff --git a/include/linux/tty.h b/include/linux/tty.h index c011dc2..83d74dc 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -597,7 +597,7 @@ extern void tty_audit_add_data(struct tty_struct *tty, const void *data, extern void tty_audit_exit(void); extern void tty_audit_fork(struct signal_struct *sig); extern void tty_audit_tiocsti(struct tty_struct *tty, char ch); -extern void tty_audit_push(struct tty_struct *tty); +extern void tty_audit_push(void); extern int tty_audit_push_current(void); #else static inline void tty_audit_add_data(struct tty_struct *tty, const void *data, @@ -613,7 +613,7 @@ static inline void tty_audit_exit(void) static inline void tty_audit_fork(struct signal_struct *sig) { } -static inline void tty_audit_push(struct tty_struct *tty) +static inline void tty_audit_push(void) { } static inline int tty_audit_push_current(void) -- cgit v0.10.2