Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

media: media/v4l2-core: Fix kernel-infoleak in video_put_user()

video_put_user() is copying uninitialized stack memory to userspace due
to the compiler not initializing holes in the structures declared on the
stack. Fix it by initializing `ev32` and `vb32` using memset().

Reported-and-tested-by: syzbot+79d751604cb6f29fbf59@syzkaller.appspotmail.com
Link: https://syzkaller.appspot.com/bug?extid=79d751604cb6f29fbf59

Cc: stable@vger.kernel.org
Fixes: 1a6c0b36dd19 ("media: v4l2-core: fix VIDIOC_DQEVENT for time64 ABI")
Fixes: 577c89b0ce72 ("media: v4l2-core: fix v4l2_buffer handling for time64 ABI")
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Peilin Ye <yepeilin.cs@gmail.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>

authored by

Peilin Ye and committed by
Mauro Carvalho Chehab
4ffb879e bec2ddfd

+27 -23
+27 -23
drivers/media/v4l2-core/v4l2-ioctl.c
··· 3189 3189 #ifdef CONFIG_COMPAT_32BIT_TIME 3190 3190 case VIDIOC_DQEVENT_TIME32: { 3191 3191 struct v4l2_event *ev = parg; 3192 - struct v4l2_event_time32 ev32 = { 3193 - .type = ev->type, 3194 - .pending = ev->pending, 3195 - .sequence = ev->sequence, 3196 - .timestamp.tv_sec = ev->timestamp.tv_sec, 3197 - .timestamp.tv_nsec = ev->timestamp.tv_nsec, 3198 - .id = ev->id, 3199 - }; 3192 + struct v4l2_event_time32 ev32; 3193 + 3194 + memset(&ev32, 0, sizeof(ev32)); 3195 + 3196 + ev32.type = ev->type; 3197 + ev32.pending = ev->pending; 3198 + ev32.sequence = ev->sequence; 3199 + ev32.timestamp.tv_sec = ev->timestamp.tv_sec; 3200 + ev32.timestamp.tv_nsec = ev->timestamp.tv_nsec; 3201 + ev32.id = ev->id; 3200 3202 3201 3203 memcpy(&ev32.u, &ev->u, sizeof(ev->u)); 3202 3204 memcpy(&ev32.reserved, &ev->reserved, sizeof(ev->reserved)); ··· 3212 3210 case VIDIOC_DQBUF_TIME32: 3213 3211 case VIDIOC_PREPARE_BUF_TIME32: { 3214 3212 struct v4l2_buffer *vb = parg; 3215 - struct v4l2_buffer_time32 vb32 = { 3216 - .index = vb->index, 3217 - .type = vb->type, 3218 - .bytesused = vb->bytesused, 3219 - .flags = vb->flags, 3220 - .field = vb->field, 3221 - .timestamp.tv_sec = vb->timestamp.tv_sec, 3222 - .timestamp.tv_usec = vb->timestamp.tv_usec, 3223 - .timecode = vb->timecode, 3224 - .sequence = vb->sequence, 3225 - .memory = vb->memory, 3226 - .m.userptr = vb->m.userptr, 3227 - .length = vb->length, 3228 - .request_fd = vb->request_fd, 3229 - }; 3213 + struct v4l2_buffer_time32 vb32; 3214 + 3215 + memset(&vb32, 0, sizeof(vb32)); 3216 + 3217 + vb32.index = vb->index; 3218 + vb32.type = vb->type; 3219 + vb32.bytesused = vb->bytesused; 3220 + vb32.flags = vb->flags; 3221 + vb32.field = vb->field; 3222 + vb32.timestamp.tv_sec = vb->timestamp.tv_sec; 3223 + vb32.timestamp.tv_usec = vb->timestamp.tv_usec; 3224 + vb32.timecode = vb->timecode; 3225 + vb32.sequence = vb->sequence; 3226 + vb32.memory = vb->memory; 3227 + vb32.m.userptr = vb->m.userptr; 3228 + vb32.length = vb->length; 3229 + vb32.request_fd = vb->request_fd; 3230 3230 3231 3231 if (copy_to_user(arg, &vb32, sizeof(vb32))) 3232 3232 return -EFAULT;