diff options
author | Peter Hurley <peter@hurleysoftware.com> | 2016-01-09 22:55:27 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-01-27 16:41:04 -0800 |
commit | 309426ae69cdf35b0d72a8bd59a5081f8ddccddd (patch) | |
tree | ab1c875ae4e292d7e897d672923c7d5da1ec23aa | |
parent | eab25a5cd1f91b5c7991affe95f24ce188b8021f (diff) | |
download | lwn-309426ae69cdf35b0d72a8bd59a5081f8ddccddd.tar.gz lwn-309426ae69cdf35b0d72a8bd59a5081f8ddccddd.zip |
tty: audit: Remove icanon mode from call chain
The tty termios bits cannot change while n_tty_read() is in the
i/o loop; the termios_rwsem ensures mutual exclusion with termios
changes in n_tty_set_termios(). Check L_ICANON() directly and
eliminate icanon parameter.
NB: tty_audit_add_data() => tty_audit_buf_get() => tty_audit_buf_alloc()
is a single path; ie., tty_audit_buf_get() and tty_audit_buf_alloc()
have no other callers.
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/tty/n_tty.c | 6 | ||||
-rw-r--r-- | drivers/tty/tty_audit.c | 22 | ||||
-rw-r--r-- | include/linux/tty.h | 4 |
3 files changed, 14 insertions, 18 deletions
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index bacafda44bf3..4fbc5defbcd8 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -162,7 +162,7 @@ static int tty_copy_to_user(struct tty_struct *tty, void __user *to, int uncopied; if (n > size) { - tty_audit_add_data(tty, from, size, ldata->icanon); + tty_audit_add_data(tty, from, size); uncopied = copy_to_user(to, from, size); if (uncopied) return uncopied; @@ -171,7 +171,7 @@ static int tty_copy_to_user(struct tty_struct *tty, void __user *to, from = ldata->read_buf; } - tty_audit_add_data(tty, from, n, ldata->icanon); + tty_audit_add_data(tty, from, n); return copy_to_user(to, from, n); } @@ -1978,7 +1978,7 @@ static int copy_from_read_buf(struct tty_struct *tty, retval = copy_to_user(*b, from, n); n -= retval; is_eof = n == 1 && *from == EOF_CHAR(tty); - tty_audit_add_data(tty, from, n, ldata->icanon); + tty_audit_add_data(tty, from, n); smp_store_release(&ldata->read_tail, ldata->read_tail + n); /* Turn single EOF into zero-length read */ if (L_EXTPROC(tty) && ldata->icanon && is_eof && diff --git a/drivers/tty/tty_audit.c b/drivers/tty/tty_audit.c index ead924e4bd53..d2a004abeb5e 100644 --- a/drivers/tty/tty_audit.c +++ b/drivers/tty/tty_audit.c @@ -22,8 +22,7 @@ struct tty_audit_buf { unsigned char *data; /* Allocated size N_TTY_BUF_SIZE */ }; -static struct tty_audit_buf *tty_audit_buf_alloc(int major, int minor, - unsigned icanon) +static struct tty_audit_buf *tty_audit_buf_alloc(struct tty_struct *tty) { struct tty_audit_buf *buf; @@ -35,9 +34,9 @@ static struct tty_audit_buf *tty_audit_buf_alloc(int major, int minor, goto err_buf; atomic_set(&buf->count, 1); mutex_init(&buf->mutex); - buf->major = major; - buf->minor = minor; - buf->icanon = icanon; + buf->major = tty->driver->major; + buf->minor = tty->driver->minor_start + tty->index; + buf->icanon = !!L_ICANON(tty); buf->valid = 0; return buf; @@ -216,8 +215,7 @@ int tty_audit_push_current(void) * if TTY auditing is disabled or out of memory. Otherwise, return a new * reference to the buffer. */ -static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty, - unsigned icanon) +static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty) { struct tty_audit_buf *buf, *buf2; unsigned long flags; @@ -234,9 +232,7 @@ static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty, } spin_unlock_irqrestore(¤t->sighand->siglock, flags); - buf2 = tty_audit_buf_alloc(tty->driver->major, - tty->driver->minor_start + tty->index, - icanon); + buf2 = tty_audit_buf_alloc(tty); if (buf2 == NULL) { audit_log_lost("out of memory in TTY auditing"); return NULL; @@ -265,13 +261,13 @@ static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty, * * Audit @data of @size from @tty, if necessary. */ -void tty_audit_add_data(struct tty_struct *tty, const void *data, - size_t size, unsigned icanon) +void tty_audit_add_data(struct tty_struct *tty, const void *data, size_t size) { struct tty_audit_buf *buf; int major, minor; int audit_log_tty_passwd; unsigned long flags; + unsigned int icanon = !!L_ICANON(tty); if (unlikely(size == 0)) return; @@ -286,7 +282,7 @@ void tty_audit_add_data(struct tty_struct *tty, const void *data, if (!audit_log_tty_passwd && icanon && !L_ECHO(tty)) return; - buf = tty_audit_buf_get(tty, icanon); + buf = tty_audit_buf_get(tty); if (!buf) return; diff --git a/include/linux/tty.h b/include/linux/tty.h index 780adbfc6dce..c011dc205e5c 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -593,7 +593,7 @@ extern void __init n_tty_init(void); /* tty_audit.c */ #ifdef CONFIG_AUDIT extern void tty_audit_add_data(struct tty_struct *tty, const void *data, - size_t size, unsigned icanon); + size_t size); 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); @@ -601,7 +601,7 @@ extern void tty_audit_push(struct tty_struct *tty); extern int tty_audit_push_current(void); #else static inline void tty_audit_add_data(struct tty_struct *tty, const void *data, - size_t size, unsigned icanon) + size_t size) { } static inline void tty_audit_tiocsti(struct tty_struct *tty, char ch) |