summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'tags/2.6.18-11/30015_usblcd-limit-memory-consumption.patch')
-rw-r--r--tags/2.6.18-11/30015_usblcd-limit-memory-consumption.patch89
1 files changed, 89 insertions, 0 deletions
diff --git a/tags/2.6.18-11/30015_usblcd-limit-memory-consumption.patch b/tags/2.6.18-11/30015_usblcd-limit-memory-consumption.patch
new file mode 100644
index 0000000..735810b
--- /dev/null
+++ b/tags/2.6.18-11/30015_usblcd-limit-memory-consumption.patch
@@ -0,0 +1,89 @@
+From: Oliver Neukum <oneukum@suse.de>
+Date: Mon, 11 Jun 2007 13:36:02 +0000 (+0200)
+Subject: USB: usblcd doesn't limit memory consumption during write
+X-Git-Tag: v2.6.22-rc7~49^2~3
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=5afeb104e7901168b21aad0437fb51dc620dfdd3
+
+USB: usblcd doesn't limit memory consumption during write
+
+usblcd currently has no way to limit memory consumption by fast writers.
+This is a security problem, as it allows users with write access to this
+device to drive the system into oom despite resource limits.
+Here's the fix taken from the modern skeleton driver.
+
+Signed-off-by: Oliver Neukum <oneukum@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+
+Backported to Debian's 2.6.18 by dann frazier <dannf@debian.org>
+
+diff -urpN linux-source-2.6.18.orig/drivers/usb/misc/usblcd.c linux-source-2.6.18/drivers/usb/misc/usblcd.c
+--- linux-source-2.6.18.orig/drivers/usb/misc/usblcd.c 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/drivers/usb/misc/usblcd.c 2007-08-07 16:12:28.000000000 -0600
+@@ -42,10 +42,14 @@ struct usb_lcd {
+ size_t bulk_in_size; /* the size of the receive buffer */
+ __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */
+ __u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */
+- struct kref kref;
++ struct kref kref;
++ struct semaphore limit_sem; /* to stop writes at full throttle from
++ * using up all RAM */
+ };
+ #define to_lcd_dev(d) container_of(d, struct usb_lcd, kref)
+
++#define USB_LCD_CONCURRENT_WRITES 5
++
+ static struct usb_driver lcd_driver;
+
+
+@@ -183,12 +187,13 @@ static void lcd_write_bulk_callback(stru
+ /* free up our allocated buffer */
+ usb_buffer_free(urb->dev, urb->transfer_buffer_length,
+ urb->transfer_buffer, urb->transfer_dma);
++ up(&dev->limit_sem);
+ }
+
+ static ssize_t lcd_write(struct file *file, const char __user * user_buffer, size_t count, loff_t *ppos)
+ {
+ struct usb_lcd *dev;
+- int retval = 0;
++ int retval = 0, r;
+ struct urb *urb = NULL;
+ char *buf = NULL;
+
+@@ -198,10 +203,16 @@ static ssize_t lcd_write(struct file *fi
+ if (count == 0)
+ goto exit;
+
++ r = down_interruptible(&dev->limit_sem);
++ if (r < 0)
++ return -EINTR;
++
+ /* create a urb, and a buffer for it, and copy the data to the urb */
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+- if (!urb)
+- return -ENOMEM;
++ if (!urb) {
++ retval = -ENOMEM;
++ goto err_no_buf;
++ }
+
+ buf = usb_buffer_alloc(dev->udev, count, GFP_KERNEL, &urb->transfer_dma);
+ if (!buf) {
+@@ -236,6 +247,8 @@ exit:
+ error:
+ usb_buffer_free(dev->udev, count, buf, urb->transfer_dma);
+ usb_free_urb(urb);
++err_no_buf:
++ up(&dev->limit_sem);
+ return retval;
+ }
+
+@@ -274,6 +287,7 @@ static int lcd_probe(struct usb_interfac
+ goto error;
+ }
+ kref_init(&dev->kref);
++ sema_init(&dev->limit_sem, USB_LCD_CONCURRENT_WRITES);
+
+ dev->udev = usb_get_dev(interface_to_usbdev(interface));
+ dev->interface = interface;