Cherry-pick 2 patches from upstream git fixing an exotic crash (rhbz#838279)

This commit is contained in:
Hans de Goede 2012-07-09 13:35:29 +02:00
parent 352a2ee69f
commit a1e20feffe
3 changed files with 174 additions and 1 deletions

View File

@ -0,0 +1,125 @@
From 6662f9f04e529ddeae3828fe18b49f7b239fdb10 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Mon, 9 Jul 2012 10:13:11 +0200
Subject: [PATCH 13/14] libv4l2: Ensure we always set buf->length when
converting
Some apps blindly use buf->length when calling munmap, even if a previous
call (ie dqbuf) on the buffer failed. We used to not set buf->length to
our conversion buffer length when the actual ioctl call to the device, or
the format conversion failed.
When a dqbuf succeeded and the conversion failed this which would cause
us to leave buf->length set to the real buffer length rather then the
conversion buffer length, if the app then wrongly uses buf->length (*)
for a munmap we would not recognize this as munmap of the conversion
buffer and pass it through to the real munmap unmapping a part of
our conversion buf without being aware of this!
*) After from the point of the app a failed dqbuf, so it should not trust the
contents of buf at all.
This patch makes things work even for buggy apps, by always setting
buf->length when converting even if things fail.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Conflicts:
lib/libv4l2/libv4l2.c
---
lib/libv4l2/libv4l2.c | 52 +++++++++++++++++++++++++++++--------------------
1 file changed, 31 insertions(+), 21 deletions(-)
diff --git a/lib/libv4l2/libv4l2.c b/lib/libv4l2/libv4l2.c
index 089fc38..a8f17ed 100644
--- a/lib/libv4l2/libv4l2.c
+++ b/lib/libv4l2/libv4l2.c
@@ -486,6 +486,23 @@ static int v4l2_needs_conversion(int index)
return 0;
}
+static void v4l2_set_conversion_buf_params(int index, struct v4l2_buffer *buf)
+{
+ if (!v4l2_needs_conversion(index))
+ return;
+
+ /* This may happen if the ioctl failed */
+ if (buf->index >= devices[index].no_frames)
+ buf->index = 0;
+
+ buf->m.offset = V4L2_MMAP_OFFSET_MAGIC | buf->index;
+ buf->length = V4L2_FRAME_BUF_SIZE;
+ if (devices[index].frame_map_count[buf->index])
+ buf->flags |= V4L2_BUF_FLAG_MAPPED;
+ else
+ buf->flags &= ~V4L2_BUF_FLAG_MAPPED;
+}
+
static int v4l2_buffers_mapped(int index)
{
unsigned int i;
@@ -1182,19 +1199,14 @@ int v4l2_ioctl(int fd, unsigned long int request, ...)
/* Do a real query even when converting to let the driver fill in
things like buf->field */
result = SYS_IOCTL(devices[index].fd, VIDIOC_QUERYBUF, buf);
- if (result || !v4l2_needs_conversion(index))
- break;
- buf->m.offset = V4L2_MMAP_OFFSET_MAGIC | buf->index;
- buf->length = V4L2_FRAME_BUF_SIZE;
- if (devices[index].frame_map_count[buf->index])
- buf->flags |= V4L2_BUF_FLAG_MAPPED;
- else
- buf->flags &= ~V4L2_BUF_FLAG_MAPPED;
+ v4l2_set_conversion_buf_params(index, buf);
break;
}
- case VIDIOC_QBUF:
+ case VIDIOC_QBUF: {
+ struct v4l2_buffer *buf = arg;
+
if (devices[index].flags & V4L2_STREAM_CONTROLLED_BY_READ) {
result = v4l2_deactivate_read_stream(index);
if (result)
@@ -1209,7 +1221,10 @@ int v4l2_ioctl(int fd, unsigned long int request, ...)
}
result = SYS_IOCTL(devices[index].fd, VIDIOC_QBUF, arg);
+
+ v4l2_set_conversion_buf_params(index, buf);
break;
+ }
case VIDIOC_DQBUF: {
struct v4l2_buffer *buf = arg;
@@ -1248,19 +1263,14 @@ int v4l2_ioctl(int fd, unsigned long int request, ...)
}
}
- result = v4l2_dequeue_and_convert(index, buf, 0, V4L2_FRAME_BUF_SIZE);
- if (result < 0)
- break;
-
- buf->bytesused = result;
- buf->m.offset = V4L2_MMAP_OFFSET_MAGIC | buf->index;
- buf->length = V4L2_FRAME_BUF_SIZE;
- if (devices[index].frame_map_count[buf->index])
- buf->flags |= V4L2_BUF_FLAG_MAPPED;
- else
- buf->flags &= ~V4L2_BUF_FLAG_MAPPED;
+ result = v4l2_dequeue_and_convert(index, buf, 0,
+ V4L2_FRAME_BUF_SIZE);
+ if (result >= 0) {
+ buf->bytesused = result;
+ result = 0;
+ }
- result = 0;
+ v4l2_set_conversion_buf_params(index, buf);
break;
}
--
1.7.10.4

