btrfs: allow idmapped SET_RECEIVED_SUBVOL ioctls
authorChristian Brauner <christian.brauner@ubuntu.com>
Tue, 27 Jul 2021 10:48:55 +0000 (12:48 +0200)
committerDavid Sterba <dsterba@suse.com>
Mon, 23 Aug 2021 11:19:14 +0000 (13:19 +0200)
The SET_RECEIVED_SUBVOL ioctls are used to set information about
a received subvolume. Make it possible to set information about a
received subvolume on idmapped mounts. This is a fairly straightforward
operation since all the permission checking helpers are already capable
of handling idmapped mounts. So we just need to pass down the mount's
userns.

Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/ioctl.c

index 63e7b2616302dcbeae15a9fceaf990201cffc16d..aa60a957874799f52bbea44eb09bafed3c678b9d 100644 (file)
@@ -4448,6 +4448,7 @@ static long btrfs_ioctl_quota_rescan_wait(struct btrfs_fs_info *fs_info,
 }
 
 static long _btrfs_ioctl_set_received_subvol(struct file *file,
+                                           struct user_namespace *mnt_userns,
                                            struct btrfs_ioctl_received_subvol_args *sa)
 {
        struct inode *inode = file_inode(file);
@@ -4459,7 +4460,7 @@ static long _btrfs_ioctl_set_received_subvol(struct file *file,
        int ret = 0;
        int received_uuid_changed;
 
-       if (!inode_owner_or_capable(&init_user_ns, inode))
+       if (!inode_owner_or_capable(mnt_userns, inode))
                return -EPERM;
 
        ret = mnt_want_write_file(file);
@@ -4564,7 +4565,7 @@ static long btrfs_ioctl_set_received_subvol_32(struct file *file,
        args64->rtime.nsec = args32->rtime.nsec;
        args64->flags = args32->flags;
 
-       ret = _btrfs_ioctl_set_received_subvol(file, args64);
+       ret = _btrfs_ioctl_set_received_subvol(file, file_mnt_user_ns(file), args64);
        if (ret)
                goto out;
 
@@ -4598,7 +4599,7 @@ static long btrfs_ioctl_set_received_subvol(struct file *file,
        if (IS_ERR(sa))
                return PTR_ERR(sa);
 
-       ret = _btrfs_ioctl_set_received_subvol(file, sa);
+       ret = _btrfs_ioctl_set_received_subvol(file, file_mnt_user_ns(file), sa);
 
        if (ret)
                goto out;