USB: serial: mos7720: fix use-after-free on probe errors
[pandora-kernel.git] / drivers / usb / serial / mos7720.c
index 9270d5c..eadeee5 100644 (file)
@@ -383,7 +383,7 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport,
                kfree(urbtrack);
                return -ENOMEM;
        }
-       urbtrack->setup = kmalloc(sizeof(*urbtrack->setup), GFP_KERNEL);
+       urbtrack->setup = kmalloc(sizeof(*urbtrack->setup), GFP_ATOMIC);
        if (!urbtrack->setup) {
                usb_free_urb(urbtrack->urb);
                kfree(urbtrack);
@@ -391,8 +391,8 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport,
        }
        urbtrack->setup->bRequestType = (__u8)0x40;
        urbtrack->setup->bRequest = (__u8)0x0e;
-       urbtrack->setup->wValue = get_reg_value(reg, dummy);
-       urbtrack->setup->wIndex = get_reg_index(reg);
+       urbtrack->setup->wValue = cpu_to_le16(get_reg_value(reg, dummy));
+       urbtrack->setup->wIndex = cpu_to_le16(get_reg_index(reg));
        urbtrack->setup->wLength = 0;
        usb_fill_control_urb(urbtrack->urb, usbdev,
                             usb_sndctrlpipe(usbdev, 0),
@@ -1320,7 +1320,7 @@ static int mos7720_write(struct tty_struct *tty, struct usb_serial_port *port,
 
        if (urb->transfer_buffer == NULL) {
                urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE,
-                                              GFP_KERNEL);
+                                              GFP_ATOMIC);
                if (urb->transfer_buffer == NULL) {
                        dev_err(&port->dev, "%s no more kernel memory...\n",
                                __func__);
@@ -2079,6 +2079,11 @@ static int mos7720_startup(struct usb_serial *serial)
                return -ENODEV;
        }
 
+       if (serial->num_bulk_in < 2 || serial->num_bulk_out < 2) {
+               dev_err(&serial->interface->dev, "missing bulk endpoints\n");
+               return -ENODEV;
+       }
+
        product = le16_to_cpu(serial->dev->descriptor.idProduct);
        dev = serial->dev;
 
@@ -2142,8 +2147,10 @@ static int mos7720_startup(struct usb_serial *serial)
 #ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT
        if (product == MOSCHIP_DEVICE_ID_7715) {
                ret_val = mos7715_parport_init(serial);
-               if (ret_val < 0)
+               if (ret_val < 0) {
+                       usb_kill_urb(serial->port[0]->interrupt_in_urb);
                        return ret_val;
+               }
        }
 #endif
        /* LSR For Port 1 */
@@ -2157,6 +2164,8 @@ static void mos7720_release(struct usb_serial *serial)
 {
        int i;
 
+       usb_kill_urb(serial->port[0]->interrupt_in_urb);
+
 #ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT
        /* close the parallel port */