media: v4l2-ioctl: fix some "too small" warnings

While the code there is right, it produces three false positives:
	drivers/media/v4l2-core/v4l2-ioctl.c:2868 video_usercopy() error: copy_from_user() 'parg' too small (128 vs 16383)
	drivers/media/v4l2-core/v4l2-ioctl.c:2868 video_usercopy() error: copy_from_user() 'parg' too small (128 vs 16383)
	drivers/media/v4l2-core/v4l2-ioctl.c:2876 video_usercopy() error: memset() 'parg' too small (128 vs 16383)

Store the ioctl size on a cache var, in order to suppress those.

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
This commit is contained in:
Mauro Carvalho Chehab 2018-03-22 14:02:21 -04:00
parent 1a086879fd
commit 912d2f8228
1 changed files with 8 additions and 7 deletions

View File

@ -2833,14 +2833,15 @@ video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
size_t array_size = 0; size_t array_size = 0;
void __user *user_ptr = NULL; void __user *user_ptr = NULL;
void **kernel_ptr = NULL; void **kernel_ptr = NULL;
size_t size = _IOC_SIZE(cmd);
/* Copy arguments into temp kernel buffer */ /* Copy arguments into temp kernel buffer */
if (_IOC_DIR(cmd) != _IOC_NONE) { if (_IOC_DIR(cmd) != _IOC_NONE) {
if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { if (size <= sizeof(sbuf)) {
parg = sbuf; parg = sbuf;
} else { } else {
/* too big to allocate from stack */ /* too big to allocate from stack */
mbuf = kvmalloc(_IOC_SIZE(cmd), GFP_KERNEL); mbuf = kvmalloc(size, GFP_KERNEL);
if (NULL == mbuf) if (NULL == mbuf)
return -ENOMEM; return -ENOMEM;
parg = mbuf; parg = mbuf;
@ -2848,7 +2849,7 @@ video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
err = -EFAULT; err = -EFAULT;
if (_IOC_DIR(cmd) & _IOC_WRITE) { if (_IOC_DIR(cmd) & _IOC_WRITE) {
unsigned int n = _IOC_SIZE(cmd); unsigned int n = size;
/* /*
* In some cases, only a few fields are used as input, * In some cases, only a few fields are used as input,
@ -2869,11 +2870,11 @@ video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
goto out; goto out;
/* zero out anything we don't copy from userspace */ /* zero out anything we don't copy from userspace */
if (n < _IOC_SIZE(cmd)) if (n < size)
memset((u8 *)parg + n, 0, _IOC_SIZE(cmd) - n); memset((u8 *)parg + n, 0, size - n);
} else { } else {
/* read-only ioctl */ /* read-only ioctl */
memset(parg, 0, _IOC_SIZE(cmd)); memset(parg, 0, size);
} }
} }
@ -2931,7 +2932,7 @@ out_array_args:
switch (_IOC_DIR(cmd)) { switch (_IOC_DIR(cmd)) {
case _IOC_READ: case _IOC_READ:
case (_IOC_WRITE | _IOC_READ): case (_IOC_WRITE | _IOC_READ):
if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) if (copy_to_user((void __user *)arg, parg, size))
err = -EFAULT; err = -EFAULT;
break; break;
} }