namei: prepare for idmapped mounts

The various vfs_*() helpers are called by filesystems or by the vfs
itself to perform core operations such as create, link, mkdir, mknod, rename,
rmdir, tmpfile and unlink. Enable them to handle idmapped mounts. If the
inode is accessed through an idmapped mount map it into the
mount's user namespace and pass it down. Afterwards the checks and
operations are identical to non-idmapped mounts. 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-15-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>
This commit is contained in:
Christian Brauner
2021-01-21 14:19:33 +01:00
parent 9fe6145097
commit 6521f89170
12 changed files with 279 additions and 105 deletions

View File

@@ -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(path.dentry->d_inode, dentry, mode,
new_decode_dev(dev));
error = vfs_mknod(&init_user_ns, path.dentry->d_inode, dentry,
mode, new_decode_dev(dev));
done_path_create(&path, dentry);
return error;
}
@@ -187,8 +187,8 @@ int __init init_link(const char *oldname, const char *newname)
error = security_path_link(old_path.dentry, &new_path, new_dentry);
if (error)
goto out_dput;
error = vfs_link(old_path.dentry, new_path.dentry->d_inode, new_dentry,
NULL);
error = vfs_link(old_path.dentry, &init_user_ns,
new_path.dentry->d_inode, new_dentry, NULL);
out_dput:
done_path_create(&new_path, new_dentry);
out:
@@ -207,7 +207,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(path.dentry->d_inode, dentry, oldname);
error = vfs_symlink(&init_user_ns, path.dentry->d_inode, dentry,
oldname);
done_path_create(&path, dentry);
return error;
}
@@ -230,7 +231,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(path.dentry->d_inode, dentry, mode);
error = vfs_mkdir(&init_user_ns, path.dentry->d_inode, dentry,
mode);
done_path_create(&path, dentry);
return error;
}