do_last(): ELOOP failure exit should be done after leaving RCU mode
authorAl Viro <viro@zeniv.linux.org.uk>
Sun, 28 Feb 2016 00:37:37 +0000 (19:37 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Sun, 28 Feb 2016 00:37:37 +0000 (19:37 -0500)
... or we risk seeing a bogus value of d_is_symlink() there.

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

index 65a0e9d1ea48c729c67da6c69bcf7d8201903f23..9c590e0f66e9c2189f360bf1b742f54f969713aa 100644 (file)
@@ -3211,11 +3211,6 @@ finish_lookup:
        if (unlikely(error))
                return error;
 
-       if (unlikely(d_is_symlink(path.dentry)) && !(open_flag & O_PATH)) {
-               path_to_nameidata(&path, nd);
-               return -ELOOP;
-       }
-
        if ((nd->flags & LOOKUP_RCU) || nd->path.mnt != path.mnt) {
                path_to_nameidata(&path, nd);
        } else {
@@ -3234,6 +3229,10 @@ finish_open:
                return error;
        }
        audit_inode(nd->name, nd->path.dentry, 0);
+       if (unlikely(d_is_symlink(nd->path.dentry)) && !(open_flag & O_PATH)) {
+               error = -ELOOP;
+               goto out;
+       }
        error = -EISDIR;
        if ((open_flag & O_CREAT) && d_is_dir(nd->path.dentry))
                goto out;