Re: [PATCH] media: video-mux: fix compliance failures

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 22/05/18 18:29, Philipp Zabel wrote:
> Limit frame sizes to the [1, UINT_MAX-1] interval, media bus formats to
> the available list of formats, and initialize pad and try formats.
> 
> Reported-by: Rui Miguel Silva <rui.silva@xxxxxxxxxx>
> Signed-off-by: Philipp Zabel <p.zabel@xxxxxxxxxxxxxx>
> ---
>  drivers/media/platform/video-mux.c | 110 +++++++++++++++++++++++++++++
>  1 file changed, 110 insertions(+)
> 
> diff --git a/drivers/media/platform/video-mux.c b/drivers/media/platform/video-mux.c
> index 1fb887293337..ade1dae706aa 100644
> --- a/drivers/media/platform/video-mux.c
> +++ b/drivers/media/platform/video-mux.c
> @@ -180,6 +180,87 @@ static int video_mux_set_format(struct v4l2_subdev *sd,
>  	if (!source_mbusformat)
>  		return -EINVAL;
>  
> +	/* No size limitations except V4L2 compliance requirements */
> +	v4l_bound_align_image(&sdformat->format.width, 1, UINT_MAX - 1, 0,
> +			      &sdformat->format.height, 1, UINT_MAX - 1, 0, 0);

This is a bit dubious. I would pick more realistic min/max values like 16 and
65536. UINT_MAX - 1 will overflow whenever code increments/multiplies it for some
reason, which can cause all sorts of weird issues.

> +
> +	/* All formats except LVDS and vendor specific formats are acceptable */
> +	switch (sdformat->format.code) {
> +	case MEDIA_BUS_FMT_RGB444_1X12:
> +	case MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE:
> +	case MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE:
> +	case MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE:
> +	case MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE:
> +	case MEDIA_BUS_FMT_RGB565_1X16:
> +	case MEDIA_BUS_FMT_BGR565_2X8_BE:
> +	case MEDIA_BUS_FMT_BGR565_2X8_LE:
> +	case MEDIA_BUS_FMT_RGB565_2X8_BE:
> +	case MEDIA_BUS_FMT_RGB565_2X8_LE:
> +	case MEDIA_BUS_FMT_RGB666_1X18:
> +	case MEDIA_BUS_FMT_RBG888_1X24:
> +	case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
> +	case MEDIA_BUS_FMT_BGR888_1X24:
> +	case MEDIA_BUS_FMT_GBR888_1X24:
> +	case MEDIA_BUS_FMT_RGB888_1X24:
> +	case MEDIA_BUS_FMT_RGB888_2X12_BE:
> +	case MEDIA_BUS_FMT_RGB888_2X12_LE:
> +	case MEDIA_BUS_FMT_ARGB8888_1X32:
> +	case MEDIA_BUS_FMT_RGB888_1X32_PADHI:
> +	case MEDIA_BUS_FMT_RGB101010_1X30:
> +	case MEDIA_BUS_FMT_RGB121212_1X36:
> +	case MEDIA_BUS_FMT_RGB161616_1X48:
> +	case MEDIA_BUS_FMT_Y8_1X8:
> +	case MEDIA_BUS_FMT_UV8_1X8:
> +	case MEDIA_BUS_FMT_UYVY8_1_5X8:
> +	case MEDIA_BUS_FMT_VYUY8_1_5X8:
> +	case MEDIA_BUS_FMT_YUYV8_1_5X8:
> +	case MEDIA_BUS_FMT_YVYU8_1_5X8:
> +	case MEDIA_BUS_FMT_UYVY8_2X8:
> +	case MEDIA_BUS_FMT_VYUY8_2X8:
> +	case MEDIA_BUS_FMT_YUYV8_2X8:
> +	case MEDIA_BUS_FMT_YVYU8_2X8:
> +	case MEDIA_BUS_FMT_Y10_1X10:
> +	case MEDIA_BUS_FMT_UYVY10_2X10:
> +	case MEDIA_BUS_FMT_VYUY10_2X10:
> +	case MEDIA_BUS_FMT_YUYV10_2X10:
> +	case MEDIA_BUS_FMT_YVYU10_2X10:
> +	case MEDIA_BUS_FMT_Y12_1X12:
> +	case MEDIA_BUS_FMT_UYVY12_2X12:
> +	case MEDIA_BUS_FMT_VYUY12_2X12:
> +	case MEDIA_BUS_FMT_YUYV12_2X12:
> +	case MEDIA_BUS_FMT_YVYU12_2X12:
> +	case MEDIA_BUS_FMT_UYVY8_1X16:
> +	case MEDIA_BUS_FMT_VYUY8_1X16:
> +	case MEDIA_BUS_FMT_YUYV8_1X16:
> +	case MEDIA_BUS_FMT_YVYU8_1X16:
> +	case MEDIA_BUS_FMT_YDYUYDYV8_1X16:
> +	case MEDIA_BUS_FMT_UYVY10_1X20:
> +	case MEDIA_BUS_FMT_VYUY10_1X20:
> +	case MEDIA_BUS_FMT_YUYV10_1X20:
> +	case MEDIA_BUS_FMT_YVYU10_1X20:
> +	case MEDIA_BUS_FMT_VUY8_1X24:
> +	case MEDIA_BUS_FMT_YUV8_1X24:
> +	case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
> +	case MEDIA_BUS_FMT_UYVY12_1X24:
> +	case MEDIA_BUS_FMT_VYUY12_1X24:
> +	case MEDIA_BUS_FMT_YUYV12_1X24:
> +	case MEDIA_BUS_FMT_YVYU12_1X24:
> +	case MEDIA_BUS_FMT_YUV10_1X30:
> +	case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
> +	case MEDIA_BUS_FMT_AYUV8_1X32:
> +	case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
> +	case MEDIA_BUS_FMT_YUV12_1X36:
> +	case MEDIA_BUS_FMT_YUV16_1X48:
> +	case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
> +	case MEDIA_BUS_FMT_JPEG_1X8:
> +	case MEDIA_BUS_FMT_AHSV8888_1X32:
> +		break;
> +	default:
> +		sdformat->format.code = MEDIA_BUS_FMT_Y8_1X8;

Add a break here.

> +	}
> +	if (sdformat->format.field == V4L2_FIELD_ANY)
> +		sdformat->format.field = V4L2_FIELD_NONE;
> +
>  	mutex_lock(&vmux->lock);
>  
>  	/* Source pad mirrors active sink pad, no limitations on sink pads */
> @@ -197,11 +278,33 @@ static int video_mux_set_format(struct v4l2_subdev *sd,
>  	return 0;
>  }
>  
> +static int video_mux_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
> +{
> +	struct video_mux *vmux = v4l2_subdev_to_video_mux(sd);
> +	struct v4l2_mbus_framefmt *mbusformat;
> +	int i;
> +
> +	mutex_lock(&vmux->lock);
> +
> +	for (i = 0; i < sd->entity.num_pads; i++) {
> +		mbusformat = v4l2_subdev_get_try_format(sd, fh->pad, i);
> +		*mbusformat = vmux->format_mbus[i];
> +	}
> +
> +	mutex_unlock(&vmux->lock);
> +
> +	return 0;
> +}

This isn't the right approach. Instead implement the init_cfg pad op.

> +
>  static const struct v4l2_subdev_pad_ops video_mux_pad_ops = {
>  	.get_fmt = video_mux_get_format,
>  	.set_fmt = video_mux_set_format,
>  };
>  
> +static const struct v4l2_subdev_internal_ops video_mux_internal_ops = {
> +	.open = video_mux_open,
> +};

So this can be dropped.

> +
>  static const struct v4l2_subdev_ops video_mux_subdev_ops = {
>  	.pad = &video_mux_pad_ops,
>  	.video = &video_mux_subdev_video_ops,
> @@ -226,6 +329,7 @@ static int video_mux_probe(struct platform_device *pdev)
>  	v4l2_subdev_init(&vmux->subdev, &video_mux_subdev_ops);
>  	snprintf(vmux->subdev.name, sizeof(vmux->subdev.name), "%s", np->name);
>  	vmux->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
> +	vmux->subdev.internal_ops = &video_mux_internal_ops;
>  	vmux->subdev.dev = dev;
>  
>  	/*
> @@ -263,6 +367,12 @@ static int video_mux_probe(struct platform_device *pdev)
>  	for (i = 0; i < num_pads - 1; i++)
>  		vmux->pads[i].flags = MEDIA_PAD_FL_SINK;
>  	vmux->pads[num_pads - 1].flags = MEDIA_PAD_FL_SOURCE;
> +	for (i = 0; i < num_pads; i++) {
> +		vmux->format_mbus[i].width = 1;
> +		vmux->format_mbus[i].height = 1;
> +		vmux->format_mbus[i].code = MEDIA_BUS_FMT_Y8_1X8;
> +		vmux->format_mbus[i].field = V4L2_FIELD_NONE;
> +	}
>  
>  	vmux->subdev.entity.function = MEDIA_ENT_F_VID_MUX;
>  	ret = media_entity_pads_init(&vmux->subdev.entity, num_pads,
> 

Regards,

	Hans



[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux