From: Hans Verkuil Date: Fri, 14 Feb 2014 11:48:39 +0000 (+0100) Subject: v4l2-compliance: test streaming with bogus v4l2_buffer values. X-Git-Tag: v4l-utils-1.2.0~218 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d536f6b43a56f3a391af2278993e4eb2e288f968;p=platform%2Fupstream%2Fv4l-utils.git v4l2-compliance: test streaming with bogus v4l2_buffer values. Check that invalid inputs do not crash anything. Signed-off-by: Hans Verkuil --- diff --git a/utils/v4l2-compliance/v4l2-test-buffers.cpp b/utils/v4l2-compliance/v4l2-test-buffers.cpp index ea38845..06388e5 100644 --- a/utils/v4l2-compliance/v4l2-test-buffers.cpp +++ b/utils/v4l2-compliance/v4l2-test-buffers.cpp @@ -136,7 +136,6 @@ static int checkQueryBuf(struct node *node, const struct v4l2_buffer &buf, } if (mode == Dequeued || mode == Prepared) { - fail_on_test(!(buf.flags & (V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_ERROR))); if (V4L2_TYPE_IS_MULTIPLANAR(type)) { fail_on_test(buf.length <= VIDEO_MAX_PLANES); for (unsigned p = 0; p < buf.length; p++) { @@ -158,6 +157,7 @@ static int checkQueryBuf(struct node *node, const struct v4l2_buffer &buf, fail_on_test(!buf.timestamp.tv_sec && !buf.timestamp.tv_usec); fail_on_test(buf.field == V4L2_FIELD_ALTERNATE); fail_on_test(buf.field == V4L2_FIELD_ANY); + fail_on_test(!(buf.flags & (V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_ERROR))); if (cur_fmt.fmt.pix.field == V4L2_FIELD_ALTERNATE) { fail_on_test(buf.field != V4L2_FIELD_BOTTOM && buf.field != V4L2_FIELD_TOP); @@ -409,6 +409,13 @@ static int setupMmap(struct node *node, struct v4l2_requestbuffers &bufs) } fail_on_test(doioctl(node, VIDIOC_QUERYBUF, &buf)); fail_on_test(checkQueryBuf(node, buf, bufs.type, bufs.memory, i, Unqueued, 0)); + + // Try a random offset + ptrs[i] = test_mmap(NULL, buf.length, + PROT_READ | PROT_WRITE, MAP_SHARED, node->fd, buf.m.offset + 0xdeadbeef); + fail_on_test(ptrs[i] != MAP_FAILED); + + // Now with the proper offset ptrs[i] = test_mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, node->fd, buf.m.offset); @@ -599,13 +606,37 @@ static int setupUserPtr(struct node *node, struct v4l2_requestbuffers &bufs) fail_on_test(checkQueryBuf(node, buf, bufs.type, bufs.memory, i, Unqueued, 0)); ptrs[i] = malloc(buf.length); fail_on_test(ptrs[i] == NULL); - buf.m.userptr = (unsigned long)ptrs[i]; - ret = doioctl(node, VIDIOC_PREPARE_BUF, &buf); - fail_on_test(ret && ret != ENOTTY); - if (ret == 0) { - fail_on_test(doioctl(node, VIDIOC_QUERYBUF, &buf)); - fail_on_test(checkQueryBuf(node, buf, bufs.type, bufs.memory, i, Prepared, 0)); + ret = ENOTTY; + // Try to use VIDIOC_PREPARE_BUF for every other buffer + if ((i & 1) == 0) { + buf.m.userptr = 0; + ret = doioctl(node, VIDIOC_PREPARE_BUF, &buf); + fail_on_test(!ret); + + buf.m.userptr = (unsigned long)ptrs[i] + buf.length / 2; + ret = doioctl(node, VIDIOC_PREPARE_BUF, &buf); + fail_on_test(!ret); + + buf.m.userptr = (unsigned long)ptrs[i]; + ret = doioctl(node, VIDIOC_PREPARE_BUF, &buf); + fail_on_test(ret && ret != ENOTTY); + + if (ret == 0) { + fail_on_test(doioctl(node, VIDIOC_QUERYBUF, &buf)); + fail_on_test(checkQueryBuf(node, buf, bufs.type, bufs.memory, i, Prepared, 0)); + } + } + if (ret == ENOTTY) { + buf.m.userptr = 0; + ret = doioctl(node, VIDIOC_QBUF, &buf); + fail_on_test(!ret); + + buf.m.userptr = (unsigned long)ptrs[i] + buf.length / 2; + ret = doioctl(node, VIDIOC_QBUF, &buf); + fail_on_test(!ret); + + buf.m.userptr = (unsigned long)ptrs[i]; } fail_on_test(doioctl(node, VIDIOC_QBUF, &buf));