This patch supports to handle 64/32 compatible array parameter, such as below: struct v4l2_fd_result { __u32 buf_index; __u32 face_cnt; __u32 reserved[6]; struct v4l2_fd_detection fd[]; }; With this patch, the pointer to user space array needn't be passed to kernel any more. Cc: Arnd Bergmann <arnd@xxxxxxxx> Signed-off-by: Ming Lei <ming.lei@xxxxxxxxxxxxx> --- drivers/media/video/v4l2-ioctl.c | 33 +++++++++++++++++++++++++++++++-- 1 files changed, 31 insertions(+), 2 deletions(-) diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index e1da8fc..ded8b72 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c @@ -2239,6 +2239,11 @@ static int check_array_args(unsigned int cmd, void *parg, size_t *array_size, return ret; } +static int is_64_32_array_args(unsigned int cmd, void *parg, int *extra_len) +{ + return 0; +} + long video_usercopy(struct file *file, unsigned int cmd, unsigned long arg, v4l2_kioctl func) @@ -2251,6 +2256,7 @@ 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; + int extra = 0; /* Copy arguments into temp kernel buffer */ if (_IOC_DIR(cmd) != _IOC_NONE) { @@ -2280,9 +2286,32 @@ video_usercopy(struct file *file, unsigned int cmd, unsigned long arg, } } - err = check_array_args(cmd, parg, &array_size, &user_ptr, &kernel_ptr); + if (is_64_32_array_args(cmd, parg, &extra)) { + int size; + void *old_mbuf; + + err = 0; + if (!extra) + goto handle_array_args; + old_mbuf = mbuf; + size = extra + _IOC_SIZE(cmd); + mbuf = kmalloc(size, GFP_KERNEL); + if (NULL == mbuf) { + mbuf = old_mbuf; + err = -ENOMEM; + goto out; + } + memcpy(mbuf, parg, _IOC_SIZE(cmd)); + parg = mbuf; + kfree(old_mbuf); + } else { + err = check_array_args(cmd, parg, &array_size, + &user_ptr, &kernel_ptr); + } + if (err < 0) goto out; +handle_array_args: has_array_args = err; if (has_array_args) { @@ -2321,7 +2350,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, _IOC_SIZE(cmd) + extra)) err = -EFAULT; break; } -- 1.7.5.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html