From 1a6c0b36dd19c51cdd76895d009c5deba2286ebb Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 16 Dec 2019 15:15:03 +0100 Subject: media: v4l2-core: fix VIDIOC_DQEVENT for time64 ABI The v4l2_event structure contains a 'struct timespec' member that is defined by the user space C library, creating an ABI incompatibility when that gets updated to a 64-bit time_t. While passing a 32-bit time_t here would be sufficient for CLOCK_MONOTONIC timestamps, simply redefining the structure to use the kernel's __kernel_old_timespec would not work for any library that uses a copy of the linux/videodev2.h header file rather than including the copy from the latest kernel headers. This means the kernel has to be changed to handle both versions of the structure layout on a 32-bit architecture. The easiest way to do this is during the copy from/to user space. Signed-off-by: Arnd Bergmann Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-subdev.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'drivers/media/v4l2-core/v4l2-subdev.c') diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index 9e987c0f840e..de926e311348 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -331,8 +331,8 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) struct v4l2_fh *vfh = file->private_data; #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh); - int rval; #endif + int rval; switch (cmd) { case VIDIOC_QUERYCTRL: @@ -392,6 +392,30 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) return v4l2_event_dequeue(vfh, arg, file->f_flags & O_NONBLOCK); + case VIDIOC_DQEVENT_TIME32: { + struct v4l2_event_time32 *ev32 = arg; + struct v4l2_event ev; + + if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS)) + return -ENOIOCTLCMD; + + rval = v4l2_event_dequeue(vfh, &ev, file->f_flags & O_NONBLOCK); + + *ev32 = (struct v4l2_event_time32) { + .type = ev.type, + .pending = ev.pending, + .sequence = ev.sequence, + .timestamp.tv_sec = ev.timestamp.tv_sec, + .timestamp.tv_nsec = ev.timestamp.tv_nsec, + .id = ev.id, + }; + + memcpy(&ev32->u, &ev.u, sizeof(ev.u)); + memcpy(&ev32->reserved, &ev.reserved, sizeof(ev.reserved)); + + return rval; + } + case VIDIOC_SUBSCRIBE_EVENT: return v4l2_subdev_call(sd, core, subscribe_event, vfh, arg); -- cgit From 0c8c1ae155b89be7e0cd7e74494dfc83554c56d2 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Tue, 7 Jan 2020 15:02:06 +0100 Subject: media: v4l2-core: fix uninitialized structure fields being returned to userspace In the case where v4l2_event_dequeue fails the structure ev is not being filled and this garbage data from the stack is being copied to the ev32 structure and being copied back to userspace on the VIDIOC_DQEVENT_TIME32 ioctl. Fix this by ensuring the ev structure is zero'd to ensure uninitialized data is not leaked back. Addresses-Coverity: ("Uninitialized scalar variable") Fixes: 1a6c0b36dd19 ("media: v4l2-core: fix VIDIOC_DQEVENT for time64 ABI") Signed-off-by: Colin Ian King Acked-by: Arnd Bergmann Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-subdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/v4l2-core/v4l2-subdev.c') diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index de926e311348..a376b351135f 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -394,7 +394,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) case VIDIOC_DQEVENT_TIME32: { struct v4l2_event_time32 *ev32 = arg; - struct v4l2_event ev; + struct v4l2_event ev = { }; if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS)) return -ENOIOCTLCMD; -- cgit