[PATCH 02/38] media: v4l2-ioctl: avoid memory leaks on some time32 compat functions

From: Mauro Carvalho Chehab
Date: Wed Sep 02 2020 - 12:19:00 EST


There are some reports about possible memory leaks:

drivers/media/v4l2-core//v4l2-ioctl.c:3203 video_put_user() warn: check that 'ev32' doesn't leak information (struct has a hole after 'type')
drivers/media/v4l2-core//v4l2-ioctl.c:3230 video_put_user() warn: check that 'vb32' doesn't leak information (struct has a hole after 'memory')

While smatch seems to be reporting a false positive (line 3203),
there's indeed a possible leak with reserved2 at vb32.

We might have fixed just that one, but smatch checks won't
be able to check leaks at ev32. So, re-work the code in a way
that will ensure that the var contents will be zeroed before
filling it.

With that, we don't need anymore to touch reserved fields.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@xxxxxxxxxx>
---
drivers/media/v4l2-core/v4l2-ioctl.c | 48 ++++++++++++++--------------
1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index a556880f225a..6f3fe9c4b64a 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -3189,17 +3189,16 @@ static int video_put_user(void __user *arg, void *parg, unsigned int cmd)
#ifdef CONFIG_COMPAT_32BIT_TIME
case VIDIOC_DQEVENT_TIME32: {
struct v4l2_event *ev = parg;
- struct v4l2_event_time32 ev32 = {
- .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,
- };
+ struct v4l2_event_time32 ev32;

+ memset(&ev32, 0, sizeof(ev32));
+ ev32.type = ev->type,
+ ev32.pending = ev->pending,
+ ev32.sequence = ev->sequence,
+ ev32.timestamp.tv_sec = ev->timestamp.tv_sec,
+ ev32.timestamp.tv_nsec = ev->timestamp.tv_nsec,
+ ev32.id = ev->id,
memcpy(&ev32.u, &ev->u, sizeof(ev->u));
- memcpy(&ev32.reserved, &ev->reserved, sizeof(ev->reserved));

if (copy_to_user(arg, &ev32, sizeof(ev32)))
return -EFAULT;
@@ -3210,21 +3209,22 @@ static int video_put_user(void __user *arg, void *parg, unsigned int cmd)
case VIDIOC_DQBUF_TIME32:
case VIDIOC_PREPARE_BUF_TIME32: {
struct v4l2_buffer *vb = parg;
- struct v4l2_buffer_time32 vb32 = {
- .index = vb->index,
- .type = vb->type,
- .bytesused = vb->bytesused,
- .flags = vb->flags,
- .field = vb->field,
- .timestamp.tv_sec = vb->timestamp.tv_sec,
- .timestamp.tv_usec = vb->timestamp.tv_usec,
- .timecode = vb->timecode,
- .sequence = vb->sequence,
- .memory = vb->memory,
- .m.userptr = vb->m.userptr,
- .length = vb->length,
- .request_fd = vb->request_fd,
- };
+ struct v4l2_buffer_time32 vb32;
+
+ memset(&vb32, 0, sizeof(vb32));
+ vb32.index = vb->index,
+ vb32.type = vb->type,
+ vb32.bytesused = vb->bytesused,
+ vb32.flags = vb->flags,
+ vb32.field = vb->field,
+ vb32.timestamp.tv_sec = vb->timestamp.tv_sec,
+ vb32.timestamp.tv_usec = vb->timestamp.tv_usec,
+ vb32.timecode = vb->timecode,
+ vb32.sequence = vb->sequence,
+ vb32.memory = vb->memory,
+ vb32.length = vb->length,
+ vb32.request_fd = vb->request_fd,
+ memcpy(&vb32.m, &vb->m, sizeof(vb->m));

if (copy_to_user(arg, &vb32, sizeof(vb32)))
return -EFAULT;
--
2.26.2