init: handle idmapped mounts
authorChristian Brauner <christian.brauner@ubuntu.com>
Thu, 21 Jan 2021 13:19:39 +0000 (14:19 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Sun, 24 Jan 2021 13:27:19 +0000 (14:27 +0100)
Enable the init helpers to handle idmapped mounts by passing down the
mount's user namespace. If the initial user namespace is passed nothing
changes so non-idmapped mounts will see identical behavior as before.

Link: https://lore.kernel.org/r/20210121131959.646623-21-christian.brauner@ubuntu.com
Cc: Christoph Hellwig <hch@lst.de>
Cc: David Howells <dhowells@redhat.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: linux-fsdevel@vger.kernel.org
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
fs/init.c

index e654527..5c36ada 100644 (file)
--- a/fs/init.c
+++ b/fs/init.c
@@ -157,8 +157,8 @@ int __init init_mknod(const char *filename, umode_t mode, unsigned int dev)
                mode &= ~current_umask();
        error = security_path_mknod(&path, dentry, mode, dev);
        if (!error)
-               error = vfs_mknod(&init_user_ns, path.dentry->d_inode, dentry,
-                                 mode, new_decode_dev(dev));
+               error = vfs_mknod(mnt_user_ns(path.mnt), path.dentry->d_inode,
+                                 dentry, mode, new_decode_dev(dev));
        done_path_create(&path, dentry);
        return error;
 }
@@ -167,6 +167,7 @@ int __init init_link(const char *oldname, const char *newname)
 {
        struct dentry *new_dentry;
        struct path old_path, new_path;
+       struct user_namespace *mnt_userns;
        int error;
 
        error = kern_path(oldname, 0, &old_path);
@@ -181,14 +182,15 @@ int __init init_link(const char *oldname, const char *newname)
        error = -EXDEV;
        if (old_path.mnt != new_path.mnt)
                goto out_dput;
-       error = may_linkat(&init_user_ns, &old_path);
+       mnt_userns = mnt_user_ns(new_path.mnt);
+       error = may_linkat(mnt_userns, &old_path);
        if (unlikely(error))
                goto out_dput;
        error = security_path_link(old_path.dentry, &new_path, new_dentry);
        if (error)
                goto out_dput;
-       error = vfs_link(old_path.dentry, &init_user_ns,
-                        new_path.dentry->d_inode, new_dentry, NULL);
+       error = vfs_link(old_path.dentry, mnt_userns, new_path.dentry->d_inode,
+                        new_dentry, NULL);
 out_dput:
        done_path_create(&new_path, new_dentry);
 out:
@@ -207,8 +209,8 @@ int __init init_symlink(const char *oldname, const char *newname)
                return PTR_ERR(dentry);
        error = security_path_symlink(&path, dentry, oldname);
        if (!error)
-               error = vfs_symlink(&init_user_ns, path.dentry->d_inode, dentry,
-                                   oldname);
+               error = vfs_symlink(mnt_user_ns(path.mnt), path.dentry->d_inode,
+                                   dentry, oldname);
        done_path_create(&path, dentry);
        return error;
 }
@@ -231,8 +233,8 @@ int __init init_mkdir(const char *pathname, umode_t mode)
                mode &= ~current_umask();
        error = security_path_mkdir(&path, dentry, mode);
        if (!error)
-               error = vfs_mkdir(&init_user_ns, path.dentry->d_inode, dentry,
-                                 mode);
+               error = vfs_mkdir(mnt_user_ns(path.mnt), path.dentry->d_inode,
+                                 dentry, mode);
        done_path_create(&path, dentry);
        return error;
 }