summaryrefslogtreecommitdiffstats
path: root/drivers/tty/vt
diff options
context:
space:
mode:
authorPeter Hurley <peter@hurleysoftware.com>2015-07-12 21:05:26 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-07-23 18:08:28 -0700
commite144c58cad6667876173dd76977e9e6557e34941 (patch)
tree77a8fb4466d880c78ccc913fa29e69fc3aac0f5f /drivers/tty/vt
parent7525a9901b5ee3c84933ad069e41506c37404ddc (diff)
downloadlinux-e144c58cad6667876173dd76977e9e6557e34941.tar.bz2
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: 2e758910832d ("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>
Diffstat (limited to 'drivers/tty/vt')
0 files changed, 0 insertions, 0 deletions