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 <[email protected]>
---
 drivers/tty/n_tty.c     |  6 +++---
 drivers/tty/tty_audit.c | 22 +++++++++-------------
 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 b09c0c1..a3ad312 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -163,7 +163,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;
@@ -172,7 +172,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);
 }
 
@@ -2008,7 +2008,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 ead924e..d2a004a 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(&current->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 70f3a9c1..f8a20a8 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -603,7 +603,7 @@ extern void n_tty_inherit_ops(struct tty_ldisc_ops *ops);
 /* 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);
@@ -611,7 +611,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)
-- 
2.6.3

--
Linux-audit mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/linux-audit

Reply via email to