• R/O
  • HTTP
  • SSH
  • HTTPS

linux-2.4.36: Commit

2.4.36-stable kernel tree


Commit MetaInfo

Revision1994e10c56cfb36df0e03090e5c917c973d3df69 (tree)
Time2008-02-07 13:54:21
Authordann frazier <dannf@hp.c...>
CommiterWilly Tarreau

Log Message

2.4: USB: fix DoS in pwc USB video driver

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>

Change Summary

Incremental Difference

--- 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)
10551055 return 0;
10561056 }
10571057
1058+static void pwc_cleanup(struct pwc_device *pdev)
1059+{
1060+ video_unregister_device(&pdev->vdev);
1061+}
1062+
10581063 /* Note that all cleanup is done in the reverse order as in _open */
10591064 static void pwc_video_close(struct video_device *vdev)
10601065 {
10611066 struct pwc_device *pdev;
1062- int i;
1067+ int i, hint;
10631068
10641069 Trace(TRACE_OPEN, ">> video_close called(vdev = 0x%p).\n", vdev);
10651070
@@ -1083,8 +1088,9 @@ static void pwc_video_close(struct video_device *vdev)
10831088 pwc_isoc_cleanup(pdev);
10841089 pwc_free_buffers(pdev);
10851090
1091+ lock_kernel();
10861092 /* Turn off LEDS and power down camera, but only when not unplugged */
1087- if (pdev->error_status != EPIPE) {
1093+ if (!pdev->unplugged) {
10881094 if (pwc_set_leds(pdev, 0, 0) < 0)
10891095 Info("Failed to set LED on/off time.\n");
10901096 if (power_save) {
@@ -1092,9 +1098,18 @@ static void pwc_video_close(struct video_device *vdev)
10921098 if (i < 0)
10931099 Err("Failed to power down camera (%d)\n", i);
10941100 }
1101+ pdev->vopen = 0;
1102+ Trace(TRACE_OPEN, "<< video_close()\n");
1103+ } else {
1104+ pwc_cleanup(pdev);
1105+ /* Free memory (don't set pdev to 0 just yet) */
1106+ kfree(pdev);
1107+ /* search device_hint[] table if we occupy a slot, by any chance */
1108+ for (hint = 0; hint < MAX_DEV_HINTS; hint++)
1109+ if (device_hint[hint].pdev == pdev)
1110+ device_hint[hint].pdev = NULL;
10951111 }
1096- pdev->vopen = 0;
1097- Trace(TRACE_OPEN, "<< video_close()\n");
1112+ unlock_kernel();
10981113 }
10991114
11001115 /*
@@ -1897,19 +1912,20 @@ static void usb_pwc_disconnect(struct usb_device *udev, void *ptr)
18971912 /* Alert waiting processes */
18981913 wake_up_interruptible(&pdev->frameq);
18991914 /* Wait until device is closed */
1900- while (pdev->vopen)
1901- schedule();
1902- /* Device is now closed, so we can safely unregister it */
1903- Trace(TRACE_PROBE, "Unregistering video device in disconnect().\n");
1904- video_unregister_device(&pdev->vdev);
1905-
1906- /* Free memory (don't set pdev to 0 just yet) */
1907- kfree(pdev);
1908-
1909- /* search device_hint[] table if we occupy a slot, by any chance */
1910- for (hint = 0; hint < MAX_DEV_HINTS; hint++)
1911- if (device_hint[hint].pdev == pdev)
1912- device_hint[hint].pdev = NULL;
1915+ if(pdev->vopen) {
1916+ pdev->unplugged = 1;
1917+ } else {
1918+ /* Device is closed, so we can safely unregister it */
1919+ Trace(TRACE_PROBE, "Unregistering video device in disconnect().\n");
1920+ pwc_cleanup(pdev);
1921+ /* Free memory (don't set pdev to 0 just yet) */
1922+ kfree(pdev);
1923+
1924+ /* search device_hint[] table if we occupy a slot, by any chance */
1925+ for (hint = 0; hint < MAX_DEV_HINTS; hint++)
1926+ if (device_hint[hint].pdev == pdev)
1927+ device_hint[hint].pdev = NULL;
1928+ }
19131929
19141930 unlock_kernel();
19151931 }
--- a/drivers/usb/pwc.h
+++ b/drivers/usb/pwc.h
@@ -141,6 +141,7 @@ struct pwc_device
141141 char vsnapshot; /* snapshot mode */
142142 char vsync; /* used by isoc handler */
143143 char vmirror; /* for ToUCaM series */
144+ char unplugged;
144145
145146 /* The image acquisition requires 3 to 4 steps:
146147 1. data is gathered in short packets from the USB controller
Show on old repository browser