Files
linux/fs
Al Viro 4b09c29ead UPSTREAM: vfs: fix do_last() regression
commit 6404674acd upstream.

Brown paperbag time: fetching ->i_uid/->i_mode really should've been
done from nd->inode.  I even suggested that, but the reason for that has
slipped through the cracks and I went for dir->d_inode instead - made
for more "obvious" patch.

Analysis:

 - at the entry into do_last() and all the way to step_into(): dir (aka
   nd->path.dentry) is known not to have been freed; so's nd->inode and
   it's equal to dir->d_inode unless we are already doomed to -ECHILD.
   inode of the file to get opened is not known.

 - after step_into(): inode of the file to get opened is known; dir
   might be pointing to freed memory/be negative/etc.

 - at the call of may_create_in_sticky(): guaranteed to be out of RCU
   mode; inode of the file to get opened is known and pinned; dir might
   be garbage.

The last was the reason for the original patch.  Except that at the
do_last() entry we can be in RCU mode and it is possible that
nd->path.dentry->d_inode has already changed under us.

In that case we are going to fail with -ECHILD, but we need to be
careful; nd->inode is pointing to valid struct inode and it's the same
as nd->path.dentry->d_inode in "won't fail with -ECHILD" case, so we
should use that.

Change-Id: I9aa97857bdf3944d67c47a45161465ec1055b41d
Reported-by: "Rantala, Tommi T. (Nokia - FI/Espoo)" <tommi.t.rantala@nokia.com>
Reported-by: syzbot+190005201ced78a74ad6@syzkaller.appspotmail.com
Wearing-brown-paperbag: Al Viro <viro@zeniv.linux.org.uk>
Cc: stable@kernel.org
Fixes: d0cb50185a ("do_last(): fetch directory ->i_mode and ->i_uid before it's too late")
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Tao Huang <huangtao@rock-chips.com>
(cherry picked from commit 8d7a5100e2)
2020-02-25 16:28:26 +08:00
..
2019-08-06 19:06:51 +02:00
2019-12-13 08:52:23 +01:00
2019-12-17 20:35:18 +01:00
2020-01-27 15:55:44 +01:00
2019-12-13 08:52:36 +01:00
2018-08-17 16:20:28 -07:00
2019-05-22 08:00:39 +02:00
2019-12-13 10:01:10 +01:00
2019-12-13 08:51:59 +01:00
2020-01-27 15:55:44 +01:00
2020-01-09 10:19:03 +01:00
2020-01-12 12:29:19 +01:00
2018-08-17 16:20:27 -07:00
2019-12-18 09:03:30 +01:00
2019-12-18 09:03:30 +01:00
2020-01-09 16:14:43 +01:00
2019-11-20 18:46:04 +01:00
2019-05-02 09:58:59 +02:00
2020-01-09 16:14:43 +01:00
2019-08-04 09:37:11 +02:00
2020-01-12 12:29:19 +01:00
2019-05-31 08:14:29 -07:00
2019-07-31 08:03:42 +02:00
2019-12-01 09:53:43 +01:00
2020-01-04 19:29:03 +01:00