Linus Torvalds 80e1e82398 Fix race in tty_fasync() properly
This reverts commit 703625118069 ("tty: fix race in tty_fasync") and
commit b04da8bfdfbb ("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 703625118069 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>
Cc: stable@kernel.org
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2010-02-07 10:26:01 -08:00
..
2010-01-26 22:22:27 -05:00
2010-01-26 22:22:25 -05:00
2009-12-10 15:02:50 +01:00
2010-01-26 22:22:25 -05:00
2010-01-14 09:05:42 -05:00
2010-01-19 22:36:06 -06:00
2009-06-17 00:36:36 -04:00
2009-07-12 12:22:34 -07:00
2009-12-15 08:53:10 -08:00
2009-12-16 07:20:06 -08:00
2010-01-14 09:05:25 -05:00
2009-12-22 12:27:35 -05:00
2009-12-17 11:03:25 -05:00
2009-12-16 07:20:18 -08:00
2010-01-26 22:22:26 -05:00
2009-06-17 00:36:37 -04:00
2009-12-14 21:40:04 +01:00
2009-12-16 07:20:06 -08:00
2009-12-16 07:20:13 -08:00
2009-12-22 12:27:34 -05:00
2009-09-24 08:41:47 -04:00
2009-09-24 07:21:03 -07:00
2009-12-17 04:52:13 -05:00
2010-02-07 10:26:01 -08:00
2009-12-17 11:03:25 -05:00
2009-12-14 18:12:11 -05:00
2009-12-22 12:27:34 -05:00
2009-12-17 10:51:40 -05:00
2009-10-04 15:05:10 -07:00
2009-12-16 12:16:49 -05:00