Fix crash in uvc_video_clock_update from Laurent Pinchart (rhbz 806433)
This commit is contained in:
parent
5be33f56fa
commit
035ffabe06
11
kernel.spec
11
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@redhat.com>
|
||||
- Fix crash in uvc_video_clock_update from Laurent Pinchart (rhbz 806433)
|
||||
|
||||
* Mon Apr 02 2012 Dave Jones <davej@redhat.com> 3.3.1-1
|
||||
- Linux 3.3.1
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue