* [PATCH] 2.4: USB: fix DoS in pwc USB video driver
@ 2008-02-07 2:06 dann frazier
2008-02-07 4:57 ` Willy Tarreau
0 siblings, 1 reply; 2+ messages in thread
From: dann frazier @ 2008-02-07 2:06 UTC (permalink / raw)
To: Willy TARREAU; +Cc: Oliver Neukum, linux-kernel
This is a 2.4 backport of a linux-2.6 change by Oliver Neukum.
(commit 85237f202d46d55c1bffe0c5b1aa3ddc0f1dce4d)
CVE-2007-5093 was assigned for this issue.
This backport has been compile-tested only.
Commit log from 2.6 follows.
the pwc driver has a disconnect method that waits for user space to
close the device. This opens up an opportunity for a DoS attack,
blocking the USB subsystem and making khubd's task busy wait in
kernel space. This patch shifts freeing resources to close if an opened
device is disconnected.
Signed-off-by: dann frazier <dannf@hp.com>
---
drivers/usb/pwc-if.c | 50 +++++++++++++++++++++++++++++++++-----------------
drivers/usb/pwc.h | 1 +
2 files changed, 34 insertions(+), 17 deletions(-)
diff --git a/drivers/usb/pwc-if.c b/drivers/usb/pwc-if.c
index e458515..a1c3989 100644
--- a/drivers/usb/pwc-if.c
+++ b/drivers/usb/pwc-if.c
@@ -1055,11 +1055,16 @@ static int pwc_video_open(struct video_device *vdev, int mode)
return 0;
}
+static void pwc_cleanup(struct pwc_device *pdev)
+{
+ video_unregister_device(&pdev->vdev);
+}
+
/* Note that all cleanup is done in the reverse order as in _open */
static void pwc_video_close(struct video_device *vdev)
{
struct pwc_device *pdev;
- int i;
+ int i, hint;
Trace(TRACE_OPEN, ">> video_close called(vdev = 0x%p).\n", vdev);
@@ -1083,8 +1088,9 @@ static void pwc_video_close(struct video_device *vdev)
pwc_isoc_cleanup(pdev);
pwc_free_buffers(pdev);
+ lock_kernel();
/* Turn off LEDS and power down camera, but only when not unplugged */
- if (pdev->error_status != EPIPE) {
+ if (!pdev->unplugged) {
if (pwc_set_leds(pdev, 0, 0) < 0)
Info("Failed to set LED on/off time.\n");
if (power_save) {
@@ -1092,9 +1098,18 @@ static void pwc_video_close(struct video_device *vdev)
if (i < 0)
Err("Failed to power down camera (%d)\n", i);
}
+ pdev->vopen = 0;
+ Trace(TRACE_OPEN, "<< video_close()\n");
+ } else {
+ pwc_cleanup(pdev);
+ /* Free memory (don't set pdev to 0 just yet) */
+ kfree(pdev);
+ /* search device_hint[] table if we occupy a slot, by any chance */
+ for (hint = 0; hint < MAX_DEV_HINTS; hint++)
+ if (device_hint[hint].pdev == pdev)
+ device_hint[hint].pdev = NULL;
}
- pdev->vopen = 0;
- Trace(TRACE_OPEN, "<< video_close()\n");
+ unlock_kernel();
}
/*
@@ -1897,19 +1912,20 @@ static void usb_pwc_disconnect(struct usb_device *udev, void *ptr)
/* Alert waiting processes */
wake_up_interruptible(&pdev->frameq);
/* Wait until device is closed */
- while (pdev->vopen)
- schedule();
- /* Device is now closed, so we can safely unregister it */
- Trace(TRACE_PROBE, "Unregistering video device in disconnect().\n");
- video_unregister_device(&pdev->vdev);
-
- /* Free memory (don't set pdev to 0 just yet) */
- kfree(pdev);
-
- /* search device_hint[] table if we occupy a slot, by any chance */
- for (hint = 0; hint < MAX_DEV_HINTS; hint++)
- if (device_hint[hint].pdev == pdev)
- device_hint[hint].pdev = NULL;
+ if(pdev->vopen) {
+ pdev->unplugged = 1;
+ } else {
+ /* Device is closed, so we can safely unregister it */
+ Trace(TRACE_PROBE, "Unregistering video device in disconnect().\n");
+ pwc_cleanup(pdev);
+ /* Free memory (don't set pdev to 0 just yet) */
+ kfree(pdev);
+
+ /* search device_hint[] table if we occupy a slot, by any chance */
+ for (hint = 0; hint < MAX_DEV_HINTS; hint++)
+ if (device_hint[hint].pdev == pdev)
+ device_hint[hint].pdev = NULL;
+ }
unlock_kernel();
}
diff --git a/drivers/usb/pwc.h b/drivers/usb/pwc.h
index b020769..999daf2 100644
--- a/drivers/usb/pwc.h
+++ b/drivers/usb/pwc.h
@@ -141,6 +141,7 @@ struct pwc_device
char vsnapshot; /* snapshot mode */
char vsync; /* used by isoc handler */
char vmirror; /* for ToUCaM series */
+ char unplugged;
/* The image acquisition requires 3 to 4 steps:
1. data is gathered in short packets from the USB controller
--
1.5.3.7
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] 2.4: USB: fix DoS in pwc USB video driver
2008-02-07 2:06 [PATCH] 2.4: USB: fix DoS in pwc USB video driver dann frazier
@ 2008-02-07 4:57 ` Willy Tarreau
0 siblings, 0 replies; 2+ messages in thread
From: Willy Tarreau @ 2008-02-07 4:57 UTC (permalink / raw)
To: dann frazier; +Cc: Oliver Neukum, linux-kernel
On Wed, Feb 06, 2008 at 07:06:18PM -0700, dann frazier wrote:
> This is a 2.4 backport of a linux-2.6 change by Oliver Neukum.
> (commit 85237f202d46d55c1bffe0c5b1aa3ddc0f1dce4d)
That's weird, because I remember about this one I checked while working
on 2.6.20-stable. For an unknown reason, I thought that it did not affect
2.4 version of the driver, and I was apparently wrong :-/
> CVE-2007-5093 was assigned for this issue.
> This backport has been compile-tested only.
I've applied it, and I have such a webcam lying somewhere, so I'll be able
to test.
Thanks Dann!
Willy
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2008-02-07 5:46 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-02-07 2:06 [PATCH] 2.4: USB: fix DoS in pwc USB video driver dann frazier
2008-02-07 4:57 ` Willy Tarreau
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®