linux/drivers/tty/serial
Peter Hurley e144c58cad serial: core: Fix crashes while echoing when closing
While closing, new rx data may be received after the input buffers
have been flushed but before stop_rx() halts receiving [1]. The
new data might not be processed by flush_to_ldisc() until after
uart_shutdown() and normal input processing is re-enabled (ie.,
tty->closing = 0). The race is outlined below:

CPU 0                         | CPU 1
                              |
uart_close()                  |
   tty_port_close_start()     |
      tty->closing = 1        |
      tty_ldisc_flush()       |
                              | => IRQ
                              |   while (LSR & data ready)
                              |      uart_insert_char()
                              |   tty_flip_buffer_push()
                              | <= EOI
   stop_rx()                  |   .
   uart_shutdown()            |   .
      free xmit.buf           |   .
   tty_port_tty_set(NULL)     |   .
   tty->closing = 0           |   .
                              | flush_to_ldisc()
                              |   n_tty_receive_buf_common()
                              |      __receive_buf()
                              |         ...
                              |         commit_echoes()
                              |            uart_flush_chars()
                              |               __uart_start()
                              | ** OOPS on port.tty deref **
   tty_ldisc_flush()          |

Input processing must be prevented from echoing (tty->closing = 1)
until _after_ the input buffers have been flushed again at the end
of uart_close().

[1] In fact, some input may actually be buffered _after_ stop_rx()
since the rx interrupt may have already triggered but not yet been
handled when stop_rx() disables rx interrupts.

