From 8023ed09cb278004a28f49844602adf23bd3615e Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 10 Jul 2012 10:41:40 -0300 Subject: [PATCH] [media] videobuf2-core: Verify planes lengths for output buffers For output buffers application provide to the kernel the number of bytes they stored in each plane of the buffer. Verify that the value is smaller than or equal to the plane length. Signed-off-by: Laurent Pinchart Acked-by: Hans Verkuil Acked-by: Pawel Osciak Acked-by: Marek Szyprowski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/videobuf2-core.c | 39 ++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index c9b50c7665de..35a5b8ff6a09 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -333,6 +333,41 @@ static int __verify_planes_array(struct vb2_buffer *vb, const struct v4l2_buffer return 0; } +/** + * __verify_length() - Verify that the bytesused value for each plane fits in + * the plane length and that the data offset doesn't exceed the bytesused value. + */ +static int __verify_length(struct vb2_buffer *vb, const struct v4l2_buffer *b) +{ + unsigned int length; + unsigned int plane; + + if (!V4L2_TYPE_IS_OUTPUT(b->type)) + return 0; + + if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) { + for (plane = 0; plane < vb->num_planes; ++plane) { + length = (b->memory == V4L2_MEMORY_USERPTR) + ? b->m.planes[plane].length + : vb->v4l2_planes[plane].length; + + if (b->m.planes[plane].bytesused > length) + return -EINVAL; + if (b->m.planes[plane].data_offset >= + b->m.planes[plane].bytesused) + return -EINVAL; + } + } else { + length = (b->memory == V4L2_MEMORY_USERPTR) + ? b->length : vb->v4l2_planes[0].length; + + if (b->bytesused > length) + return -EINVAL; + } + + return 0; +} + /** * __buffer_in_use() - return true if the buffer is in use and * the queue cannot be freed (by the means of REQBUFS(0)) call @@ -1167,6 +1202,10 @@ static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b) struct vb2_queue *q = vb->vb2_queue; int ret; + ret = __verify_length(vb, b); + if (ret < 0) + return ret; + switch (q->memory) { case V4L2_MEMORY_MMAP: ret = __qbuf_mmap(vb, b); -- 2.39.5