summaryrefslogtreecommitdiff
path: root/drivers/media/v4l2-core
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2020-10-30 17:55:26 +0100
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>2020-11-16 10:31:06 +0100
commit3f65c6f67e8813448d7e3cfd3470b0f8c15bfaea (patch)
tree9eb3fb033057c603884fb676066e89feec40d896 /drivers/media/v4l2-core
parent00af58fd9a20556a25deb85f32085f82c697c178 (diff)
media: v4l2: allocate v4l2_clip objects early
The v4l2_format based ioctls can have an indirect pointer to an array of v4l2_clip structures for overlay mode, depending on the 'type' member. There are only five drivers that use the overlay mode and copy the data through the __user pointer. Change the five drivers to use memcpy() instead, and copy the data in common code using the check_array_args() helpers. This allows for a subsequent patch that use the same mechanism for compat ioctl handlers. Note that there is another pointer for a 'bitmap' that is only used in the 'vivid' driver and nowhere else. There is no easy way to use the same trick without adding complexity to the common code, so this remains a __user pointer. [hverkuil: fix: CHECK: spaces preferred around that '*' (ctx:VxV)] [hverkuil: fix: CHECK: Alignment should match open parenthesis] Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Diffstat (limited to 'drivers/media/v4l2-core')
-rw-r--r--drivers/media/v4l2-core/v4l2-ioctl.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index b8be61a09776..f0f6906a879d 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -1582,7 +1582,7 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
switch (p->type) {
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: {
- struct v4l2_clip __user *clips = p->fmt.win.clips;
+ struct v4l2_clip *clips = p->fmt.win.clips;
u32 clipcount = p->fmt.win.clipcount;
void __user *bitmap = p->fmt.win.bitmap;
@@ -3084,6 +3084,27 @@ static int check_array_args(unsigned int cmd, void *parg, size_t *array_size,
}
break;
}
+ case VIDIOC_G_FMT:
+ case VIDIOC_S_FMT:
+ case VIDIOC_TRY_FMT: {
+ struct v4l2_format *fmt = parg;
+
+ if (fmt->type != V4L2_BUF_TYPE_VIDEO_OVERLAY &&
+ fmt->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY)
+ break;
+ if (fmt->fmt.win.clipcount > 2048)
+ return -EINVAL;
+ if (!fmt->fmt.win.clipcount)
+ break;
+
+ *user_ptr = (void __user *)fmt->fmt.win.clips;
+ *kernel_ptr = (void **)&fmt->fmt.win.clips;
+ *array_size = sizeof(struct v4l2_clip)
+ * fmt->fmt.win.clipcount;
+
+ ret = 1;
+ break;
+ }
}
return ret;