should_follow_link(): validate ->d_seq after having decided to follow
authorAl Viro <viro@zeniv.linux.org.uk>
Sun, 28 Feb 2016 00:31:01 +0000 (19:31 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Sun, 28 Feb 2016 00:31:01 +0000 (19:31 -0500)
... otherwise d_is_symlink() above might have nothing to do with
the inode value we've got.

Cc: stable@vger.kernel.org # v4.2+
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/namei.c

index e0881c0..65a0e9d 100644 (file)
@@ -1712,6 +1712,11 @@ static inline int should_follow_link(struct nameidata *nd, struct path *link,
                return 0;
        if (!follow)
                return 0;
+       /* make sure that d_is_symlink above matches inode */
+       if (nd->flags & LOOKUP_RCU) {
+               if (read_seqcount_retry(&link->dentry->d_seq, seq))
+                       return -ECHILD;
+       }
        return pick_link(nd, link, inode, seq);
 }