diff options
Diffstat (limited to 'tags/2.6.18-6/30015_usblcd-limit-memory-consumption.patch')
-rw-r--r-- | tags/2.6.18-6/30015_usblcd-limit-memory-consumption.patch | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/tags/2.6.18-6/30015_usblcd-limit-memory-consumption.patch b/tags/2.6.18-6/30015_usblcd-limit-memory-consumption.patch new file mode 100644 index 0000000..735810b --- /dev/null +++ b/tags/2.6.18-6/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; |