Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 943bffb2 authored by Hans Verkuil's avatar Hans Verkuil Committed by Greg Kroah-Hartman
Browse files

media: vivid: s_fbuf: add more sanity checks



[ Upstream commit f8bcaf714abfc94818dff8c0db84d750433984f4 ]

VIDIOC_S_FBUF is by definition a scary ioctl, which is why only root
can use it. But at least check if the framebuffer parameters match that
of one of the framebuffer created by vivid, and reject anything else.

Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Fixes: ef834f78 ([media] vivid: add the video capture and output parts)
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent dbfa3848
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -302,6 +302,28 @@ static int vidioc_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *a
	return vivid_vid_out_g_fbuf(file, fh, a);
}

/*
 * Only support the framebuffer of one of the vivid instances.
 * Anything else is rejected.
 */
bool vivid_validate_fb(const struct v4l2_framebuffer *a)
{
	struct vivid_dev *dev;
	int i;

	for (i = 0; i < n_devs; i++) {
		dev = vivid_devs[i];
		if (!dev || !dev->video_pbase)
			continue;
		if ((unsigned long)a->base == dev->video_pbase &&
		    a->fmt.width <= dev->display_width &&
		    a->fmt.height <= dev->display_height &&
		    a->fmt.bytesperline <= dev->display_byte_stride)
			return true;
	}
	return false;
}

static int vidioc_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *a)
{
	struct video_device *vdev = video_devdata(file);
+2 −0
Original line number Diff line number Diff line
@@ -561,4 +561,6 @@ static inline bool vivid_is_hdmi_out(const struct vivid_dev *dev)
	return dev->output_type[dev->output] == HDMI;
}

bool vivid_validate_fb(const struct v4l2_framebuffer *a);

#endif
+8 −1
Original line number Diff line number Diff line
@@ -1232,7 +1232,14 @@ int vivid_vid_cap_s_fbuf(struct file *file, void *fh,
		return -EINVAL;
	if (a->fmt.bytesperline < (a->fmt.width * fmt->bit_depth[0]) / 8)
		return -EINVAL;
	if (a->fmt.height * a->fmt.bytesperline < a->fmt.sizeimage)
	if (a->fmt.bytesperline > a->fmt.sizeimage / a->fmt.height)
		return -EINVAL;

	/*
	 * Only support the framebuffer of one of the vivid instances.
	 * Anything else is rejected.
	 */
	if (!vivid_validate_fb(a))
		return -EINVAL;

	dev->fb_vbase_cap = phys_to_virt((unsigned long)a->base);