aboutsummaryrefslogtreecommitdiff
path: root/security/security.c
diff options
context:
space:
mode:
authorPeter Hurley <peter@hurleysoftware.com>2013-03-20 13:20:43 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-04-09 17:05:02 -0700
commit39f610e40eecc39e4c34e047fd6904ca6b525520 (patch)
tree39af27120456a3a3b68b7068d65a71f5614db008 /security/security.c
parent31bdfc649f4577c9b1120c67b7b1e85f7777aad0 (diff)
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>
Diffstat (limited to 'security/security.c')
0 files changed, 0 insertions, 0 deletions