View File

@ -0,0 +1,41 @@
From 8fcfbbc58a0b6a0eeb31c02493e164f82236a8e6 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Mon, 9 Jul 2012 13:23:41 +0200
Subject: [PATCH 14/14] libv4l2: dqbuf: Don't requeue buffers which we are
returning to the app
We retry dqbuf when we get a short frame or a decode error, but if the retries
are exhausted and the frame is short we will return the (short) buffer to the
caller, since returning a short frame is better then not returning anything
at all.
This means that we must not re-queue it then! Also see:
https://bugzilla.redhat.com/show_bug.cgi?id=838279
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
lib/libv4l2/libv4l2.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/lib/libv4l2/libv4l2.c b/lib/libv4l2/libv4l2.c
index a8f17ed..070ac0d 100644
--- a/lib/libv4l2/libv4l2.c
+++ b/lib/libv4l2/libv4l2.c
@@ -317,7 +317,13 @@ static int v4l2_dequeue_and_convert(int index, struct v4l2_buffer *buf,
V4L2_LOG_ERR("converting / decoding frame data: %s",
v4lconvert_get_error_message(devices[index].convert));
- v4l2_queue_read_buffer(index, buf->index);
+ /*
+ * If this is the last try, and the frame is short
+ * we will return the (short) buffer to the caller,
+ * so we must not re-queue it then!
+ */
+ if (!(tries == 1 && errno == EPIPE))
+ v4l2_queue_read_buffer(index, buf->index);
errno = saved_err;
}
tries--;
--
1.7.10.4

View File

@ -1,6 +1,6 @@
Name: v4l-utils
Version: 0.8.8
Release: 1%{?dist}
Release: 2%{?dist}
Summary: Utilities for video4linux and DVB devices
Group: Applications/System
# ir-keytable and v4l2-sysfs-path are GPLv2 only
@ -20,6 +20,8 @@ Patch9: 0009-libv4lcontrol-Add-Lenovo-Thinkpad-X220-Tablet-to-ups.patch
Patch10: 0010-libv4l2-Improve-VIDIOC_-_FMT-logging.patch
Patch11: 0011-libv4lconvert-replace-strndupa-with-more-portable-st.patch
Patch12: 0012-libdvbv5-Add-missing-includes.patch
Patch13: 0013-libv4l2-Ensure-we-always-set-buf-length-when-convert.patch
Patch14: 0014-libv4l2-dqbuf-Don-t-requeue-buffers-which-we-are-ret.patch
BuildRequires: libjpeg-devel qt4-devel kernel-headers desktop-file-utils
# For /lib/udev/rules.d ownership
Requires: udev
@ -102,6 +104,8 @@ developing applications that use libv4l.
%patch10 -p1
%patch11 -p1
%patch12 -p1
%patch13 -p1
%patch14 -p1
%build
@ -175,6 +179,9 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
%changelog
* Mon Jul 9 2012 Hans de Goede <hdegoede@redhat.com> - 0.8.8-2
- Cherry-pick 2 patches from upstream git fixing an exotic crash (rhbz#838279)
* Tue May 22 2012 Hans de Goede <hdegoede@redhat.com> - 0.8.8-1
- New upstream release 0.8.8
- Add patches from upstream git to improve Pixart JPEG decoding