media: ipu3-cio2: Validate mbus format in setting subdev format

commit a86cf9b29e upstream.

Validate media bus code, width and height when setting the subdev format.

This effectively reworks how setting subdev format is implemented in the
driver.

Fixes: c2a6a07afe ("media: intel-ipu3: cio2: add new MIPI-CSI2 driver")
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: stable@vger.kernel.org # v4.16 and up
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Sakari Ailus 2020-10-08 21:33:26 +02:00 committed by Greg Kroah-Hartman
parent ffa790f9e1
commit dd9d14e067

View file

@ -1258,6 +1258,9 @@ static int cio2_subdev_set_fmt(struct v4l2_subdev *sd,
struct v4l2_subdev_format *fmt)
{
struct cio2_queue *q = container_of(sd, struct cio2_queue, subdev);
struct v4l2_mbus_framefmt *mbus;
u32 mbus_code = fmt->format.code;
unsigned int i;
/*
* Only allow setting sink pad format;
@ -1266,18 +1269,26 @@ static int cio2_subdev_set_fmt(struct v4l2_subdev *sd,
if (fmt->pad == CIO2_PAD_SOURCE)
return cio2_subdev_get_fmt(sd, cfg, fmt);
mutex_lock(&q->subdev_lock);
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
mbus = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
else
mbus = &q->subdev_fmt;
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
*v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
} else {
/* It's the sink, allow changing frame size */
q->subdev_fmt.width = fmt->format.width;
q->subdev_fmt.height = fmt->format.height;
q->subdev_fmt.code = fmt->format.code;
fmt->format = q->subdev_fmt;
fmt->format.code = formats[0].mbus_code;
for (i = 0; i < ARRAY_SIZE(formats); i++) {
if (formats[i].mbus_code == fmt->format.code) {
fmt->format.code = mbus_code;
break;
}
}
fmt->format.width = min_t(u32, fmt->format.width, CIO2_IMAGE_MAX_WIDTH);
fmt->format.height = min_t(u32, fmt->format.height,
CIO2_IMAGE_MAX_LENGTH);
mutex_lock(&q->subdev_lock);
*mbus = fmt->format;
mutex_unlock(&q->subdev_lock);
return 0;