@@ -1444,9 +1444,57 @@ static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
struct v4l2_create_buffers *create = arg;
- int ret = check_fmt(file, create->format.type);
+ const struct v4l2_format *fmt = &create->format;
+ const struct v4l2_pix_format *pix = &fmt->fmt.pix;
+ const struct v4l2_pix_format_mplane *mp = &fmt->fmt.pix_mp;
+ const struct v4l2_plane_pix_format *p;
+ int ret = check_fmt(file, fmt->type);
+ unsigned i;
+
+ if (ret)
+ return ret;
- return ret ? ret : ops->vidioc_create_bufs(file, fh, create);
+ /* Sanity checks */
+ switch (fmt->type) {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ if (pix->sizeimage == 0 || pix->width == 0 || pix->height == 0)
+ return -EINVAL;
+ /* Note: bytesperline is 0 for compressed formats */
+ if (pix->bytesperline &&
+ pix->height * pix->bytesperline > pix->sizeimage)
+ return -EINVAL;
+ break;
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+ if (mp->num_planes == 0 || mp->width == 0 || mp->height == 0)
+ return -EINVAL;
+ for (i = 0; i < mp->num_planes; i++) {
+ p = &mp->plane_fmt[i];
+
+ if (p->sizeimage == 0)
+ return -EINVAL;
+ /* Note: bytesperline is 0 for compressed formats */
+ if (p->bytesperline &&
+ p->bytesperline * mp->height > p->sizeimage)
+ return -EINVAL;
+ }
+ break;
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ if (fmt->fmt.vbi.count[0] + fmt->fmt.vbi.count[1] == 0)
+ return -EINVAL;
+ break;
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ if (fmt->fmt.sliced.io_size == 0)
+ return -EINVAL;
+ break;
+ default:
+ /* Overlay formats are invalid */
+ return -EINVAL;
+ }
+ return ops->vidioc_create_bufs(file, fh, create);
}
static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops,