Skip to content

Commit 21cb47b

Browse files
author
Christian Brauner
committed
inode: make init and permission helpers idmapped mount aware
The inode_owner_or_capable() helper determines whether the caller is the owner of the inode or is capable with respect to that inode. Allow it to handle idmapped mounts. If the inode is accessed through an idmapped mount it according to the mount's user namespace. Afterwards the checks 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. Similarly, allow the inode_init_owner() helper to handle idmapped mounts. It initializes a new inode on idmapped mounts by mapping the fsuid and fsgid of the caller 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-7-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> Reviewed-by: James Morris <jamorris@linux.microsoft.com> Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
1 parent 47291ba commit 21cb47b

File tree

54 files changed

+112
-91
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+112
-91
lines changed

fs/9p/acl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler,
258258

259259
if (S_ISLNK(inode->i_mode))
260260
return -EOPNOTSUPP;
261-
if (!inode_owner_or_capable(inode))
261+
if (!inode_owner_or_capable(&init_user_ns, inode))
262262
return -EPERM;
263263
if (value) {
264264
/* update the cached acl value */

fs/9p/vfs_inode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ int v9fs_init_inode(struct v9fs_session_info *v9ses,
251251
{
252252
int err = 0;
253253

254-
inode_init_owner(inode, NULL, mode);
254+
inode_init_owner(&init_user_ns,inode, NULL, mode);
255255
inode->i_blocks = 0;
256256
inode->i_rdev = rdev;
257257
inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);

fs/attr.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ int setattr_prepare(struct dentry *dentry, struct iattr *attr)
8787

8888
/* Make sure a caller can chmod. */
8989
if (ia_valid & ATTR_MODE) {
90-
if (!inode_owner_or_capable(inode))
90+
if (!inode_owner_or_capable(&init_user_ns, inode))
9191
return -EPERM;
9292
/* Also check the setgid bit! */
9393
if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid :
@@ -98,7 +98,7 @@ int setattr_prepare(struct dentry *dentry, struct iattr *attr)
9898

9999
/* Check for setting the inode time. */
100100
if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)) {
101-
if (!inode_owner_or_capable(inode))
101+
if (!inode_owner_or_capable(&init_user_ns, inode))
102102
return -EPERM;
103103
}
104104

@@ -243,7 +243,7 @@ int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **de
243243
if (IS_IMMUTABLE(inode))
244244
return -EPERM;
245245

246-
if (!inode_owner_or_capable(inode)) {
246+
if (!inode_owner_or_capable(&init_user_ns, inode)) {
247247
error = inode_permission(&init_user_ns, inode,
248248
MAY_WRITE);
249249
if (error)

fs/bfs/dir.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ static int bfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
9696
}
9797
set_bit(ino, info->si_imap);
9898
info->si_freei--;
99-
inode_init_owner(inode, dir, mode);
99+
inode_init_owner(&init_user_ns, inode, dir, mode);
100100
inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
101101
inode->i_blocks = 0;
102102
inode->i_op = &bfs_file_inops;

fs/btrfs/inode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6190,7 +6190,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
61906190
if (ret != 0)
61916191
goto fail_unlock;
61926192

6193-
inode_init_owner(inode, dir, mode);
6193+
inode_init_owner(&init_user_ns, inode, dir, mode);
61946194
inode_set_bytes(inode, 0);
61956195

61966196
inode->i_mtime = current_time(inode);

fs/btrfs/ioctl.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
213213
const char *comp = NULL;
214214
u32 binode_flags;
215215

216-
if (!inode_owner_or_capable(inode))
216+
if (!inode_owner_or_capable(&init_user_ns, inode))
217217
return -EPERM;
218218

219219
if (btrfs_root_readonly(root))
@@ -429,7 +429,7 @@ static int btrfs_ioctl_fssetxattr(struct file *file, void __user *arg)
429429
unsigned old_i_flags;
430430
int ret = 0;
431431

432-
if (!inode_owner_or_capable(inode))
432+
if (!inode_owner_or_capable(&init_user_ns, inode))
433433
return -EPERM;
434434

435435
if (btrfs_root_readonly(root))
@@ -1862,7 +1862,7 @@ static noinline int __btrfs_ioctl_snap_create(struct file *file,
18621862
btrfs_info(BTRFS_I(file_inode(file))->root->fs_info,
18631863
"Snapshot src from another FS");
18641864
ret = -EXDEV;
1865-
} else if (!inode_owner_or_capable(src_inode)) {
1865+
} else if (!inode_owner_or_capable(&init_user_ns, src_inode)) {
18661866
/*
18671867
* Subvolume creation is not restricted, but snapshots
18681868
* are limited to own subvolumes only
@@ -1982,7 +1982,7 @@ static noinline int btrfs_ioctl_subvol_setflags(struct file *file,
19821982
u64 flags;
19831983
int ret = 0;
19841984

1985-
if (!inode_owner_or_capable(inode))
1985+
if (!inode_owner_or_capable(&init_user_ns, inode))
19861986
return -EPERM;
19871987

19881988
ret = mnt_want_write_file(file);
@@ -4453,7 +4453,7 @@ static long _btrfs_ioctl_set_received_subvol(struct file *file,
44534453
int ret = 0;
44544454
int received_uuid_changed;
44554455

4456-
if (!inode_owner_or_capable(inode))
4456+
if (!inode_owner_or_capable(&init_user_ns, inode))
44574457
return -EPERM;
44584458

44594459
ret = mnt_want_write_file(file);

fs/btrfs/tests/btrfs-tests.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ struct inode *btrfs_new_test_inode(void)
6262
BTRFS_I(inode)->location.type = BTRFS_INODE_ITEM_KEY;
6363
BTRFS_I(inode)->location.objectid = BTRFS_FIRST_FREE_OBJECTID;
6464
BTRFS_I(inode)->location.offset = 0;
65-
inode_init_owner(inode, NULL, S_IFREG);
65+
inode_init_owner(&init_user_ns, inode, NULL, S_IFREG);
6666

6767
return inode;
6868
}

fs/crypto/policy.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ int fscrypt_ioctl_set_policy(struct file *filp, const void __user *arg)
465465
return -EFAULT;
466466
policy.version = version;
467467

468-
if (!inode_owner_or_capable(inode))
468+
if (!inode_owner_or_capable(&init_user_ns, inode))
469469
return -EACCES;
470470

471471
ret = mnt_want_write_file(filp);

fs/efivarfs/file.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ efivarfs_ioc_setxflags(struct file *file, void __user *arg)
137137
unsigned int oldflags = efivarfs_getflags(inode);
138138
int error;
139139

140-
if (!inode_owner_or_capable(inode))
140+
if (!inode_owner_or_capable(&init_user_ns, inode))
141141
return -EACCES;
142142

143143
if (copy_from_user(&flags, arg, sizeof(flags)))

fs/ext2/ialloc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ struct inode *ext2_new_inode(struct inode *dir, umode_t mode,
551551
inode->i_uid = current_fsuid();
552552
inode->i_gid = dir->i_gid;
553553
} else
554-
inode_init_owner(inode, dir, mode);
554+
inode_init_owner(&init_user_ns, inode, dir, mode);
555555

556556
inode->i_ino = ino;
557557
inode->i_blocks = 0;

0 commit comments

Comments
 (0)