Commit 1c2bd8e2 authored by Oliver Neukum's avatar Oliver Neukum Committed by Greg Kroah-Hartman

[PATCH] USB: usblcd: race between open and read/write

usblcd registers a device before all buffers are allocated leading
to a race resulting in NULL pointers being followed.
This fixes it.
parent ba0b18d2
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <linux/usb.h> #include <linux/usb.h>
#define DRIVER_VERSION "USBLCD Driver Version 1.03" #define DRIVER_VERSION "USBLCD Driver Version 1.04"
#define USBLCD_MINOR 144 #define USBLCD_MINOR 144
...@@ -274,30 +274,32 @@ static int probe_lcd(struct usb_interface *intf, const struct usb_device_id *id) ...@@ -274,30 +274,32 @@ static int probe_lcd(struct usb_interface *intf, const struct usb_device_id *id)
(i & 0xF000)>>12,(i & 0xF00)>>8,(i & 0xF0)>>4,(i & 0xF), (i & 0xF000)>>12,(i & 0xF00)>>8,(i & 0xF0)>>4,(i & 0xF),
dev->devnum); dev->devnum);
retval = usb_register_dev(intf, &usb_lcd_class);
if (retval) {
err("Not able to get a minor for this device.");
return -ENOMEM;
}
lcd->present = 1; lcd->present = 1;
lcd->lcd_dev = dev; lcd->lcd_dev = dev;
if (!(lcd->obuf = (char *) kmalloc(OBUF_SIZE, GFP_KERNEL))) { if (!(lcd->obuf = (char *) kmalloc(OBUF_SIZE, GFP_KERNEL))) {
err("probe_lcd: Not enough memory for the output buffer"); err("probe_lcd: Not enough memory for the output buffer");
usb_deregister_dev(intf, &usb_lcd_class);
return -ENOMEM; return -ENOMEM;
} }
dbg("probe_lcd: obuf address:%p", lcd->obuf); dbg("probe_lcd: obuf address:%p", lcd->obuf);
if (!(lcd->ibuf = (char *) kmalloc(IBUF_SIZE, GFP_KERNEL))) { if (!(lcd->ibuf = (char *) kmalloc(IBUF_SIZE, GFP_KERNEL))) {
err("probe_lcd: Not enough memory for the input buffer"); err("probe_lcd: Not enough memory for the input buffer");
usb_deregister_dev(intf, &usb_lcd_class);
kfree(lcd->obuf); kfree(lcd->obuf);
return -ENOMEM; return -ENOMEM;
} }
dbg("probe_lcd: ibuf address:%p", lcd->ibuf); dbg("probe_lcd: ibuf address:%p", lcd->ibuf);
retval = usb_register_dev(intf, &usb_lcd_class);
if (retval) {
err("Not able to get a minor for this device.");
kfree(lcd->obuf);
kfree(lcd->ibuf);
return -ENOMEM;
}
usb_set_intfdata (intf, lcd); usb_set_intfdata (intf, lcd);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment