Wrapfs: fix NULL pointer dereference when stacking wrapfs on top of itself. wrapfs
authorAndrew Burford <aburford@cs.stonybrook.edu>
Sun, 15 May 2022 02:15:41 +0000 (22:15 -0400)
committerAndrew Burford <aburford@cs.stonybrook.edu>
Sun, 15 May 2022 02:15:41 +0000 (22:15 -0400)
Wrapfs assumes that the d_fsdata field has already been initialized whenever
it is passed one of its own dentries, but it doesn't give the lower fs a chance
to allocate their d_fsdata field when it creates a new lower_dentry. This is
fixed by simply replacing a call to d_add in __wrapfs_lookup with a call to
->lookup on the lower fs inode.

Signed-off-by: Andrew Burford <aburford@cs.stonybrook.edu>
fs/wrapfs/lookup.c
fs/wrapfs/main.c

index 7c78d5a4a30fcc3c2fd73fc3340661a966c6e3bb..b4c468fc5e68e6ca89847153d79f4ed96c886569 100644 (file)
@@ -260,7 +260,14 @@ static struct dentry *__wrapfs_lookup(struct dentry *dentry,
                err = -ENOMEM;
                goto out;
        }
-       d_add(lower_dentry, NULL); /* instantiate and hash */
+
+       /*
+        * Calling ->lookup instead of d_add will give the lower fs a chance
+        * to allocate the d_fsdata field but will still instantiate and hash the
+        * lower_dentry. Without this, wrapfs could not stack on top of itself.
+        */
+       d_inode(lower_dir_dentry)->i_op->lookup(d_inode(lower_dir_dentry),
+                                               lower_dentry, flags);
 
 setup_lower:
        lower_path.dentry = lower_dentry;
index 15c97a78d7655f6e2d4bed9f8504ca85c00258d3..b5d7c178324c2198f529f73e199c94a92722471f 100644 (file)
@@ -39,14 +39,6 @@ static int wrapfs_read_super(struct super_block *sb, void *raw_data, int silent)
                goto out;
        }
 
-        if (lower_path.dentry->d_sb->s_type == &wrapfs_fs_type) {
-               err = -EINVAL;
-               printk(KERN_ERR "Mount on filesystem of type "
-                      "wrapfs explicitly disallowed due to "
-                      "known incompatibilities\n");
-               goto out_pput;
-       }
-
        if (mnt_user_ns(lower_path.mnt) != &init_user_ns) {
                err = -EINVAL;
                printk(KERN_ERR "Mounting on idmapped mounts currently "