Files
linux/fs
Al Viro 4eab574ff2 fix __legitimize_mnt()/mntput() race
commit 119e1ef80e upstream.

__legitimize_mnt() has two problems - one is that in case of success
the check of mount_lock is not ordered wrt preceding increment of
refcount, making it possible to have successful __legitimize_mnt()
on one CPU just before the otherwise final mntpu() on another,
with __legitimize_mnt() not seeing mntput() taking the lock and
mntput() not seeing the increment done by __legitimize_mnt().
Solved by a pair of barriers.

Another is that failure of __legitimize_mnt() on the second
read_seqretry() leaves us with reference that'll need to be
dropped by caller; however, if that races with final mntput()
we can end up with caller dropping rcu_read_lock() and doing
mntput() to release that reference - with the first mntput()
having freed the damn thing just as rcu_read_lock() had been
dropped.  Solution: in "do mntput() yourself" failure case
grab mount_lock, check if MNT_DOOMED has been set by racing
final mntput() that has missed our increment and if it has -
undo the increment and treat that as "failure, caller doesn't
need to drop anything" case.

It's not easy to hit - the final mntput() has to come right
after the first read_seqretry() in __legitimize_mnt() *and*
manage to miss the increment done by __legitimize_mnt() before
the second read_seqretry() in there.  The things that are almost
impossible to hit on bare hardware are not impossible on SMP
KVM, though...

Reported-by: Oleg Nesterov <oleg@redhat.com>
Fixes: 48a066e72d ("RCU'd vsfmounts")
Cc: stable@vger.kernel.org
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-05-12 16:46:57 +09:00
..
2018-07-11 16:40:16 +02:00
2017-08-06 18:59:43 -07:00
2018-05-30 13:19:56 +02:00
2016-05-20 17:58:30 -07:00
2018-05-30 13:19:56 +02:00
2018-07-03 18:27:19 +02:00
2018-05-30 13:19:56 +02:00
2017-11-30 08:39:04 +00:00
2018-05-19 14:06:17 +02:00
2018-04-24 11:26:46 +02:00
2018-07-03 11:23:17 +02:00
2018-06-06 16:44:38 +02:00
2018-03-05 15:34:36 +08:00
2017-06-14 15:06:00 +02:00
2016-09-27 21:20:53 -04:00
2017-07-05 16:18:14 +02:00
2017-09-07 10:32:23 +02:00
2016-09-27 18:47:38 -04:00
2018-05-16 11:39:34 +02:00
2017-09-20 09:59:51 +02:00
2017-09-26 00:32:37 -07:00
2017-09-26 00:32:37 -07:00
2018-02-17 13:21:15 +01:00
2017-07-12 17:07:29 +02:00
2017-07-21 08:55:50 +02:00
2017-06-14 15:06:01 +02:00
2018-03-05 07:38:41 +01:00
2017-12-20 10:51:15 +01:00