Files
linux/fs
Linus Torvalds 3520341ce3 Fix race in tty_fasync() properly
commit 80e1e82398 upstream.

This reverts commit 7036251180 ("tty: fix race in tty_fasync") and
commit b04da8bfdf ("fnctl: f_modown should call write_lock_irqsave/
restore") that tried to fix up some of the fallout but was incomplete.

It turns out that we really cannot hold 'tty->ctrl_lock' over calling
__f_setown, because not only did that cause problems with interrupt
disables (which the second commit fixed), it also causes a potential
ABBA deadlock due to lock ordering.

Thanks to Tetsuo Handa for following up on the issue, and running
lockdep to show the problem.  It goes roughly like this:

 - f_getown gets filp->f_owner.lock for reading without interrupts
   disabled, so an interrupt that happens while that lock is held can
   cause a lockdep chain from f_owner.lock -> sighand->siglock.

 - at the same time, the tty->ctrl_lock -> f_owner.lock chain that
   commit 7036251180 introduced, together with the pre-existing
   sighand->siglock -> tty->ctrl_lock chain means that we have a lock
   dependency the other way too.

So instead of extending tty->ctrl_lock over the whole __f_setown() call,
we now just take a reference to the 'pid' structure while holding the
lock, and then release it after having done the __f_setown.  That still
guarantees that 'struct pid' won't go away from under us, which is all
we really ever needed.

Reported-and-tested-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Acked-by: Américo Wang <xiyou.wangcong@gmail.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2010-02-23 07:37:44 -08:00
..
2010-02-09 04:50:46 -08:00
2010-02-09 04:50:48 -08:00
2010-02-09 04:50:46 -08:00
2009-10-04 15:05:10 -07:00
2009-09-30 12:19:44 -05:00
2009-06-17 00:36:36 -04:00
2009-07-12 12:22:34 -07:00
2009-12-18 14:04:08 -08:00
2009-07-12 12:22:34 -07:00
2009-09-23 18:13:10 -07:00
2010-01-28 15:01:18 -08:00
2009-09-23 07:39:30 -07:00
2009-09-24 08:41:47 -04:00
2010-02-09 04:50:47 -08:00
2009-06-17 00:36:37 -04:00
2009-06-18 13:03:46 -07:00
2009-09-24 08:41:47 -04:00
2009-09-24 07:21:03 -07:00
2009-06-18 13:03:41 -07:00
2010-02-23 07:37:44 -08:00
2009-03-31 23:00:26 -04:00
2009-09-24 07:47:27 -04:00
2009-04-07 08:31:16 -07:00
2009-10-22 08:11:44 +09:00
2009-10-04 15:05:10 -07:00
2009-09-23 07:39:29 -07:00