ChangeSet 1.1455.1.37, 2003/07/16 10:15:18-07:00, oliver@neukum.org [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. drivers/usb/misc/usblcd.c | 22 ++++++++++++---------- 1 files changed, 12 insertions(+), 10 deletions(-) diff -Nru a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c --- a/drivers/usb/misc/usblcd.c Thu Jul 17 17:03:35 2003 +++ b/drivers/usb/misc/usblcd.c Thu Jul 17 17:03:35 2003 @@ -1,4 +1,4 @@ -/***************************************************************************** +/***************************************************************************** * USBLCD Kernel Driver * * See http://www.usblcd.de for Hardware and Documentation. * * Version 1.03 * @@ -18,7 +18,7 @@ #include #include -#define DRIVER_VERSION "USBLCD Driver Version 1.03" +#define DRIVER_VERSION "USBLCD Driver Version 1.04" #define USBLCD_MINOR 144 @@ -257,7 +257,7 @@ struct lcd_usb_data *lcd = &lcd_instance; int i; int retval; - + if (dev->descriptor.idProduct != 0x0001 ) { warn(KERN_INFO "USBLCD model not supported."); return -ENODEV; @@ -274,29 +274,31 @@ (i & 0xF000)>>12,(i & 0xF00)>>8,(i & 0xF0)>>4,(i & 0xF), 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->lcd_dev = dev; if (!(lcd->obuf = (char *) kmalloc(OBUF_SIZE, GFP_KERNEL))) { err("probe_lcd: Not enough memory for the output buffer"); - usb_deregister_dev(intf, &usb_lcd_class); return -ENOMEM; } dbg("probe_lcd: obuf address:%p", lcd->obuf); if (!(lcd->ibuf = (char *) kmalloc(IBUF_SIZE, GFP_KERNEL))) { err("probe_lcd: Not enough memory for the input buffer"); - usb_deregister_dev(intf, &usb_lcd_class); kfree(lcd->obuf); return -ENOMEM; } 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); return 0;