]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
ceph: fix potential use-after-free in ceph_mdsc_build_path
authorJeff Layton <jlayton@kernel.org>
Fri, 26 Apr 2019 17:33:39 +0000 (13:33 -0400)
committerIlya Dryomov <idryomov@gmail.com>
Tue, 7 May 2019 17:22:37 +0000 (19:22 +0200)
temp is not defined outside of the RCU critical section here. Ensure
we grab that value before we drop the rcu_read_lock.

Reported-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
fs/ceph/mds_client.c

index 761cb669aa1399da7c1a0b805e3709e677234d58..b01e2043b1b27390a5d00ad0dce04f3f638fa656 100644 (file)
@@ -2089,13 +2089,14 @@ static inline  u64 __get_oldest_tid(struct ceph_mds_client *mdsc)
  * Encode hidden .snap dirs as a double /, i.e.
  *   foo/.snap/bar -> foo//bar
  */
-char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *base,
+char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *pbase,
                           int stop_on_nosnap)
 {
        struct dentry *temp;
        char *path;
        int len, pos;
        unsigned seq;
+       u64 base;
 
        if (!dentry)
                return ERR_PTR(-EINVAL);
@@ -2151,6 +2152,7 @@ retry:
                        path[--pos] = '/';
                temp = temp->d_parent;
        }
+       base = ceph_ino(d_inode(temp));
        rcu_read_unlock();
        if (pos != 0 || read_seqretry(&rename_lock, seq)) {
                pr_err("build_path did not end path lookup where "
@@ -2163,10 +2165,10 @@ retry:
                goto retry;
        }
 
-       *base = ceph_ino(d_inode(temp));
+       *pbase = base;
        *plen = len;
        dout("build_path on %p %d built %llx '%.*s'\n",
-            dentry, d_count(dentry), *base, len, path);
+            dentry, d_count(dentry), base, len, path);
        return path;
 }