Message ID | 20170615121259.8281-2-linus.walleij@linaro.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hi, On 2017/6/15 20:12, Linus Walleij wrote: > mmc_blk_ioctl() calls either mmc_blk_ioctl_cmd() or > mmc_blk_ioctl_multi_cmd() and each of these make the same > check. Factor it into a new helper function, call it on > both branches of the switch() statement and save a chunk > of duplicate code. > > Cc: Shawn Lin <shawn.lin@rock-chips.com> > Signed-off-by: Linus Walleij <linus.walleij@linaro.org> > --- > ChangeLog v1->v2: > - We need to check the block device only if an actual > well-known ioctl() is coming in, on the path of the > switch() statments, only those branches that handle > actual ioctl()s. Create a new helper function to check > the block device and call that. Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com> > --- > drivers/mmc/core/block.c | 36 ++++++++++++++++++++---------------- > 1 file changed, 20 insertions(+), 16 deletions(-) > > diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c > index 1ce6012ce3c1..d1b824e65590 100644 > --- a/drivers/mmc/core/block.c > +++ b/drivers/mmc/core/block.c > @@ -566,14 +566,6 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, > int err = 0, ioc_err = 0; > struct request *req; > > - /* > - * The caller must have CAP_SYS_RAWIO, and must be calling this on the > - * whole block device, not on a partition. This prevents overspray > - * between sibling partitions. > - */ > - if ((!capable(CAP_SYS_RAWIO)) || (bdev != bdev->bd_contains)) > - return -EPERM; > - > idata = mmc_blk_ioctl_copy_from_user(ic_ptr); > if (IS_ERR(idata)) > return PTR_ERR(idata); > @@ -626,14 +618,6 @@ static int mmc_blk_ioctl_multi_cmd(struct block_device *bdev, > __u64 num_of_cmds; > struct request *req; > > - /* > - * The caller must have CAP_SYS_RAWIO, and must be calling this on the > - * whole block device, not on a partition. This prevents overspray > - * between sibling partitions. > - */ > - if ((!capable(CAP_SYS_RAWIO)) || (bdev != bdev->bd_contains)) > - return -EPERM; > - > if (copy_from_user(&num_of_cmds, &user->num_of_cmds, > sizeof(num_of_cmds))) > return -EFAULT; > @@ -697,14 +681,34 @@ static int mmc_blk_ioctl_multi_cmd(struct block_device *bdev, > return ioc_err ? ioc_err : err; > } > > +static int mmc_blk_check_blkdev(struct block_device *bdev) > +{ > + /* > + * The caller must have CAP_SYS_RAWIO, and must be calling this on the > + * whole block device, not on a partition. This prevents overspray > + * between sibling partitions. > + */ > + if ((!capable(CAP_SYS_RAWIO)) || (bdev != bdev->bd_contains)) > + return -EPERM; > + return 0; > +} > + > static int mmc_blk_ioctl(struct block_device *bdev, fmode_t mode, > unsigned int cmd, unsigned long arg) > { > + int ret; > + > switch (cmd) { > case MMC_IOC_CMD: > + ret = mmc_blk_check_blkdev(bdev); > + if (ret) > + return ret; > return mmc_blk_ioctl_cmd(bdev, > (struct mmc_ioc_cmd __user *)arg); > case MMC_IOC_MULTI_CMD: > + ret = mmc_blk_check_blkdev(bdev); > + if (ret) > + return ret; > return mmc_blk_ioctl_multi_cmd(bdev, > (struct mmc_ioc_multi_cmd __user *)arg); > default: >
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index 1ce6012ce3c1..d1b824e65590 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -566,14 +566,6 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, int err = 0, ioc_err = 0; struct request *req; - /* - * The caller must have CAP_SYS_RAWIO, and must be calling this on the - * whole block device, not on a partition. This prevents overspray - * between sibling partitions. - */ - if ((!capable(CAP_SYS_RAWIO)) || (bdev != bdev->bd_contains)) - return -EPERM; - idata = mmc_blk_ioctl_copy_from_user(ic_ptr); if (IS_ERR(idata)) return PTR_ERR(idata); @@ -626,14 +618,6 @@ static int mmc_blk_ioctl_multi_cmd(struct block_device *bdev, __u64 num_of_cmds; struct request *req; - /* - * The caller must have CAP_SYS_RAWIO, and must be calling this on the - * whole block device, not on a partition. This prevents overspray - * between sibling partitions. - */ - if ((!capable(CAP_SYS_RAWIO)) || (bdev != bdev->bd_contains)) - return -EPERM; - if (copy_from_user(&num_of_cmds, &user->num_of_cmds, sizeof(num_of_cmds))) return -EFAULT; @@ -697,14 +681,34 @@ static int mmc_blk_ioctl_multi_cmd(struct block_device *bdev, return ioc_err ? ioc_err : err; } +static int mmc_blk_check_blkdev(struct block_device *bdev) +{ + /* + * The caller must have CAP_SYS_RAWIO, and must be calling this on the + * whole block device, not on a partition. This prevents overspray + * between sibling partitions. + */ + if ((!capable(CAP_SYS_RAWIO)) || (bdev != bdev->bd_contains)) + return -EPERM; + return 0; +} + static int mmc_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { + int ret; + switch (cmd) { case MMC_IOC_CMD: + ret = mmc_blk_check_blkdev(bdev); + if (ret) + return ret; return mmc_blk_ioctl_cmd(bdev, (struct mmc_ioc_cmd __user *)arg); case MMC_IOC_MULTI_CMD: + ret = mmc_blk_check_blkdev(bdev); + if (ret) + return ret; return mmc_blk_ioctl_multi_cmd(bdev, (struct mmc_ioc_multi_cmd __user *)arg); default:
mmc_blk_ioctl() calls either mmc_blk_ioctl_cmd() or mmc_blk_ioctl_multi_cmd() and each of these make the same check. Factor it into a new helper function, call it on both branches of the switch() statement and save a chunk of duplicate code. Cc: Shawn Lin <shawn.lin@rock-chips.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> --- ChangeLog v1->v2: - We need to check the block device only if an actual well-known ioctl() is coming in, on the path of the switch() statments, only those branches that handle actual ioctl()s. Create a new helper function to check the block device and call that. --- drivers/mmc/core/block.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-)