Re: KASAN: user-memory-access Write in n_tty_set_termios

From: Tetsuo Handa
Date: Fri Apr 06 2018 - 06:07:18 EST


On 2018/04/05 19:31, Tetsuo Handa wrote:
> Hello.
>
> I manually simplified the reproducer. Since the bug is timing dependent,
> this reproducer might fail to reproducer the bug. Anyway, I guess that
> there is a race condition between
>
> vfree(ldata);
> tty->disc_data = NULL;
>
> at n_tty_close() by something (ioctl(TIOCVHANGUP) ?) and
>
> struct n_tty_data *ldata = tty->disc_data;
>
> if (!old || (old->c_lflag ^ tty->termios.c_lflag) & (ICANON | EXTPROC)) {
> bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE);
>
> at n_tty_set_termios() by ioctl(TCSETS), for the report says that ldata == NULL
> ("Write of size 512 at addr 0000000000001060").

I confirmed that ioctl(TIOCVHANGUP) versus ioctl(TCSETS) can race.
We need some lock for protecting tty->disc_data.

--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -1861,6 +1861,7 @@ static void n_tty_close(struct tty_struct *tty)

vfree(ldata);
tty->disc_data = NULL;
+ WARN_ON(1);
}

/**

ioctl(TIOCVHANGUP):
[ 75.176171] RIP: 0010:n_tty_close+0x34/0x40 /* drivers/tty/n_tty.c:1863 */
[ 75.176193] Call Trace:
[ 75.176200] tty_ldisc_kill+0x15/0x30 /* drivers/tty/tty_ldisc.c:641 */
[ 75.176204] tty_ldisc_hangup+0xfa/0x1c0 /* drivers/tty/tty_ldisc.c:758 */
[ 75.176209] __tty_hangup.part.26+0x16b/0x280 /* drivers/tty/tty_io.c:623 */
[ 75.176216] tty_ioctl+0x61f/0x950 /* drivers/tty/tty_io.c:2585 */
[ 75.176244] do_vfs_ioctl+0xa7/0x6d0 /* fs/ioctl.c:686 */
[ 75.176257] ksys_ioctl+0x6b/0x80 /* fs/ioctl.c:701 */
[ 75.176266] SyS_ioctl+0x5/0x10 /* fs/ioctl.c:706 */
[ 75.176268] do_syscall_64+0x6e/0x270 /* arch/x86/entry/common.c:287 */

ioctl(TCSETS):
[ 75.783367] BUG: unable to handle kernel paging request at 0000000000001060
[ 75.934024] RIP: 0010:n_tty_set_termios+0x17c/0x2a0 /* drivers/tty/n_tty.c:1766 */
[ 75.950549] Call Trace:
[ 75.952733] tty_set_termios+0x18a/0x200 /* drivers/tty/tty_ioctl.c:342 */
[ 75.954915] set_termios+0x14a/0x250 /* drivers/tty/tty_ioctl.c:414 */
[ 75.956823] tty_mode_ioctl+0x42e/0x4f0 /* drivers/tty/tty_ioctl.c:749 */
[ 75.958632] tty_ioctl+0x128/0x950 /* drivers/tty/tty_io.c:2655 */
[ 75.968883] do_vfs_ioctl+0xa7/0x6d0 /* fs/ioctl.c:686 */
[ 75.972892] ksys_ioctl+0x6b/0x80 /* fs/ioctl.c:701 */
[ 75.977031] SyS_ioctl+0x5/0x10 /* fs/ioctl.c:706 */
[ 75.977036] do_syscall_64+0x6e/0x270 /* arch/x86/entry/common.c:287 */