diff --git a/block/ioctl.c b/block/ioctl.c index 61feed686418..98c4c7b9e7fe 100644 --- a/block/ioctl.c +++ b/block/ioctl.c @@ -18,6 +18,8 @@ #include "blk.h" #include "blk-crypto-internal.h" +#define PR_KEYS_MAX_NUM (1u << 16) + static int blkpg_do_ioctl(struct block_device *bdev, struct blkpg_partition __user *upart, int op) { @@ -442,11 +444,12 @@ static int blkdev_pr_read_keys(struct block_device *bdev, blk_mode_t mode, if (copy_from_user(&read_keys, arg, sizeof(read_keys))) return -EFAULT; - keys_info_len = struct_size(keys_info, keys, read_keys.num_keys); - if (keys_info_len == SIZE_MAX) + if (read_keys.num_keys > PR_KEYS_MAX_NUM) return -EINVAL; - keys_info = kzalloc(keys_info_len, GFP_KERNEL); + keys_info_len = struct_size(keys_info, keys, read_keys.num_keys); + + keys_info = kvzalloc(keys_info_len, GFP_KERNEL); if (!keys_info) return -ENOMEM; @@ -473,7 +476,7 @@ static int blkdev_pr_read_keys(struct block_device *bdev, blk_mode_t mode, if (copy_to_user(arg, &read_keys, sizeof(read_keys))) ret = -EFAULT; out: - kfree(keys_info); + kvfree(keys_info); return ret; }