Skip to content

Commit

Permalink
compat_ioctl: block: simplify compat_blkpg_ioctl()
Browse files Browse the repository at this point in the history
There is no need to go through a compat_alloc_user_space()
copy any more, just wrap the function in a small helper that
works the same way for native and compat mode.

Reviewed-by: Ben Hutchings <[email protected]>
Signed-off-by: Arnd Bergmann <[email protected]>
  • Loading branch information
arndb committed Jan 3, 2020
1 parent bdc1dda commit 5fb889f
Showing 1 changed file with 38 additions and 36 deletions.
74 changes: 38 additions & 36 deletions block/ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,28 @@
#include <linux/pr.h>
#include <linux/uaccess.h>

static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user *arg)
static int blkpg_do_ioctl(struct block_device *bdev,
struct blkpg_partition __user *upart, int op)
{
struct block_device *bdevp;
struct gendisk *disk;
struct hd_struct *part, *lpart;
struct blkpg_ioctl_arg a;
struct blkpg_partition p;
struct disk_part_iter piter;
long long start, length;
int partno;

if (!capable(CAP_SYS_ADMIN))
return -EACCES;
if (copy_from_user(&a, arg, sizeof(struct blkpg_ioctl_arg)))
return -EFAULT;
if (copy_from_user(&p, a.data, sizeof(struct blkpg_partition)))
if (copy_from_user(&p, upart, sizeof(struct blkpg_partition)))
return -EFAULT;
disk = bdev->bd_disk;
if (bdev != bdev->bd_contains)
return -EINVAL;
partno = p.pno;
if (partno <= 0)
return -EINVAL;
switch (a.op) {
switch (op) {
case BLKPG_ADD_PARTITION:
start = p.start >> 9;
length = p.length >> 9;
Expand Down Expand Up @@ -156,6 +154,39 @@ static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user
}
}

static int blkpg_ioctl(struct block_device *bdev,
struct blkpg_ioctl_arg __user *arg)
{
struct blkpg_partition __user *udata;
int op;

if (get_user(op, &arg->op) || get_user(udata, &arg->data))
return -EFAULT;

return blkpg_do_ioctl(bdev, udata, op);
}

#ifdef CONFIG_COMPAT
struct compat_blkpg_ioctl_arg {
compat_int_t op;
compat_int_t flags;
compat_int_t datalen;
compat_caddr_t data;
};

static int compat_blkpg_ioctl(struct block_device *bdev,
struct compat_blkpg_ioctl_arg __user *arg)
{
compat_caddr_t udata;
int op;

if (get_user(op, &arg->op) || get_user(udata, &arg->data))
return -EFAULT;

return blkpg_do_ioctl(bdev, compat_ptr(udata), op);
}
#endif

static int blkdev_reread_part(struct block_device *bdev)
{
int ret;
Expand Down Expand Up @@ -676,35 +707,6 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
EXPORT_SYMBOL_GPL(blkdev_ioctl);

#ifdef CONFIG_COMPAT
struct compat_blkpg_ioctl_arg {
compat_int_t op;
compat_int_t flags;
compat_int_t datalen;
compat_caddr_t data;
};

static int compat_blkpg_ioctl(struct block_device *bdev, fmode_t mode,
unsigned int cmd, struct compat_blkpg_ioctl_arg __user *ua32)
{
struct blkpg_ioctl_arg __user *a = compat_alloc_user_space(sizeof(*a));
compat_caddr_t udata;
compat_int_t n;
int err;

err = get_user(n, &ua32->op);
err |= put_user(n, &a->op);
err |= get_user(n, &ua32->flags);
err |= put_user(n, &a->flags);
err |= get_user(n, &ua32->datalen);
err |= put_user(n, &a->datalen);
err |= get_user(udata, &ua32->data);
err |= put_user(compat_ptr(udata), &a->data);
if (err)
return err;

return blkdev_ioctl(bdev, mode, cmd, (unsigned long)a);
}

#define BLKBSZGET_32 _IOR(0x12, 112, int)
#define BLKBSZSET_32 _IOW(0x12, 113, int)
#define BLKGETSIZE64_32 _IOR(0x12, 114, int)
Expand Down Expand Up @@ -767,7 +769,7 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
return blkdev_ioctl(bdev, mode, BLKBSZSET,
(unsigned long)compat_ptr(arg));
case BLKPG:
return compat_blkpg_ioctl(bdev, mode, cmd, compat_ptr(arg));
return compat_blkpg_ioctl(bdev, compat_ptr(arg));
case BLKRAGET:
case BLKFRAGET:
if (!arg)
Expand Down

0 comments on commit 5fb889f

Please sign in to comment.