mount_subtree() pointless use-after-free
authorAl Viro <viro@zeniv.linux.org.uk>
Tue, 22 Nov 2011 17:31:21 +0000 (12:31 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Tue, 22 Nov 2011 17:31:21 +0000 (12:31 -0500)
d'oh... we'd carefully pinned mnt->mnt_sb down, dropped mnt and attempt
to grab s_umount on mnt->mnt_sb.  The trouble is, *mnt might've been
overwritten by now...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/namespace.c

index 50ee303..6d3a196 100644 (file)
@@ -2493,6 +2493,7 @@ EXPORT_SYMBOL(create_mnt_ns);
 struct dentry *mount_subtree(struct vfsmount *mnt, const char *name)
 {
        struct mnt_namespace *ns;
 struct dentry *mount_subtree(struct vfsmount *mnt, const char *name)
 {
        struct mnt_namespace *ns;
+       struct super_block *s;
        struct path path;
        int err;
 
        struct path path;
        int err;
 
@@ -2509,10 +2510,11 @@ struct dentry *mount_subtree(struct vfsmount *mnt, const char *name)
                return ERR_PTR(err);
 
        /* trade a vfsmount reference for active sb one */
                return ERR_PTR(err);
 
        /* trade a vfsmount reference for active sb one */
-       atomic_inc(&path.mnt->mnt_sb->s_active);
+       s = path.mnt->mnt_sb;
+       atomic_inc(&s->s_active);
        mntput(path.mnt);
        /* lock the sucker */
        mntput(path.mnt);
        /* lock the sucker */
-       down_write(&path.mnt->mnt_sb->s_umount);
+       down_write(&s->s_umount);
        /* ... and return the root of (sub)tree on it */
        return path.dentry;
 }
        /* ... and return the root of (sub)tree on it */
        return path.dentry;
 }