Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b90c17ff authored by Arun Menon's avatar Arun Menon
Browse files

Revert "[media] vb2: fix bytesused == 0 handling"



This reverts 'commit 8a75ffb8
("[media] vb2: fix bytesused == 0 handling")'

This change is needed to support zero filled len on
Output plane. Without this change, v4l2 framework sets
bytesused to alloc len, in case of zero filled len from client,
causing the firmware to read corrupt data and crash.

Change-Id: I42735d39f3bb08d031b6130e385f20115fbcb8f7
Signed-off-by: default avatarArun Menon <avmenon@codeaurora.org>
parent 8d8e42e4
Loading
Loading
Loading
Loading
+40 −38
Original line number Diff line number Diff line
@@ -576,7 +576,6 @@ static int __verify_planes_array(struct vb2_buffer *vb, const struct v4l2_buffer
static int __verify_length(struct vb2_buffer *vb, const struct v4l2_buffer *b)
{
	unsigned int length;
	unsigned int bytesused;
	unsigned int plane;

	if (!V4L2_TYPE_IS_OUTPUT(b->type))
@@ -584,24 +583,21 @@ static int __verify_length(struct vb2_buffer *vb, const struct v4l2_buffer *b)

	if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) {
		for (plane = 0; plane < vb->num_planes; ++plane) {
			length = (b->memory == V4L2_MEMORY_USERPTR ||
				  b->memory == V4L2_MEMORY_DMABUF)
			length = (b->memory == V4L2_MEMORY_USERPTR)
			       ? b->m.planes[plane].length
			       : vb->v4l2_planes[plane].length;
			bytesused = b->m.planes[plane].bytesused
				  ? b->m.planes[plane].bytesused : length;

			if (b->m.planes[plane].bytesused > length)
				return -EINVAL;

			if (b->m.planes[plane].data_offset > 0 &&
			    b->m.planes[plane].data_offset >= bytesused)
			    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;
		bytesused = b->bytesused ? b->bytesused : length;

		if (b->bytesused > length)
			return -EINVAL;
@@ -1246,6 +1242,35 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b
	unsigned int plane;

	if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) {
		/* Fill in driver-provided information for OUTPUT types */
		if (V4L2_TYPE_IS_OUTPUT(b->type)) {
			bool bytesused_is_used;

			/* Check if bytesused == 0 for all planes */
			for (plane = 0; plane < vb->num_planes; ++plane)
				if (b->m.planes[plane].bytesused)
					break;
			bytesused_is_used = plane < vb->num_planes;

			/*
			 * Will have to go up to b->length when API starts
			 * accepting variable number of planes.
			 *
			 * If bytesused_is_used is false, then fall back to the
			 * full buffer size. In that case userspace clearly
			 * never bothered to set it and it's a safe assumption
			 * that they really meant to use the full plane sizes.
			 */
			for (plane = 0; plane < vb->num_planes; ++plane) {
				struct v4l2_plane *pdst = &v4l2_planes[plane];
				struct v4l2_plane *psrc = &b->m.planes[plane];

				pdst->bytesused = bytesused_is_used ?
					psrc->bytesused : psrc->length;
				pdst->data_offset = psrc->data_offset;
			}
		}

		if (b->memory == V4L2_MEMORY_USERPTR) {
			for (plane = 0; plane < vb->num_planes; ++plane) {
				v4l2_planes[plane].m.userptr =
@@ -1262,28 +1287,6 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b
					b->m.planes[plane].length;
			}
		}

		/* Fill in driver-provided information for OUTPUT types */
		if (V4L2_TYPE_IS_OUTPUT(b->type)) {
			/*
			 * Will have to go up to b->length when API starts
			 * accepting variable number of planes.
			 *
			 * If bytesused == 0 for the output buffer, then fall
			 * back to the full buffer size. In that case
			 * userspace clearly never bothered to set it and
			 * it's a safe assumption that they really meant to
			 * use the full plane sizes.
			 */
			for (plane = 0; plane < vb->num_planes; ++plane) {
				struct v4l2_plane *pdst = &v4l2_planes[plane];
				struct v4l2_plane *psrc = &b->m.planes[plane];

				pdst->bytesused = psrc->bytesused ?
					psrc->bytesused : pdst->length;
				pdst->data_offset = psrc->data_offset;
			}
		}
	} else {
		/*
		 * Single-planar buffers do not use planes array,
@@ -1291,9 +1294,15 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b
		 * In videobuf we use our internal V4l2_planes struct for
		 * single-planar buffers as well, for simplicity.
		 *
		 * If bytesused == 0 for the output buffer, then fall back
		 * to the full buffer size as that's a sensible default.
		 * If bytesused == 0, then fall back to the full buffer size
		 * as that's a sensible default.
		 */
		if (V4L2_TYPE_IS_OUTPUT(b->type))
			v4l2_planes[0].bytesused =
				b->bytesused ? b->bytesused : b->length;
		else
			v4l2_planes[0].bytesused = 0;

		if (b->memory == V4L2_MEMORY_USERPTR) {
			v4l2_planes[0].m.userptr = b->m.userptr;
			v4l2_planes[0].length = b->length;
@@ -1303,13 +1312,6 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b
			v4l2_planes[0].m.fd = b->m.fd;
			v4l2_planes[0].length = b->length;
		}

		if (V4L2_TYPE_IS_OUTPUT(b->type))
			v4l2_planes[0].bytesused = b->bytesused ?
				b->bytesused : v4l2_planes[0].length;
		else
			v4l2_planes[0].bytesused = 0;

	}

	/* Zero flags that the vb2 core handles */