1 From 3cab989afd8d8d1bc3d99fef0e7ed87c31e7b647 Mon Sep 17 00:00:00 2001
2 From: Al Viro <viro@zeniv.linux.org.uk>
3 Date: Fri, 24 Apr 2015 15:47:07 -0400
4 Subject: RCU pathwalk breakage when running into a symlink overmounting something
6 From: Al Viro <viro@zeniv.linux.org.uk>
8 commit 3cab989afd8d8d1bc3d99fef0e7ed87c31e7b647 upstream.
10 Calling unlazy_walk() in walk_component() and do_last() when we find
11 a symlink that needs to be followed doesn't acquire a reference to vfsmount.
12 That's fine when the symlink is on the same vfsmount as the parent directory
13 (which is almost always the case), but it's not always true - one _can_
14 manage to bind a symlink on top of something. And in such cases we end up
15 with excessive mntput().
17 Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
18 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
22 1 file changed, 4 insertions(+), 2 deletions(-)
26 @@ -1585,7 +1585,8 @@ static inline int walk_component(struct
28 if (should_follow_link(path->dentry, follow)) {
29 if (nd->flags & LOOKUP_RCU) {
30 - if (unlikely(unlazy_walk(nd, path->dentry))) {
31 + if (unlikely(nd->path.mnt != path->mnt ||
32 + unlazy_walk(nd, path->dentry))) {
36 @@ -3028,7 +3029,8 @@ finish_lookup:
38 if (should_follow_link(path->dentry, !symlink_ok)) {
39 if (nd->flags & LOOKUP_RCU) {
40 - if (unlikely(unlazy_walk(nd, path->dentry))) {
41 + if (unlikely(nd->path.mnt != path->mnt ||
42 + unlazy_walk(nd, path->dentry))) {