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

Hans de Goede jwrdegoede at fedoraproject.org
Mon Jul 9 11:35:01 UTC 2012


commit a1e20feffef8be2f68877545dcdac469b05ced4d
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Mon Jul 9 13:35:29 2012 +0200

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

 ...ure-we-always-set-buf-length-when-convert.patch |  125 ++++++++++++++++++++
 ...uf-Don-t-requeue-buffers-which-we-are-ret.patch |   41 +++++++
 v4l-utils.spec                                     |    9 ++-
 3 files changed, 174 insertions(+), 1 deletions(-)
---
diff --git a/0013-libv4l2-Ensure-we-always-set-buf-length-when-convert.patch b/0013-libv4l2-Ensure-we-always-set-buf-length-when-convert.patch
new file mode 100644
index 0000000..f7f2b73
--- /dev/null
+++ b/0013-libv4l2-Ensure-we-always-set-buf-length-when-convert.patch
@@ -0,0 +1,125 @@
+From 6662f9f04e529ddeae3828fe18b49f7b239fdb10 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at 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 at 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
+
diff --git a/0014-libv4l2-dqbuf-Don-t-requeue-buffers-which-we-are-ret.patch b/0014-libv4l2-dqbuf-Don-t-requeue-buffers-which-we-are-ret.patch
new file mode 100644
index 0000000..42ea6f0
--- /dev/null
+++ b/0014-libv4l2-dqbuf-Don-t-requeue-buffers-which-we-are-ret.patch
@@ -0,0 +1,41 @@
+From 8fcfbbc58a0b6a0eeb31c02493e164f82236a8e6 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at 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 at 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
+
diff --git a/v4l-utils.spec b/v4l-utils.spec
index e3ffaae..701fe72 100644
--- a/v4l-utils.spec
+++ b/v4l-utils.spec
@@ -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 at 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 at redhat.com> - 0.8.8-1
 - New upstream release 0.8.8
 - Add patches from upstream git to improve Pixart JPEG decoding


More information about the scm-commits mailing list