Commit 4ffb879e authored by Peilin Ye's avatar Peilin Ye Committed by Mauro Carvalho Chehab
Browse files

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: default avatar <syzbot+79d751604cb6f29fbf59@syzkaller.appspotmail.com>
Link: https://syzkaller.appspot.com/bug?extid=79d751604cb6f29fbf59



Cc: stable@vger.kernel.org
Fixes: 1a6c0b36 ("media: v4l2-core: fix VIDIOC_DQEVENT for time64 ABI")
Fixes: 577c89b0 ("media: v4l2-core: fix v4l2_buffer handling for time64 ABI")
Reviewed-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: default avatarArnd Bergmann <arnd@arndb.de>
Signed-off-by: default avatarPeilin Ye <yepeilin.cs@gmail.com>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
parent bec2ddfd
Loading
Loading
Loading
Loading
+27 −23
Original line number Diff line number Diff line
@@ -3189,14 +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));
@@ -3210,21 +3212,23 @@ 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.m.userptr	= vb->m.userptr;
		vb32.length	= vb->length;
		vb32.request_fd	= vb->request_fd;

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