[kernel/f17] Fix crash in uvc_video_clock_update from Laurent Pinchart (rhbz 806433)
Josh Boyer
jwboyer at fedoraproject.org
Tue Apr 3 17:58:16 UTC 2012
commit 035ffabe064c59845c3edb92a1b776701d0dd556
Author: Josh Boyer <jwboyer at redhat.com>
Date: Tue Apr 3 12:55:28 2012 -0400
Fix crash in uvc_video_clock_update from Laurent Pinchart (rhbz 806433)
kernel.spec | 11 ++-
...e-induced-crash-in-uvc_video_clock_update.patch | 113 ++++++++++++++++++++
2 files changed, 123 insertions(+), 1 deletions(-)
---
diff --git a/kernel.spec b/kernel.spec
index f51b2d1..76d4dd5 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -54,7 +54,7 @@ Summary: The Linux kernel
# For non-released -rc kernels, this will be appended after the rcX and
# gitX tags, so a 3 here would become part of release "0.rcX.gitX.3"
#
-%global baserelease 1
+%global baserelease 2
%global fedora_build %{baserelease}
# base_sublevel is the kernel version we're starting with and patching
@@ -767,6 +767,9 @@ Patch21351: x86-add-io_apic_ops-to-allow-interception.patch
Patch21352: x86-apic_ops-Replace-apic_ops-with-x86_apic_ops.patch
Patch21353: xen-x86-Implement-x86_apic_ops.patch
+#rhbz 806433
+Patch21360: uvcvideo-Fix-race-induced-crash-in-uvc_video_clock_update.patch
+
#rhbz 770476
Patch21370: iwlegacy-do-not-nulify-il-vif-on-reset.patch
Patch21371: iwlwifi-do-not-nulify-ctx-vif-on-reset.patch
@@ -1508,6 +1511,9 @@ ApplyPatch nfs-Fix-length-of-buffer-copied-in-__nfs4_get_acl_uncached.patch
#rhbz 808207 CVE-2012-1601
ApplyPatch KVM-Ensure-all-vcpus-are-consistent-with-in-kernel-i.patch
+#rhbz 806433
+ApplyPatch uvcvideo-Fix-race-induced-crash-in-uvc_video_clock_update.patch
+
# END OF PATCH APPLICATIONS
%endif
@@ -2347,6 +2353,9 @@ fi
# '-' | |
# '-'
%changelog
+* Tue Apr 03 2012 Josh Boyer <jwboyer at redhat.com>
+- Fix crash in uvc_video_clock_update from Laurent Pinchart (rhbz 806433)
+
* Mon Apr 02 2012 Dave Jones <davej at redhat.com> 3.3.1-1
- Linux 3.3.1
diff --git a/uvcvideo-Fix-race-induced-crash-in-uvc_video_clock_update.patch b/uvcvideo-Fix-race-induced-crash-in-uvc_video_clock_update.patch
new file mode 100644
index 0000000..5f2a1c0
--- /dev/null
+++ b/uvcvideo-Fix-race-induced-crash-in-uvc_video_clock_update.patch
@@ -0,0 +1,113 @@
+@@ -, +, @@
+ drivers/media/video/uvc/uvc_video.c | 50 ++++++++++++++++++++++------------
+ 1 files changed, 32 insertions(+), 18 deletions(-)
+--- a/drivers/media/video/uvc/uvc_video.c
++++ a/drivers/media/video/uvc/uvc_video.c
+@@ -468,22 +468,30 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf,
+ spin_unlock_irqrestore(&stream->clock.lock, flags);
+ }
+
+-static int uvc_video_clock_init(struct uvc_streaming *stream)
++static void uvc_video_clock_reset(struct uvc_streaming *stream)
+ {
+ struct uvc_clock *clock = &stream->clock;
+
+- spin_lock_init(&clock->lock);
+ clock->head = 0;
+ clock->count = 0;
+- clock->size = 32;
+ clock->last_sof = -1;
+ clock->sof_offset = -1;
++}
++
++static int uvc_video_clock_init(struct uvc_streaming *stream)
++{
++ struct uvc_clock *clock = &stream->clock;
++
++ spin_lock_init(&clock->lock);
++ clock->size = 32;
+
+ clock->samples = kmalloc(clock->size * sizeof(*clock->samples),
+ GFP_KERNEL);
+ if (clock->samples == NULL)
+ return -ENOMEM;
+
++ uvc_video_clock_reset(stream);
++
+ return 0;
+ }
+
+@@ -1424,8 +1432,6 @@ static void uvc_uninit_video(struct uvc_streaming *stream, int free_buffers)
+
+ if (free_buffers)
+ uvc_free_urb_buffers(stream);
+-
+- uvc_video_clock_cleanup(stream);
+ }
+
+ /*
+@@ -1555,10 +1561,6 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags)
+
+ uvc_video_stats_start(stream);
+
+- ret = uvc_video_clock_init(stream);
+- if (ret < 0)
+- return ret;
+-
+ if (intf->num_altsetting > 1) {
+ struct usb_host_endpoint *best_ep = NULL;
+ unsigned int best_psize = 3 * 1024;
+@@ -1683,6 +1685,8 @@ int uvc_video_resume(struct uvc_streaming *stream, int reset)
+
+ stream->frozen = 0;
+
++ uvc_video_clock_reset(stream);
++
+ ret = uvc_commit_video(stream, &stream->ctrl);
+ if (ret < 0) {
+ uvc_queue_enable(&stream->queue, 0);
+@@ -1819,25 +1823,35 @@ int uvc_video_enable(struct uvc_streaming *stream, int enable)
+ uvc_uninit_video(stream, 1);
+ usb_set_interface(stream->dev->udev, stream->intfnum, 0);
+ uvc_queue_enable(&stream->queue, 0);
++ uvc_video_clock_cleanup(stream);
+ return 0;
+ }
+
+- ret = uvc_queue_enable(&stream->queue, 1);
++ ret = uvc_video_clock_init(stream);
+ if (ret < 0)
+ return ret;
+
++ ret = uvc_queue_enable(&stream->queue, 1);
++ if (ret < 0)
++ goto error_queue;
++
+ /* Commit the streaming parameters. */
+ ret = uvc_commit_video(stream, &stream->ctrl);
+- if (ret < 0) {
+- uvc_queue_enable(&stream->queue, 0);
+- return ret;
+- }
++ if (ret < 0)
++ goto error_commit;
+
+ ret = uvc_init_video(stream, GFP_KERNEL);
+- if (ret < 0) {
+- usb_set_interface(stream->dev->udev, stream->intfnum, 0);
+- uvc_queue_enable(&stream->queue, 0);
+- }
++ if (ret < 0)
++ goto error_video;
++
++ return 0;
++
++error_video:
++ usb_set_interface(stream->dev->udev, stream->intfnum, 0);
++error_commit:
++ uvc_queue_enable(&stream->queue, 0);
++error_queue:
++ uvc_video_clock_cleanup(stream);
+
+ return ret;
+ }
More information about the scm-commits
mailing list