linux/drivers/tty
Yan.Gao c9cd57bf57 tty: Protect disc_data in n_tty_close and n_tty_flush_buffer
n_tty_flush_buffer can happen in parallel with n_tty_close that the
tty->disc_data will be set to NULL. n_tty_flush_buffer accesses
tty->disc_data, so we must prevent n_tty_close clear tty->disc_data
while n_tty_flush_buffer  has a non-NULL view of tty->disc_data.

So we need to make sure that accesses to disc_data are atomic using
tty->termios_rwsem.

There is an example I meet:
When n_tty_flush_buffer accesses tty struct, the disc_data is right.
However, then reset_buffer_flags accesses tty->disc_data, disc_data
become NULL, So kernel crash when accesses tty->disc_data->real_tail.
I guess there could be another thread change tty->disc_data to NULL,
and during N_TTY line discipline, n_tty_close will set tty->disc_data
to be NULL. So use tty->termios_rwsem to protect disc_data between close
and flush_buffer.

IP: reset_buffer_flags+0x9/0xf0
PGD 0 P4D 0
Oops: 0002 [#1] SMP
CPU: 23 PID: 2087626 Comm: (agetty) Kdump: loaded Tainted: G
Hardware name: UNISINSIGHT X3036P-G3/ST01M2C7S, BIOS 2.00.13 01/11/2019
task: ffff9c4e9da71e80 task.stack: ffffb30cfe898000
RIP: 0010:reset_buffer_flags+0x9/0xf0
RSP: 0018:ffffb30cfe89bca8 EFLAGS: 00010246
RAX: ffff9c4e9da71e80 RBX: ffff9c368d1bac00 RCX: 0000000000000000
RDX: 0000000000000000 RSI: ffff9c4ea17b50f0 RDI: 0000000000000000
RBP: ffffb30cfe89bcc8 R08: 0000000000000100 R09: 0000000000000001
R10: 0000000000000001 R11: 0000000000000000 R12: ffff9c368d1bacc0
R13: ffff9c20cfd18428 R14: ffff9c4ea17b50f0 R15: ffff9c368d1bac00
FS:  00007f9fbbe97940(0000) GS:ffff9c375c740000(0000)
knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000002260 CR3: 0000002f72233003 CR4: 00000000007606e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
PKRU: 55555554
Call Trace:
? n_tty_flush_buffer+0x2a/0x60
tty_buffer_flush+0x76/0x90
tty_ldisc_flush+0x22/0x40
vt_ioctl+0x5a7/0x10b0
? n_tty_ioctl_helper+0x27/0x110
tty_ioctl+0xef/0x8c0
do_vfs_ioctl+0xa7/0x5e0
? __audit_syscall_entry+0xaf/0x100
? syscall_trace_enter+0x1d0/0x2b0
SyS_ioctl+0x79/0x90
do_syscall_64+0x6c/0x1b0
entry_SYSCALL64_slow_path+0x25/0x25

n_tty_flush_buffer			--->tty->disc_data is OK
	->reset_buffer_flags		 -->tty->disc_data is NULL

Signed-off-by: Yan.Gao <gao.yanB@h3c.com>
Reviewed-by: Xianting Tian <tian.xianting@h3c.com>
Link: https://lore.kernel.org/r/20201210022507.30729-1-gao.yanB@h3c.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-01-07 16:34:26 +01:00
..
hvc tty_port: drop last traces of low_latency 2021-01-07 16:17:32 +01:00
ipwireless tty_port: drop last traces of low_latency 2021-01-07 16:17:32 +01:00
serdev tty: serdev: core: Provide missing description for 'owner' 2020-11-06 10:49:27 +01:00
serial serial: stm32: update transmission complete error message in shutdown 2021-01-07 16:19:29 +01:00
vt vt: drop old FONT ioctls 2021-01-07 16:17:31 +01:00
amiserial.c tty_port: drop last traces of low_latency 2021-01-07 16:17:32 +01:00
cyclades.c treewide: Remove uninitialized_var() usage 2020-07-16 12:35:15 -07:00
ehv_bytechan.c tty: evh_bytechan: Fix out of bounds accesses 2020-03-17 23:40:31 +11:00
goldfish.c tty: goldfish: use __raw_writel()/__raw_readl() 2020-10-28 13:44:43 +01:00
isicom.c treewide: Remove uninitialized_var() usage 2020-07-16 12:35:15 -07:00
Kconfig printk changes for 5.11 2020-12-16 10:45:11 -08:00
Makefile printk changes for 5.11 2020-12-16 10:45:11 -08:00
mips_ejtag_fdc.c treewide: Use fallthrough pseudo-keyword 2020-08-23 17:36:59 -05:00
moxa.c remove ioremap_nocache and devm_ioremap_nocache 2020-01-06 09:45:59 +01:00
moxa.h tty: fix spelling mistake 2020-06-27 16:21:20 +02:00
mxser.c tty_port: drop last traces of low_latency 2021-01-07 16:17:32 +01:00
mxser.h
n_gsm.c tty: n_gsm: Demote obvious abuse of kernel-doc and supply other missing docss 2020-11-06 10:54:04 +01:00
n_hdlc.c Linux 5.9-rc3 2020-08-31 07:19:25 +02:00
n_null.c
n_r3964.c treewide: Use fallthrough pseudo-keyword 2020-08-23 17:36:59 -05:00
n_tracerouter.c
n_tracesink.c
n_tracesink.h tty: n_tracesink: Use the correct style for SPDX License Identifier 2020-03-18 13:01:31 +01:00
n_tty.c tty: Protect disc_data in n_tty_close and n_tty_flush_buffer 2021-01-07 16:34:26 +01:00
nozomi.c tty: nozomi: remove unneeded break 2020-10-28 13:44:43 +01:00
pty.c drivers:tty:pty: Fix a race causing data loss on close 2021-01-07 16:30:55 +01:00
rocket_int.h
rocket.c Merge 5.7-rc3 into tty-next 2020-04-27 09:33:21 +02:00
rocket.h
synclink_gt.c tty_port: drop last traces of low_latency 2021-01-07 16:17:32 +01:00
sysrq.c tty/sysrq: Extend the sysrq_key_table to cover capital letters 2020-10-02 14:56:06 +02:00
tty_audit.c tty: tty_audit: Demote non-conformant kernel-doc headers 2020-11-06 10:54:04 +01:00
tty_baudrate.c tty: tty_baudrate: Add missing description for 'tty' 2020-11-06 10:49:27 +01:00
tty_buffer.c tty: tty_buffer: Add missing description for 'limit' 2020-11-06 10:49:27 +01:00
tty_io.c drivers:tty:pty: Fix a race causing data loss on close 2021-01-07 16:30:55 +01:00
tty_ioctl.c tty: Remove dead termiox code 2020-12-04 16:54:35 +01:00
tty_jobctrl.c Merge 5.10-rc7 into tty-next 2020-12-07 10:19:31 +01:00
tty_ldisc.c tty: tty_ldisc: Fix some kernel-doc related misdemeanours 2020-11-13 15:30:45 +01:00
tty_ldsem.c locking/lockdep: Remove unused @nested argument from lock_release() 2019-10-09 12:46:10 +02:00
tty_mutex.c
tty_port.c tty: tty_port: Demote obvious abuse of kernel-doc formatting 2020-11-06 10:49:27 +01:00
ttynull.c init/console: Use ttynull as a fallback when there is no console 2020-11-20 12:23:50 +01:00
vcc.c sparc64: vcc: Fix error return code in vcc_probe() 2020-04-28 14:38:54 +02:00