Commit 96d85695 authored by Hans Verkuil's avatar Hans Verkuil
Browse files

media: vivid: fix buffer overwrite when using > 32 buffers

The maximum number of buffers that can be requested was increased to
64 for the video capture queue. But video capture used a must_blank
array that was still sized for 32 (VIDEO_MAX_FRAME). This caused an
out-of-bounds write when using buffer indices >= 32.

Create a new define MAX_VID_CAP_BUFFERS that is used to access the
must_blank array and set max_num_buffers for the video capture queue.

This solves a crash reported by:

	https://bugzilla.kernel.org/show_bug.cgi?id=219258



Signed-off-by: default avatarHans Verkuil <hverkuil@xs4all.nl>
Fixes: cea70ed4 ("media: test-drivers: vivid: Increase max supported buffers for capture queues")
Cc: stable@vger.kernel.org
parent ba9cf6b4
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -910,7 +910,7 @@ static int vivid_create_queue(struct vivid_dev *dev,
	 * videobuf2-core.c to MAX_BUFFER_INDEX.
	 */
	if (buf_type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
		q->max_num_buffers = 64;
		q->max_num_buffers = MAX_VID_CAP_BUFFERS;
	if (buf_type == V4L2_BUF_TYPE_SDR_CAPTURE)
		q->max_num_buffers = 1024;
	if (buf_type == V4L2_BUF_TYPE_VBI_CAPTURE)
+3 −1
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@
#define MAX_INPUTS 16
/* The maximum number of outputs */
#define MAX_OUTPUTS 16
/* The maximum number of video capture buffers */
#define MAX_VID_CAP_BUFFERS 64
/* The maximum up or down scaling factor is 4 */
#define MAX_ZOOM  4
/* The maximum image width/height are set to 4K DMT */
@@ -481,7 +483,7 @@ struct vivid_dev {
	/* video capture */
	struct tpg_data			tpg;
	unsigned			ms_vid_cap;
	bool				must_blank[VIDEO_MAX_FRAME];
	bool				must_blank[MAX_VID_CAP_BUFFERS];

	const struct vivid_fmt		*fmt_cap;
	struct v4l2_fract		timeperframe_vid_cap;
+1 −1
Original line number Diff line number Diff line
@@ -553,7 +553,7 @@ static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl)
		break;
	case VIVID_CID_PERCENTAGE_FILL:
		tpg_s_perc_fill(&dev->tpg, ctrl->val);
		for (i = 0; i < VIDEO_MAX_FRAME; i++)
		for (i = 0; i < MAX_VID_CAP_BUFFERS; i++)
			dev->must_blank[i] = ctrl->val < 100;
		break;
	case VIVID_CID_INSERT_SAV:
+1 −1
Original line number Diff line number Diff line
@@ -213,7 +213,7 @@ static int vid_cap_start_streaming(struct vb2_queue *vq, unsigned count)

	dev->vid_cap_seq_count = 0;
	dprintk(dev, 1, "%s\n", __func__);
	for (i = 0; i < VIDEO_MAX_FRAME; i++)
	for (i = 0; i < MAX_VID_CAP_BUFFERS; i++)
		dev->must_blank[i] = tpg_g_perc_fill(&dev->tpg) < 100;
	if (dev->start_streaming_error) {
		dev->start_streaming_error = false;