Fixes: 2e75891083 ("serial: core: Flush ldisc after dropping port
mutex in uart_close()")
Reported-by: Robert Elliott <elliott@hp.com>
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-07-23 18:08:28 -07:00
..
8250 ARM: SoC: late fixes and dependencies 2015-07-02 14:40:49 -07:00
cpm_uart tty: cpm_uart: replace CONFIG_8xx by CONFIG_CPM1 2015-03-26 23:00:36 +01:00
jsm serial: jsm: some off by one bugs 2015-03-26 23:00:36 +01:00
21285.c serial: treewide: Remove empty implementations of enable_ms() 2014-07-09 17:29:38 -07:00
68328serial.c tty: 68328serial.c: move assignment out of if () block 2015-05-10 19:04:16 +02:00
altera_jtaguart.c drivers/tty/serial: altera: fix typos in #endif comments 2015-05-06 22:26:58 +02:00
altera_uart.c drivers/tty/serial: altera: fix typos in #endif comments 2015-05-06 22:26:58 +02:00
amba-pl010.c serial: Test/disable MSIs if switching from N_PPS 2014-11-06 14:57:27 -08:00
amba-pl011.c serial: amba-pl011: Fix devm_ioremap_resource return value check 2015-07-23 15:05:53 -07:00
apbuart.c tty: constify of_device_id array 2015-03-26 22:49:10 +01:00
apbuart.h
ar933x_uart.c serial: ar933x_uart: Fix off-by-one for checking valid alias id 2015-03-07 03:20:25 +01:00
arc_uart.c tty: serial: drop owner assignment from platform_drivers 2014-10-20 16:21:45 +02:00
atmel_serial.c tty/serial: at91: RS485 mode: 0 is valid for delay_rts_after_send 2015-05-24 12:49:16 -07:00
bcm63xx_uart.c tty: serial/bcm63xx_uart: fix sparse warning 2015-03-07 03:13:07 +01:00
bfin_sport_uart.c tty: pr_warning->pr_warn and logging neatening 2014-11-25 17:06:38 -08:00
bfin_sport_uart.h
bfin_uart.c serial: bfin: ctsrts: enfore Kconfig naming convention 2015-05-06 22:26:59 +02:00
clps711x.c serial: clps711x: fail if mctrl_gpio_init fails 2015-03-07 03:15:03 +01:00
crisv10.c tty: crisv10.c: move assignment out of if () block 2015-05-10 19:04:17 +02:00
crisv10.h cris: Remove obsolete ASYNC_SPLIT_TERMIOS behavior 2014-11-05 20:18:30 -08:00
digicolor-usart.c tty/serial: digicolor: remove sysrq reference 2015-02-02 10:11:25 -08:00
dz.c serial: treewide: Remove empty implementations of enable_ms() 2014-07-09 17:29:38 -07:00
dz.h
earlycon-arm-semihost.c
earlycon.c serial: earlycon: Add support for big-endian MMIO accesses 2015-06-01 06:55:12 +09:00
efm32-uart.c tty: serial: drop owner assignment from platform_drivers 2014-10-20 16:21:45 +02:00
etraxfs-uart.c serial: etraxfs-uart: Fix release etraxfs_uart_ports 2015-07-23 15:25:38 -07:00
fsl_lpuart.c Merge 4.0-rc7 into tty-next 2015-04-07 11:07:20 +02:00
icom.c tty: icom.c: move assignment out of if () block 2015-05-10 19:04:17 +02:00
icom.h
ifx6x60.c serial: ifx6x60: Remove superfluous casts when calling request_irq() 2015-05-06 22:27:01 +02:00
ifx6x60.h
imx.c Revert "serial: imx: initialized DMA w/o HW flow enabled" 2015-07-23 17:40:14 -07:00
ioc3_serial.c tty: ioc3_serial.c: move assignment out of if () block 2015-05-10 19:04:17 +02:00
ioc4_serial.c tty: ioc4_serial.c: move assignment out of if () block 2015-05-10 19:04:17 +02:00
ip22zilog.c serial: use container_of to resolve uart_ip22zilog_port from uart_port 2014-11-05 19:20:52 -08:00
ip22zilog.h
Kconfig sc16is7xx: fix Kconfig dependencies 2015-07-23 15:32:32 -07:00
kgdb_nmi.c serial: kgdb_nmi: Use bool function return values of true/false not 1/0 2015-05-06 22:26:57 +02:00
kgdboc.c
lantiq.c Driver core patches for 3.19-rc1 2014-12-14 16:10:09 -08:00
lpc32xx_hs.c tty: serial: drop owner assignment from platform_drivers 2014-10-20 16:21:45 +02:00
m32r_sio_reg.h
m32r_sio.c serial: use container_of to resolve uart_sio_port from uart_port 2014-11-05 19:20:52 -08:00
m32r_sio.h
Makefile serial: stm32-usart: Add STM32 USART Driver 2015-06-10 17:34:26 -07:00
max310x.c drivers/max310: Use the rs485 functions on serial_core 2014-11-06 15:00:15 -08:00
max3100.c tty: max3100: use msecs_to_jiffies for time conversion 2015-03-07 03:13:08 +01:00
mcf.c drivers/tty/serial/mcf.c: fix typo on SERIAL_MCF_CONSOLE 2015-05-06 22:26:59 +02:00
men_z135_uart.c tty: serial: men_z135_uart: Fix driver for changes in hardware 2015-02-02 10:11:27 -08:00
meson_uart.c ARM: meson: serial: convert iounmap to devm_iounmap 2015-05-06 22:27:02 +02:00
mpc52xx_uart.c drivers/tty/serial/mpc52xx_uart.c: fix typo in C comment 2015-05-06 22:26:59 +02:00
mpsc.c tty: mpsc.c: move assignment out of if () block 2015-05-10 19:04:17 +02:00
msm_serial.c tty: serial: msm_serial: Remove console unregistration from driver exit. 2015-02-02 10:11:25 -08:00
msm_serial.h tty: serial: msm_serial: Remove dead code 2015-03-26 22:31:09 +01:00
mux.c serial: treewide: Remove empty implementations of enable_ms() 2014-07-09 17:29:38 -07:00
mxs-auart.c serial: mxs: Constify platform_device_id 2015-05-10 19:08:16 +02:00
netx-serial.c tty: serial: drop owner assignment from platform_drivers 2014-10-20 16:21:45 +02:00
nwpserial.c serial: Fix build failure caused by missing header file 2014-09-08 16:17:45 -07:00
of_serial.c serial: of_serial: check the return value of clk_prepare_enable() 2015-06-01 06:55:12 +09:00
omap-serial.c serial: omap: Switch wake-up interrupt to generic wakeirq 2015-06-09 23:35:00 -07:00
pch_uart.c pch_uart: don't hardcode PCI slot to get DMA device 2014-08-01 16:04:21 -07:00
pmac_zilog.c tty: constify of_device_id array 2015-03-26 22:49:10 +01:00
pmac_zilog.h
pnx8xxx_uart.c Driver core patches for 3.19-rc1 2014-12-14 16:10:09 -08:00
pxa.c tty: constify of_device_id array 2015-03-26 22:49:10 +01:00
rp2.c
sa1100.c Driver core patches for 3.19-rc1 2014-12-14 16:10:09 -08:00
samsung.c serial: samsung: Constify platform_device_id 2015-05-10 19:08:16 +02:00
samsung.h serial: samsung: add DMA support for RX 2015-01-09 14:25:39 -08:00
sb1250-duart.c
sc16is7xx.c sc16is7xx: fix FIFO address of secondary UART 2015-07-23 15:32:32 -07:00
sccnxp.c tty: serial: drop owner assignment from platform_drivers 2014-10-20 16:21:45 +02:00
serial_core.c serial: core: Fix crashes while echoing when closing 2015-07-23 18:08:28 -07:00
serial_ks8695.c tty/serial: kill off set_irq_flags usage 2015-06-09 12:26:32 -07:00
serial_mctrl_gpio.c TTY/Serial driver patches for 4.2-rc1 2015-06-26 15:53:22 -07:00
serial_mctrl_gpio.h
serial_txx9.c tty: serial: drop owner assignment from platform_drivers 2014-10-20 16:21:45 +02:00
serial-tegra.c serial: tegra: Fix memory leak on DMA setup failure 2015-05-24 12:53:44 -07:00
sh-sci.c TTY/Serial driver patches for 4.2-rc1 2015-06-26 15:53:22 -07:00
sh-sci.h serial: sh-sci: Replace hardcoded overrun bit values 2015-05-10 19:06:39 +02:00
sirfsoc_uart.c tty/serial: kill off set_irq_flags usage 2015-06-09 12:26:32 -07:00
sirfsoc_uart.h serial: sirf: use hrtimer for data rx 2015-06-01 06:51:37 +09:00
sn_console.c serial: treewide: Remove empty implementations of enable_ms() 2014-07-09 17:29:38 -07:00
sprd_serial.c serial: sprd: check for NULL after calling devm_clk_get 2015-06-12 17:39:50 -07:00
st-asc.c tty: constify of_device_id array 2015-03-26 22:49:10 +01:00
stm32-usart.c serial: stm32-usart: Add STM32 USART Driver 2015-06-10 17:34:26 -07:00
suncore.c
sunhv.c tty: serial: drop owner assignment from platform_drivers 2014-10-20 16:21:45 +02:00
sunsab.c Driver core patches for 3.19-rc1 2014-12-14 16:10:09 -08:00
sunsab.h
sunsu.c Driver core patches for 3.19-rc1 2014-12-14 16:10:09 -08:00
sunzilog.c Driver core patches for 3.19-rc1 2014-12-14 16:10:09 -08:00
sunzilog.h
tilegx.c serial: treewide: Remove empty implementations of enable_ms() 2014-07-09 17:29:38 -07:00
timbuart.c Driver core patches for 3.19-rc1 2014-12-14 16:10:09 -08:00
timbuart.h
uartlite.c serial: xilinx: Use platform_get_irq to get irq description structure 2015-04-28 14:26:21 +02:00
ucc_uart.c tty: constify of_device_id array 2015-03-26 22:49:10 +01:00
vr41xx_siu.c tty: serial: drop owner assignment from platform_drivers 2014-10-20 16:21:45 +02:00
vt8500_serial.c tty: serial: drop owner assignment from platform_drivers 2014-10-20 16:21:45 +02:00
xilinx_uartps.c serial: xuartps: add __init to earlycon write method 2015-05-10 19:10:08 +02:00
zs.c
zs.h