summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2018-01-24 05:19:59 -0500
committerMauro Carvalho Chehab <mchehab@s-opensource.com>2018-01-30 07:30:22 -0500
commit8ed5a59dcb47a6f76034ee760b36e089f3e82529 (patch)
tree8c11b66491bc2630a9b2fe93b3309de9952e7efa
parent333b1e9f96ce05f7498b581509bb30cde03018bf (diff)
media: v4l2-compat-ioctl32.c: copy m.userptr in put_v4l2_plane32
The struct v4l2_plane32 should set m.userptr as well. The same happens in v4l2_buffer32 and v4l2-compliance tests for this. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com> Cc: <stable@vger.kernel.org> # for v4.15 and up Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
-rw-r--r--drivers/media/v4l2-core/v4l2-compat-ioctl32.c47
1 files changed, 28 insertions, 19 deletions
diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index 6c70705a48bc..7dff9b4aeb19 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -310,19 +310,24 @@ static int get_v4l2_plane32(struct v4l2_plane __user *up, struct v4l2_plane32 __
sizeof(up->data_offset)))
return -EFAULT;
- if (memory == V4L2_MEMORY_USERPTR) {
+ switch (memory) {
+ case V4L2_MEMORY_MMAP:
+ case V4L2_MEMORY_OVERLAY:
+ if (copy_in_user(&up->m.mem_offset, &up32->m.mem_offset,
+ sizeof(up32->m.mem_offset)))
+ return -EFAULT;
+ break;
+ case V4L2_MEMORY_USERPTR:
if (get_user(p, &up32->m.userptr))
return -EFAULT;
up_pln = compat_ptr(p);
if (put_user((unsigned long)up_pln, &up->m.userptr))
return -EFAULT;
- } else if (memory == V4L2_MEMORY_DMABUF) {
+ break;
+ case V4L2_MEMORY_DMABUF:
if (copy_in_user(&up->m.fd, &up32->m.fd, sizeof(up32->m.fd)))
return -EFAULT;
- } else {
- if (copy_in_user(&up->m.mem_offset, &up32->m.mem_offset,
- sizeof(up32->m.mem_offset)))
- return -EFAULT;
+ break;
}
return 0;
@@ -331,22 +336,32 @@ static int get_v4l2_plane32(struct v4l2_plane __user *up, struct v4l2_plane32 __
static int put_v4l2_plane32(struct v4l2_plane __user *up, struct v4l2_plane32 __user *up32,
enum v4l2_memory memory)
{
+ unsigned long p;
+
if (copy_in_user(up32, up, 2 * sizeof(__u32)) ||
copy_in_user(&up32->data_offset, &up->data_offset,
sizeof(up->data_offset)))
return -EFAULT;
- /* For MMAP, driver might've set up the offset, so copy it back.
- * USERPTR stays the same (was userspace-provided), so no copying. */
- if (memory == V4L2_MEMORY_MMAP)
+ switch (memory) {
+ case V4L2_MEMORY_MMAP:
+ case V4L2_MEMORY_OVERLAY:
if (copy_in_user(&up32->m.mem_offset, &up->m.mem_offset,
sizeof(up->m.mem_offset)))
return -EFAULT;
- /* For DMABUF, driver might've set up the fd, so copy it back. */
- if (memory == V4L2_MEMORY_DMABUF)
+ break;
+ case V4L2_MEMORY_USERPTR:
+ if (get_user(p, &up->m.userptr) ||
+ put_user((compat_ulong_t)ptr_to_compat((__force void *)p),
+ &up32->m.userptr))
+ return -EFAULT;
+ break;
+ case V4L2_MEMORY_DMABUF:
if (copy_in_user(&up32->m.fd, &up->m.fd,
sizeof(up->m.fd)))
return -EFAULT;
+ break;
+ }
return 0;
}
@@ -408,6 +423,7 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
} else {
switch (kp->memory) {
case V4L2_MEMORY_MMAP:
+ case V4L2_MEMORY_OVERLAY:
if (get_user(kp->m.offset, &up->m.offset))
return -EFAULT;
break;
@@ -421,10 +437,6 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
kp->m.userptr = (unsigned long)compat_ptr(tmp);
}
break;
- case V4L2_MEMORY_OVERLAY:
- if (get_user(kp->m.offset, &up->m.offset))
- return -EFAULT;
- break;
case V4L2_MEMORY_DMABUF:
if (get_user(kp->m.fd, &up->m.fd))
return -EFAULT;
@@ -481,6 +493,7 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
} else {
switch (kp->memory) {
case V4L2_MEMORY_MMAP:
+ case V4L2_MEMORY_OVERLAY:
if (put_user(kp->m.offset, &up->m.offset))
return -EFAULT;
break;
@@ -488,10 +501,6 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
if (put_user(kp->m.userptr, &up->m.userptr))
return -EFAULT;
break;
- case V4L2_MEMORY_OVERLAY:
- if (put_user(kp->m.offset, &up->m.offset))
- return -EFAULT;
- break;
case V4L2_MEMORY_DMABUF:
if (put_user(kp->m.fd, &up->m.fd))
return -EFAULT;