mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-03-22 15:14:35 +00:00
open: handle idmapped mounts
For core file operations such as changing directories or chrooting, determining file access, changing mode or ownership the vfs will verify that the caller is privileged over the inode. Extend the various helpers to handle idmapped mounts. If the inode is accessed through an idmapped mount map it into the mount's user namespace. Afterwards the permissions checks are identical to non-idmapped mounts. When changing file ownership we need to map the uid and gid from 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-17-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: James Morris <jamorris@linux.microsoft.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
This commit is contained in:
parent
643fe55a06
commit
b8b546a061
1 changed files with 9 additions and 4 deletions
13
fs/open.c
13
fs/open.c
|
@ -438,7 +438,7 @@ retry:
|
||||||
goto out_path_release;
|
goto out_path_release;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = inode_permission(&init_user_ns, inode, mode | MAY_ACCESS);
|
res = inode_permission(mnt_user_ns(path.mnt), inode, mode | MAY_ACCESS);
|
||||||
/* SuS v2 requires we report a read only fs too */
|
/* SuS v2 requires we report a read only fs too */
|
||||||
if (res || !(mode & S_IWOTH) || special_file(inode->i_mode))
|
if (res || !(mode & S_IWOTH) || special_file(inode->i_mode))
|
||||||
goto out_path_release;
|
goto out_path_release;
|
||||||
|
@ -582,8 +582,8 @@ retry_deleg:
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
|
newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
|
||||||
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
|
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
|
||||||
error = notify_change(&init_user_ns, path->dentry, &newattrs,
|
error = notify_change(mnt_user_ns(path->mnt), path->dentry,
|
||||||
&delegated_inode);
|
&newattrs, &delegated_inode);
|
||||||
out_unlock:
|
out_unlock:
|
||||||
inode_unlock(inode);
|
inode_unlock(inode);
|
||||||
if (delegated_inode) {
|
if (delegated_inode) {
|
||||||
|
@ -644,6 +644,7 @@ SYSCALL_DEFINE2(chmod, const char __user *, filename, umode_t, mode)
|
||||||
|
|
||||||
int chown_common(const struct path *path, uid_t user, gid_t group)
|
int chown_common(const struct path *path, uid_t user, gid_t group)
|
||||||
{
|
{
|
||||||
|
struct user_namespace *mnt_userns;
|
||||||
struct inode *inode = path->dentry->d_inode;
|
struct inode *inode = path->dentry->d_inode;
|
||||||
struct inode *delegated_inode = NULL;
|
struct inode *delegated_inode = NULL;
|
||||||
int error;
|
int error;
|
||||||
|
@ -654,6 +655,10 @@ int chown_common(const struct path *path, uid_t user, gid_t group)
|
||||||
uid = make_kuid(current_user_ns(), user);
|
uid = make_kuid(current_user_ns(), user);
|
||||||
gid = make_kgid(current_user_ns(), group);
|
gid = make_kgid(current_user_ns(), group);
|
||||||
|
|
||||||
|
mnt_userns = mnt_user_ns(path->mnt);
|
||||||
|
uid = kuid_from_mnt(mnt_userns, uid);
|
||||||
|
gid = kgid_from_mnt(mnt_userns, gid);
|
||||||
|
|
||||||
retry_deleg:
|
retry_deleg:
|
||||||
newattrs.ia_valid = ATTR_CTIME;
|
newattrs.ia_valid = ATTR_CTIME;
|
||||||
if (user != (uid_t) -1) {
|
if (user != (uid_t) -1) {
|
||||||
|
@ -674,7 +679,7 @@ retry_deleg:
|
||||||
inode_lock(inode);
|
inode_lock(inode);
|
||||||
error = security_path_chown(path, uid, gid);
|
error = security_path_chown(path, uid, gid);
|
||||||
if (!error)
|
if (!error)
|
||||||
error = notify_change(&init_user_ns, path->dentry, &newattrs,
|
error = notify_change(mnt_userns, path->dentry, &newattrs,
|
||||||
&delegated_inode);
|
&delegated_inode);
|
||||||
inode_unlock(inode);
|
inode_unlock(inode);
|
||||||
if (delegated_inode) {
|
if (delegated_inode) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue