media: v4l2-ioctl: fix some "too small" warnings
authorMauro Carvalho Chehab <mchehab@s-opensource.com>
Thu, 22 Mar 2018 18:02:21 +0000 (14:02 -0400)
committerMauro Carvalho Chehab <mchehab@s-opensource.com>
Fri, 23 Mar 2018 10:28:42 +0000 (06:28 -0400)
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>
drivers/media/v4l2-core/v4l2-ioctl.c

index 672ab22ccd96df9c47572e1d66d1deb738726882..a5dab16ff2d29003eaae87ec42a405b2e990540e 100644 (file)
@@ -2833,14 +2833,15 @@ video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
        size_t  array_size = 0;
        void __user *user_ptr = NULL;
        void    **kernel_ptr = NULL;
+       size_t  size = _IOC_SIZE(cmd);
 
        /*  Copy arguments into temp kernel buffer  */
        if (_IOC_DIR(cmd) != _IOC_NONE) {
-               if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
+               if (size <= sizeof(sbuf)) {
                        parg = sbuf;
                } else {
                        /* too big to allocate from stack */
-                       mbuf = kvmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
+                       mbuf = kvmalloc(size, GFP_KERNEL);
                        if (NULL == mbuf)
                                return -ENOMEM;
                        parg = mbuf;
@@ -2848,7 +2849,7 @@ video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
 
                err = -EFAULT;
                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,
@@ -2869,11 +2870,11 @@ video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
                                goto out;
 
                        /* zero out anything we don't copy from userspace */
-                       if (n < _IOC_SIZE(cmd))
-                               memset((u8 *)parg + n, 0, _IOC_SIZE(cmd) - n);
+                       if (n < size)
+                               memset((u8 *)parg + n, 0, size - n);
                } else {
                        /* read-only ioctl */
-                       memset(parg, 0, _IOC_SIZE(cmd));
+                       memset(parg, 0, size);
                }
        }
 
@@ -2931,7 +2932,7 @@ out_array_args:
        switch (_IOC_DIR(cmd)) {
        case _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;
                break;
        }