linux/drivers/tty
Peter Hurley 39f610e40e tty: Fix race condition if flushing tty flip buffers
As Ilya Zykov identified in his patch 'PROBLEM: Race condition in
tty buffer's function flush_to_ldisc()', a race condition exists
which allows a parallel flush_to_ldisc() to flush and free the tty
flip buffers while those buffers are in-use. For example,

  CPU 0                         |  CPU 1                                  |  CPU 2
                                | flush_to_ldisc()                        |
                                |  grab spin lock                         |
tty_buffer_flush()              |                                         | flush_to_ldisc()
 wait for spin lock             |                                         |  wait for spin lock
                                |   if (!test_and_set_bit(TTYP_FLUSHING)) |
                                |    while (next flip buffer)             |
                                |     ...                                 |
                                |     drop spin lock                      |
  grab spin lock                |                                         |
   if (test_bit(TTYP_FLUSHING)) |                                         |
    set_bit(TTYP_FLUSHPENDING)  |      receive_buf()                      |
    drop spin lock              |                                         |
                                |                                         |   grab spin lock
                                |                                         |    if (!test_and_set_bit(TTYP_FLUSHING))
                                |                                         |    if (test_bit(TTYP_FLUSHPENDING))
                                |                                         |    __tty_buffer_flush()

CPU 2 has just flushed and freed all tty flip buffers while CPU 1 is
transferring data from the head flip buffer.

The original patch was rejected under the assumption that parallel
flush_to_ldisc() was not possible. Because of necessary changes to
the workqueue api, work items can execute in parallel on SMP.

This patch differs slightly from the original patch by testing for
a pending flush _after_ each receive_buf(), since TTYP_FLUSHPENDING
can only be set while the lock is dropped around receive_buf().

Reported-by: Ilya Zykov <linux@izyk.ru>
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Acked-by: Ilya Zykov <linux@izyk.ru>
Cc: Jiri Slaby <jslaby@suse.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-04-09 17:05:02 -07:00
..
hvc TTY: add tty_port_tty_wakeup helper 2013-03-18 16:19:45 -07:00
ipwireless tty: ipwireless: Remove redundant NULL check before kfree 2013-03-15 13:58:32 -07:00
serial serial: max3100: use spi_get_drvdata() and spi_set_drvdata() 2013-04-05 15:49:39 -07:00
vt Merge 3.9-rc5 into tty-next 2013-04-01 12:01:10 -07:00
amiserial.c TTY: amiserial, use module_platform_driver_probe() 2013-03-15 13:55:23 -07:00
bfin_jtag_comm.c TTY: switch tty_flip_buffer_push 2013-01-15 22:30:15 -08:00
cyclades.c TTY: add tty_port_tty_hangup helper 2013-03-18 16:24:29 -07:00
ehv_bytechan.c TTY: add tty_port_tty_wakeup helper 2013-03-18 16:19:45 -07:00
goldfish.c goldfish: move to tty_port for flip buffers 2013-01-25 08:09:38 -08:00
isicom.c TTY: switch tty_flip_buffer_push 2013-01-15 22:30:15 -08:00
Kconfig tty: metag_da: Add metag DA TTY driver 2013-02-06 11:10:17 -08:00
Makefile tty: metag_da: Add metag DA TTY driver 2013-02-06 11:10:17 -08:00
metag_da.c tty: metag_da: avoid getting tty kref in dashtty_timer() 2013-02-06 11:10:17 -08:00
moxa.c TTY: add tty_port_tty_hangup helper 2013-03-18 16:24:29 -07:00
moxa.h
mxser.c TTY: fix DTR not being dropped on hang up 2013-03-18 16:27:53 -07:00
mxser.h
n_gsm.c TTY: fix DTR not being dropped on hang up 2013-03-18 16:27:53 -07:00
n_hdlc.c
n_r3964.c tty: localise the lock 2012-08-10 12:55:47 -07:00
n_tracerouter.c
n_tracesink.c
n_tracesink.h
n_tty.c n_tty: Fully initialize ldisc before restarting buffer work 2013-03-18 16:44:01 -07:00
nozomi.c TTY: add tty_port_tty_hangup helper 2013-03-18 16:24:29 -07:00
pty.c pty: Remove redundant itty reset 2013-03-15 13:00:48 -07:00
rocket_int.h
rocket.c TTY: cleanup tty->hw_stopped uses 2013-03-18 16:24:30 -07:00
rocket.h
synclink_gt.c TTY: synclink: Convert + to | for bit operations 2013-01-30 00:09:58 -05:00
synclink.c TTY: synclink, remove superfluous check 2013-03-18 16:17:20 -07:00
synclinkmp.c TTY: synclink: Convert + to | for bit operations 2013-01-30 00:09:58 -05:00
sysrq.c sysrq: fix inconstistent help message of sysrq key 2013-03-15 14:06:45 -07:00
tty_audit.c TTY: audit, stop accessing tty->icount 2012-10-22 16:50:54 -07:00
tty_buffer.c tty: Fix race condition if flushing tty flip buffers 2013-04-09 17:05:02 -07:00
tty_io.c tty: tty_vhangup_session can be static 2013-03-25 14:07:34 -07:00
tty_ioctl.c tty: Fix recursive deadlock in tty_perform_flush() 2013-03-18 16:52:24 -07:00
tty_ldisc.c tty: Remove redundant tty_wait_until_sent() 2013-03-18 16:48:42 -07:00
tty_mutex.c tty: tty_mutex.c: Fixed coding style warning (using printk) 2012-10-24 11:34:51 -07:00
tty_port.c tty: Complete ownership transfer of flip buffers 2013-03-18 16:44:02 -07:00