TTY: fix atime/mtime regression [Linux 3.9]

This Linux kernel change "TTY: fix atime/mtime regression" is included in the Linux 3.9 release. This change is authored by Jiri Slaby <jslaby [at] suse.cz> on Fri Apr 26 13:48:53 2013 +0200. The commit for this change in Linux stable tree is 37b7f3c (patch).

TTY: fix atime/mtime regression

In commit b0de59b5733d ("TTY: do not update atime/mtime on read/write")
we removed timestamps from tty inodes to fix a security issue and waited
if something breaks.  Well, 'w', the utility to find out logged users
and their inactivity time broke.  It shows that users are inactive since
the time they logged in.

To revert to the old behaviour while still preventing attackers to
guess the password length, we update the timestamps in one-minute
intervals by this patch.

Signed-off-by: Jiri Slaby <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>

There are 18 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 drivers/tty/tty_io.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 05400ac..b045268 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -941,6 +941,14 @@ void start_tty(struct tty_struct *tty)

 EXPORT_SYMBOL(start_tty);

+static void tty_update_time(struct timespec *time)
+{
+   unsigned long sec = get_seconds();
+   sec -= sec % 60;
+   if ((long)(sec - time->tv_sec) > 0)
+       time->tv_sec = sec;
+}
+
 /**
  * tty_read    -   read method for tty device files
  * @file: pointer to tty file
@@ -960,10 +968,11 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count,
            loff_t *ppos)
 {
    int i;
+   struct inode *inode = file_inode(file);
    struct tty_struct *tty = file_tty(file);
    struct tty_ldisc *ld;

-   if (tty_paranoia_check(tty, file_inode(file), "tty_read"))
+   if (tty_paranoia_check(tty, inode, "tty_read"))
        return -EIO;
    if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags)))
        return -EIO;
@@ -977,6 +986,9 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count,
        i = -EIO;
    tty_ldisc_deref(ld);

+   if (i > 0)
+       tty_update_time(&inode->i_atime);
+
    return i;
 }

@@ -1077,8 +1089,10 @@ static inline ssize_t do_tty_write(
            break;
        cond_resched();
    }
-   if (written)
+   if (written) {
+       tty_update_time(&file_inode(file)->i_mtime);
        ret = written;
+   }
 out:
    tty_write_unlock(tty);
    return ret;

Leave a Reply

Your email address will not be published. Required fields are marked *