From 8cfbe7e60d9618d8f80a3cd218c45dd64cb9e5cf Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Wed, 30 May 2007 11:06:33 -0400 Subject: USB: g_file_storage: call allow_signal() New changes in the signal-handling code require compensating changes in g_file_storage. This patch (as913) by Oleg Nesterov makes the code use allow_signal() instead of sigprocmask(). From: Alan Stern Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/file_storage.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index c6b6479fa4d..4639b629e60 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -686,7 +686,6 @@ struct fsg_dev { int thread_wakeup_needed; struct completion thread_notifier; struct task_struct *thread_task; - sigset_t thread_signal_mask; int cmnd_size; u8 cmnd[MAX_COMMAND_SIZE]; @@ -3277,8 +3276,7 @@ static void handle_exception(struct fsg_dev *fsg) /* Clear the existing signals. Anything but SIGUSR1 is converted * into a high-priority EXIT exception. */ for (;;) { - sig = dequeue_signal_lock(current, &fsg->thread_signal_mask, - &info); + sig = dequeue_signal_lock(current, ¤t->blocked, &info); if (!sig) break; if (sig != SIGUSR1) { @@ -3431,10 +3429,10 @@ static int fsg_main_thread(void *fsg_) /* Allow the thread to be killed by a signal, but set the signal mask * to block everything but INT, TERM, KILL, and USR1. */ - siginitsetinv(&fsg->thread_signal_mask, sigmask(SIGINT) | - sigmask(SIGTERM) | sigmask(SIGKILL) | - sigmask(SIGUSR1)); - sigprocmask(SIG_SETMASK, &fsg->thread_signal_mask, NULL); + allow_signal(SIGINT); + allow_signal(SIGTERM); + allow_signal(SIGKILL); + allow_signal(SIGUSR1); /* Arrange for userspace references to be interpreted as kernel * pointers. That way we can pass a kernel pointer to a routine -- cgit v1.2.3 From 944dc184f6fe0dc63633099ba87cb75fe4ee0c51 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Mon, 7 May 2007 08:33:18 +0200 Subject: USB: ti serial driver sleeps with spinlock held you are submitting an URB with GFP_KERNEL holding a spinlock. In this case the spinlock can be dropped earlier. Signed-off-by: Oliver Neukum Cc: Al Borchers Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ti_usb_3410_5052.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 4203e2b1a76..3d505fd0645 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -1555,15 +1555,17 @@ static int ti_restart_read(struct ti_port *tport, struct tty_struct *tty) spin_lock_irqsave(&tport->tp_lock, flags); if (tport->tp_read_urb_state == TI_READ_URB_STOPPED) { + tport->tp_read_urb_state = TI_READ_URB_RUNNING; urb = tport->tp_port->read_urb; + spin_unlock_irqrestore(&tport->tp_lock, flags); urb->complete = ti_bulk_in_callback; urb->context = tport; urb->dev = tport->tp_port->serial->dev; status = usb_submit_urb(urb, GFP_KERNEL); + } else { + tport->tp_read_urb_state = TI_READ_URB_RUNNING; + spin_unlock_irqrestore(&tport->tp_lock, flags); } - tport->tp_read_urb_state = TI_READ_URB_RUNNING; - - spin_unlock_irqrestore(&tport->tp_lock, flags); return status; } -- cgit v1.2.3 From fc0f8fc9be654bbff08ede04a49bd8f9805b9e13 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Tue, 12 Jun 2007 15:36:07 +0200 Subject: USB: memory leak in iowarrior.c this is a classical memory leak in the ioctl handler. The buffer is simply never freed. This fixes it the obvious way. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/iowarrior.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index fc51207b71b..3bb33f7bfa3 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c @@ -495,8 +495,8 @@ static int iowarrior_ioctl(struct inode *inode, struct file *file, /* verify that the device wasn't unplugged */ if (!dev->present) { - mutex_unlock(&dev->mutex); - return -ENODEV; + retval = -ENODEV; + goto error_out; } dbg("%s - minor %d, cmd 0x%.4x, arg %ld", __func__, dev->minor, cmd, @@ -579,9 +579,10 @@ static int iowarrior_ioctl(struct inode *inode, struct file *file, retval = -ENOTTY; break; } - +error_out: /* unlock the device */ mutex_unlock(&dev->mutex); + kfree(buffer); return retval; } -- cgit v1.2.3 From 5afeb104e7901168b21aad0437fb51dc620dfdd3 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Mon, 11 Jun 2007 15:36:02 +0200 Subject: 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 Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/usblcd.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c index 887ef953f3d..12bad8a205a 100644 --- a/drivers/usb/misc/usblcd.c +++ b/drivers/usb/misc/usblcd.c @@ -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; static DEFINE_MUTEX(usb_lcd_open_mutex); @@ -186,12 +190,13 @@ static void lcd_write_bulk_callback(struct urb *urb) /* 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; @@ -201,10 +206,16 @@ static ssize_t lcd_write(struct file *file, const char __user * user_buffer, siz 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) { @@ -239,6 +250,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; } @@ -277,6 +290,7 @@ static int lcd_probe(struct usb_interface *interface, const struct usb_device_id 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; -- cgit v1.2.3 From 74ac07e8b8209ba9429fa1a9afc07aa5ecef5af8 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Wed, 13 Jun 2007 18:50:41 +0200 Subject: USB: fix race leading to use after free in io_edgeport usb_unlink_urb() is asynchronous, therefore an URB's buffer may not be freed without waiting for the completion handler. This patch switches to usb_kill_urb(), which is synchronous. Thanks to Alan for making me look at the remaining users of usb_unlink_urb() Signed-off-by: Oliver Neukum Signed-off-by: Al Borchers Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/io_edgeport.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index 4807f960150..056e1923c4d 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -3046,11 +3046,11 @@ static void edge_shutdown (struct usb_serial *serial) } /* free up our endpoint stuff */ if (edge_serial->is_epic) { - usb_unlink_urb(edge_serial->interrupt_read_urb); + usb_kill_urb(edge_serial->interrupt_read_urb); usb_free_urb(edge_serial->interrupt_read_urb); kfree(edge_serial->interrupt_in_buffer); - usb_unlink_urb(edge_serial->read_urb); + usb_kill_urb(edge_serial->read_urb); usb_free_urb(edge_serial->read_urb); kfree(edge_serial->bulk_in_buffer); } -- cgit v1.2.3 From 46269db99cc1a618d707deb370d821d1f8d75945 Mon Sep 17 00:00:00 2001 From: Alexander Gattin Date: Wed, 20 Jun 2007 00:48:10 +0300 Subject: USB: add new device id to option driver Cc: Matthias Urlichs Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 89f067d9507..5d3999e3ff6 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -111,7 +111,8 @@ static int option_send_setup(struct usb_serial_port *port); #define NOVATELWIRELESS_VENDOR_ID 0x1410 #define ANYDATA_VENDOR_ID 0x16d5 -#define ANYDATA_PRODUCT_ID 0x6501 +#define ANYDATA_PRODUCT_ADU_E100A 0x6501 +#define ANYDATA_PRODUCT_ADU_500A 0x6502 #define BANDRICH_VENDOR_ID 0x1A8D #define BANDRICH_PRODUCT_C100_1 0x1002 @@ -169,7 +170,8 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2110) }, /* Novatel Merlin ES620 / Merlin ES720 / Ovation U720 */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2410) }, /* Novatel EU740 */ - { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) }, + { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, + { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, { USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard */ -- cgit v1.2.3 From d099321bdbba0d49796841cd9d9faf6b0f0aa658 Mon Sep 17 00:00:00 2001 From: "Luiz Fernando N. Capitulino" Date: Thu, 21 Jun 2007 22:34:23 -0300 Subject: USB: ftdio_sio: New IPlus device ID Reported by Grzegorz Chimosz Signed-off-by: Luiz Fernando N. Capitulino Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 1 + drivers/usb/serial/ftdi_sio.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 2353679f601..da1c6f7f82b 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -317,6 +317,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_ACTZWAVE_PID) }, { USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_IPLUS_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_IPLUS2_PID) }, { USB_DEVICE(FTDI_VID, FTDI_DMX4ALL) }, { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) }, { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) }, diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 33aee904724..d9e49716db1 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -56,6 +56,7 @@ /* iPlus device */ #define FTDI_IPLUS_PID 0xD070 /* Product Id */ +#define FTDI_IPLUS2_PID 0xD071 /* Product Id */ /* DMX4ALL DMX Interfaces */ #define FTDI_DMX4ALL 0xC850 -- cgit v1.2.3