| From: Peter Hurley <peter@hurleysoftware.com> |
| Date: Fri, 27 Nov 2015 14:30:21 -0500 |
| Subject: tty: Prevent ldisc drivers from re-using stale tty fields |
| |
| commit dd42bf1197144ede075a9d4793123f7689e164bc upstream. |
| |
| Line discipline drivers may mistakenly misuse ldisc-related fields |
| when initializing. For example, a failure to initialize tty->receive_room |
| in the N_GIGASET_M101 line discipline was recently found and fixed [1]. |
| Now, the N_X25 line discipline has been discovered accessing the previous |
| line discipline's already-freed private data [2]. |
| |
| Harden the ldisc interface against misuse by initializing revelant |
| tty fields before instancing the new line discipline. |
| |
| [1] |
| commit fd98e9419d8d622a4de91f76b306af6aa627aa9c |
| Author: Tilman Schmidt <tilman@imap.cc> |
| Date: Tue Jul 14 00:37:13 2015 +0200 |
| |
| isdn/gigaset: reset tty->receive_room when attaching ser_gigaset |
| |
| [2] Report from Sasha Levin <sasha.levin@oracle.com> |
| [ 634.336761] ================================================================== |
| [ 634.338226] BUG: KASAN: use-after-free in x25_asy_open_tty+0x13d/0x490 at addr ffff8800a743efd0 |
| [ 634.339558] Read of size 4 by task syzkaller_execu/8981 |
| [ 634.340359] ============================================================================= |
| [ 634.341598] BUG kmalloc-512 (Not tainted): kasan: bad access detected |
| ... |
| [ 634.405018] Call Trace: |
| [ 634.405277] dump_stack (lib/dump_stack.c:52) |
| [ 634.405775] print_trailer (mm/slub.c:655) |
| [ 634.406361] object_err (mm/slub.c:662) |
| [ 634.406824] kasan_report_error (mm/kasan/report.c:138 mm/kasan/report.c:236) |
| [ 634.409581] __asan_report_load4_noabort (mm/kasan/report.c:279) |
| [ 634.411355] x25_asy_open_tty (drivers/net/wan/x25_asy.c:559 (discriminator 1)) |
| [ 634.413997] tty_ldisc_open.isra.2 (drivers/tty/tty_ldisc.c:447) |
| [ 634.414549] tty_set_ldisc (drivers/tty/tty_ldisc.c:567) |
| [ 634.415057] tty_ioctl (drivers/tty/tty_io.c:2646 drivers/tty/tty_io.c:2879) |
| [ 634.423524] do_vfs_ioctl (fs/ioctl.c:43 fs/ioctl.c:607) |
| [ 634.427491] SyS_ioctl (fs/ioctl.c:622 fs/ioctl.c:613) |
| [ 634.427945] entry_SYSCALL_64_fastpath (arch/x86/entry/entry_64.S:188) |
| |
| Cc: Tilman Schmidt <tilman@imap.cc> |
| Cc: Sasha Levin <sasha.levin@oracle.com> |
| Signed-off-by: Peter Hurley <peter@hurleysoftware.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| drivers/tty/tty_ldisc.c | 7 +++++++ |
| 1 file changed, 7 insertions(+) |
| |
| --- a/drivers/tty/tty_ldisc.c |
| +++ b/drivers/tty/tty_ldisc.c |
| @@ -414,6 +414,10 @@ EXPORT_SYMBOL_GPL(tty_ldisc_flush); |
| * they are not on hot paths so a little discipline won't do |
| * any harm. |
| * |
| + * The line discipline-related tty_struct fields are reset to |
| + * prevent the ldisc driver from re-using stale information for |
| + * the new ldisc instance. |
| + * |
| * Locking: takes termios_rwsem |
| */ |
| |
| @@ -422,6 +426,9 @@ static void tty_set_termios_ldisc(struct |
| down_write(&tty->termios_rwsem); |
| tty->termios.c_line = num; |
| up_write(&tty->termios_rwsem); |
| + |
| + tty->disc_data = NULL; |
| + tty->receive_room = 0; |
| } |
| |
| /** |