From 86266452f80545285c14e20a8024f79c4fb88a86 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Wed, 13 Jan 2010 15:33:15 +0100 Subject: [PATCH] USB: Push BKL on open down into the drivers Straightforward push into the drivers to allow auditing individual drivers separately Signed-off-by: Oliver Neukum Acked-by: Mauro Carvalho Chehab Cc: Jiri Kosina Signed-off-by: Greg Kroah-Hartman --- drivers/hid/usbhid/hiddev.c | 7 +++++-- drivers/media/video/dabusb.c | 8 +++++++- drivers/staging/frontier/alphatrack.c | 3 +++ drivers/staging/frontier/tranzport.c | 3 +++ drivers/usb/class/cdc-wdm.c | 3 +++ drivers/usb/class/usblp.c | 3 +++ drivers/usb/class/usbtmc.c | 3 +++ drivers/usb/core/file.c | 2 -- drivers/usb/image/mdc800.c | 3 +++ drivers/usb/misc/adutux.c | 3 +++ drivers/usb/misc/ftdi-elan.c | 15 ++++++++++++--- drivers/usb/misc/idmouse.c | 8 +++++++- drivers/usb/misc/iowarrior.c | 4 ++++ drivers/usb/misc/ldusb.c | 12 ++++++++++-- drivers/usb/misc/legousbtower.c | 3 +++ drivers/usb/misc/rio500.c | 3 ++- drivers/usb/misc/sisusbvga/sisusb.c | 14 ++++++++++++-- drivers/usb/misc/usblcd.c | 5 +++++ drivers/usb/misc/vstusb.c | 9 ++++++++- drivers/usb/usb-skeleton.c | 3 +++ 20 files changed, 99 insertions(+), 15 deletions(-) diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index 867e08433e4b..433602aed468 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c @@ -265,9 +265,10 @@ static int hiddev_release(struct inode * inode, struct file * file) static int hiddev_open(struct inode *inode, struct file *file) { struct hiddev_list *list; - int res; + int res, i; - int i = iminor(inode) - HIDDEV_MINOR_BASE; + lock_kernel(); + i = iminor(inode) - HIDDEV_MINOR_BASE; if (i >= HIDDEV_MINORS || i < 0 || !hiddev_table[i]) return -ENODEV; @@ -313,10 +314,12 @@ static int hiddev_open(struct inode *inode, struct file *file) usbhid_open(hid); } + unlock_kernel(); return 0; bail: file->private_data = NULL; kfree(list); + unlock_kernel(); return res; } diff --git a/drivers/media/video/dabusb.c b/drivers/media/video/dabusb.c index 9b413a35e048..0f505086774c 100644 --- a/drivers/media/video/dabusb.c +++ b/drivers/media/video/dabusb.c @@ -616,10 +616,12 @@ static int dabusb_open (struct inode *inode, struct file *file) { int devnum = iminor(inode); pdabusb_t s; + int r; if (devnum < DABUSB_MINOR || devnum >= (DABUSB_MINOR + NRDABUSB)) return -EIO; + lock_kernel(); s = &dabusb[devnum - DABUSB_MINOR]; dbg("dabusb_open"); @@ -634,6 +636,7 @@ static int dabusb_open (struct inode *inode, struct file *file) msleep_interruptible(500); if (signal_pending (current)) { + unlock_kernel(); return -EAGAIN; } mutex_lock(&s->mutex); @@ -641,6 +644,7 @@ static int dabusb_open (struct inode *inode, struct file *file) if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) { mutex_unlock(&s->mutex); dev_err(&s->usbdev->dev, "set_interface failed\n"); + unlock_kernel(); return -EINVAL; } s->opened = 1; @@ -649,7 +653,9 @@ static int dabusb_open (struct inode *inode, struct file *file) file->f_pos = 0; file->private_data = s; - return nonseekable_open(inode, file); + r = nonseekable_open(inode, file); + unlock_kernel(); + return r; } static int dabusb_release (struct inode *inode, struct file *file) diff --git a/drivers/staging/frontier/alphatrack.c b/drivers/staging/frontier/alphatrack.c index 15aed87fe1bb..e2f82f0dbad8 100644 --- a/drivers/staging/frontier/alphatrack.c +++ b/drivers/staging/frontier/alphatrack.c @@ -41,6 +41,7 @@ #include #include +#include #include #include #include @@ -325,6 +326,7 @@ static int usb_alphatrack_open(struct inode *inode, struct file *file) int retval = 0; struct usb_interface *interface; + lock_kernel(); nonseekable_open(inode, file); subminor = iminor(inode); @@ -394,6 +396,7 @@ unlock_exit: unlock_disconnect_exit: mutex_unlock(&disconnect_mutex); + unlock_kernel(); return retval; } diff --git a/drivers/staging/frontier/tranzport.c b/drivers/staging/frontier/tranzport.c index ef8fcc8c67bd..1d3f7dc90f4f 100644 --- a/drivers/staging/frontier/tranzport.c +++ b/drivers/staging/frontier/tranzport.c @@ -40,6 +40,7 @@ #include #include +#include #include #include #include @@ -343,6 +344,7 @@ static int usb_tranzport_open(struct inode *inode, struct file *file) int retval = 0; struct usb_interface *interface; + lock_kernel(); nonseekable_open(inode, file); subminor = iminor(inode); @@ -413,6 +415,7 @@ unlock_exit: unlock_disconnect_exit: mutex_unlock(&disconnect_mutex); + unlock_kernel(); return retval; } diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 18aafcb08fc8..b75a3d8bb02f 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -516,6 +517,7 @@ static int wdm_open(struct inode *inode, struct file *file) struct usb_interface *intf; struct wdm_device *desc; + lock_kernel(); mutex_lock(&wdm_mutex); intf = usb_find_interface(&wdm_driver, minor); if (!intf) @@ -548,6 +550,7 @@ static int wdm_open(struct inode *inode, struct file *file) usb_autopm_put_interface(desc->intf); out: mutex_unlock(&wdm_mutex); + unlock_kernel(); return rv; } diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index 93b5f85d7ceb..d53f9499f936 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c @@ -56,6 +56,7 @@ #include #include #include +#include #undef DEBUG #include @@ -395,6 +396,7 @@ static int usblp_open(struct inode *inode, struct file *file) if (minor < 0) return -ENODEV; + lock_kernel(); mutex_lock (&usblp_mutex); retval = -ENODEV; @@ -434,6 +436,7 @@ static int usblp_open(struct inode *inode, struct file *file) } out: mutex_unlock (&usblp_mutex); + unlock_kernel(); return retval; } diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index 8588c0937a89..426bfc72b9b4 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -113,6 +114,7 @@ static int usbtmc_open(struct inode *inode, struct file *filp) struct usbtmc_device_data *data; int retval = 0; + lock_kernel(); intf = usb_find_interface(&usbtmc_driver, iminor(inode)); if (!intf) { printk(KERN_ERR KBUILD_MODNAME @@ -128,6 +130,7 @@ static int usbtmc_open(struct inode *inode, struct file *filp) filp->private_data = data; exit: + unlock_kernel(); return retval; } diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index bfc6c2eea647..c3536f151f02 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c @@ -34,7 +34,6 @@ static int usb_open(struct inode * inode, struct file * file) int err = -ENODEV; const struct file_operations *old_fops, *new_fops = NULL; - lock_kernel(); down_read(&minor_rwsem); c = usb_minors[minor]; @@ -53,7 +52,6 @@ static int usb_open(struct inode * inode, struct file * file) fops_put(old_fops); done: up_read(&minor_rwsem); - unlock_kernel(); return err; } diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c index e192e8f7c560..dce4f7b69ac3 100644 --- a/drivers/usb/image/mdc800.c +++ b/drivers/usb/image/mdc800.c @@ -96,6 +96,7 @@ #include #include #include +#include #include #include @@ -622,6 +623,7 @@ static int mdc800_device_open (struct inode* inode, struct file *file) int retval=0; int errn=0; + lock_kernel(); mutex_lock(&mdc800->io_lock); if (mdc800->state == NOT_CONNECTED) @@ -660,6 +662,7 @@ static int mdc800_device_open (struct inode* inode, struct file *file) error_out: mutex_unlock(&mdc800->io_lock); + unlock_kernel(); return errn; } diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c index 306e97825b36..ac8ad91c2dac 100644 --- a/drivers/usb/misc/adutux.c +++ b/drivers/usb/misc/adutux.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #ifdef CONFIG_USB_DEBUG @@ -274,6 +275,7 @@ static int adu_open(struct inode *inode, struct file *file) dbg(2,"%s : enter", __func__); + lock_kernel(); subminor = iminor(inode); if ((retval = mutex_lock_interruptible(&adutux_mutex))) { @@ -332,6 +334,7 @@ static int adu_open(struct inode *inode, struct file *file) exit_no_device: mutex_unlock(&adutux_mutex); exit_no_lock: + unlock_kernel(); dbg(2,"%s : leave, return value %d ", __func__, retval); return retval; } diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c index f21bf5160f83..32c47fbee288 100644 --- a/drivers/usb/misc/ftdi-elan.c +++ b/drivers/usb/misc/ftdi-elan.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -623,22 +624,30 @@ static void ftdi_elan_status_work(struct work_struct *work) */ static int ftdi_elan_open(struct inode *inode, struct file *file) { - int subminor = iminor(inode); - struct usb_interface *interface = usb_find_interface(&ftdi_elan_driver, - subminor); + int subminor; + struct usb_interface *interface; + + lock_kernel(); + subminor = iminor(inode); + interface = usb_find_interface(&ftdi_elan_driver, subminor); + if (!interface) { + unlock_kernel(); printk(KERN_ERR "can't find device for minor %d\n", subminor); return -ENODEV; } else { struct usb_ftdi *ftdi = usb_get_intfdata(interface); if (!ftdi) { + unlock_kernel(); return -ENODEV; } else { if (down_interruptible(&ftdi->sw_lock)) { + unlock_kernel(); return -EINTR; } else { ftdi_elan_get_kref(ftdi); file->private_data = ftdi; + unlock_kernel(); return 0; } } diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c index a54c3cb804ce..68df9ac76699 100644 --- a/drivers/usb/misc/idmouse.c +++ b/drivers/usb/misc/idmouse.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -226,16 +227,20 @@ static int idmouse_open(struct inode *inode, struct file *file) struct usb_interface *interface; int result; + lock_kernel(); /* get the interface from minor number and driver information */ interface = usb_find_interface (&idmouse_driver, iminor (inode)); - if (!interface) + if (!interface) { + unlock_kernel(); return -ENODEV; + } mutex_lock(&open_disc_mutex); /* get the device information block from the interface */ dev = usb_get_intfdata(interface); if (!dev) { mutex_unlock(&open_disc_mutex); + unlock_kernel(); return -ENODEV; } @@ -272,6 +277,7 @@ error: /* unlock this device */ mutex_unlock(&dev->lock); + unlock_kernel(); return result; } diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index 5206423211fb..d3c852363883 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c @@ -602,10 +602,12 @@ static int iowarrior_open(struct inode *inode, struct file *file) dbg("%s", __func__); + lock_kernel(); subminor = iminor(inode); interface = usb_find_interface(&iowarrior_driver, subminor); if (!interface) { + unlock_kernel(); err("%s - error, can't find device for minor %d", __func__, subminor); return -ENODEV; @@ -615,6 +617,7 @@ static int iowarrior_open(struct inode *inode, struct file *file) dev = usb_get_intfdata(interface); if (!dev) { mutex_unlock(&iowarrior_open_disc_lock); + unlock_kernel(); return -ENODEV; } @@ -641,6 +644,7 @@ static int iowarrior_open(struct inode *inode, struct file *file) out: mutex_unlock(&dev->mutex); + unlock_kernel(); return retval; } diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index 7c0bd13eccb2..8de32df5978a 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -296,12 +297,14 @@ static int ld_usb_open(struct inode *inode, struct file *file) int retval; struct usb_interface *interface; + lock_kernel(); nonseekable_open(inode, file); subminor = iminor(inode); interface = usb_find_interface(&ld_usb_driver, subminor); if (!interface) { + unlock_kernel(); err("%s - error, can't find device for minor %d\n", __func__, subminor); return -ENODEV; @@ -309,12 +312,16 @@ static int ld_usb_open(struct inode *inode, struct file *file) dev = usb_get_intfdata(interface); - if (!dev) + if (!dev) { + unlock_kernel(); return -ENODEV; + } /* lock this device */ - if (mutex_lock_interruptible(&dev->mutex)) + if (mutex_lock_interruptible(&dev->mutex)) { + unlock_kernel(); return -ERESTARTSYS; + } /* allow opening only once */ if (dev->open_count) { @@ -353,6 +360,7 @@ static int ld_usb_open(struct inode *inode, struct file *file) unlock_exit: mutex_unlock(&dev->mutex); + unlock_kernel(); return retval; } diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c index 3d4378fb4410..94e1b84134dd 100644 --- a/drivers/usb/misc/legousbtower.c +++ b/drivers/usb/misc/legousbtower.c @@ -82,6 +82,7 @@ #include #include #include +#include #include #include #include @@ -345,6 +346,7 @@ static int tower_open (struct inode *inode, struct file *file) dbg(2, "%s: enter", __func__); + lock_kernel(); nonseekable_open(inode, file); subminor = iminor(inode); @@ -430,6 +432,7 @@ unlock_exit: mutex_unlock(&dev->lock); exit: + unlock_kernel(); dbg(2, "%s: leave, return value %d ", __func__, retval); return retval; diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c index 17e4eecaee73..47ce46bb5b01 100644 --- a/drivers/usb/misc/rio500.c +++ b/drivers/usb/misc/rio500.c @@ -77,7 +77,7 @@ static struct rio_usb_data rio_instance; static int open_rio(struct inode *inode, struct file *file) { struct rio_usb_data *rio = &rio_instance; - + lock_kernel(); mutex_lock(&(rio->lock)); if (rio->isopen || !rio->present) { @@ -91,6 +91,7 @@ static int open_rio(struct inode *inode, struct file *file) mutex_unlock(&(rio->lock)); dev_info(&rio->rio_dev->dev, "Rio opened.\n"); + unlock_kernel(); return 0; } diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index bb0b315b521d..3991655f8f09 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c @@ -2416,21 +2416,28 @@ sisusb_open(struct inode *inode, struct file *file) struct usb_interface *interface; int subminor = iminor(inode); - if (!(interface = usb_find_interface(&sisusb_driver, subminor))) + lock_kernel(); + if (!(interface = usb_find_interface(&sisusb_driver, subminor))) { + unlock_kernel(); return -ENODEV; + } - if (!(sisusb = usb_get_intfdata(interface))) + if (!(sisusb = usb_get_intfdata(interface))) { + unlock_kernel(); return -ENODEV; + } mutex_lock(&sisusb->lock); if (!sisusb->present || !sisusb->ready) { mutex_unlock(&sisusb->lock); + unlock_kernel(); return -ENODEV; } if (sisusb->isopen) { mutex_unlock(&sisusb->lock); + unlock_kernel(); return -EBUSY; } @@ -2439,11 +2446,13 @@ sisusb_open(struct inode *inode, struct file *file) if (sisusb_init_gfxdevice(sisusb, 0)) { mutex_unlock(&sisusb->lock); dev_err(&sisusb->sisusb_dev->dev, "Failed to initialize device\n"); + unlock_kernel(); return -EIO; } } else { mutex_unlock(&sisusb->lock); dev_err(&sisusb->sisusb_dev->dev, "Device not attached to USB 2.0 hub\n"); + unlock_kernel(); return -EIO; } } @@ -2456,6 +2465,7 @@ sisusb_open(struct inode *inode, struct file *file) file->private_data = sisusb; mutex_unlock(&sisusb->lock); + unlock_kernel(); return 0; } diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c index 499d7508be9a..90aede90553e 100644 --- a/drivers/usb/misc/usblcd.c +++ b/drivers/usb/misc/usblcd.c @@ -74,10 +74,12 @@ static int lcd_open(struct inode *inode, struct file *file) struct usb_interface *interface; int subminor, r; + lock_kernel(); subminor = iminor(inode); interface = usb_find_interface(&lcd_driver, subminor); if (!interface) { + unlock_kernel(); err ("USBLCD: %s - error, can't find device for minor %d", __func__, subminor); return -ENODEV; @@ -87,6 +89,7 @@ static int lcd_open(struct inode *inode, struct file *file) dev = usb_get_intfdata(interface); if (!dev) { mutex_unlock(&open_disc_mutex); + unlock_kernel(); return -ENODEV; } @@ -98,11 +101,13 @@ static int lcd_open(struct inode *inode, struct file *file) r = usb_autopm_get_interface(interface); if (r < 0) { kref_put(&dev->kref, lcd_delete); + unlock_kernel(); return r; } /* save our object in the file's private structure */ file->private_data = dev; + unlock_kernel(); return 0; } diff --git a/drivers/usb/misc/vstusb.c b/drivers/usb/misc/vstusb.c index 874c81bb27b9..b787b25d4cc4 100644 --- a/drivers/usb/misc/vstusb.c +++ b/drivers/usb/misc/vstusb.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -103,19 +104,23 @@ static int vstusb_open(struct inode *inode, struct file *file) struct vstusb_device *vstdev; struct usb_interface *interface; + lock_kernel(); interface = usb_find_interface(&vstusb_driver, iminor(inode)); if (!interface) { printk(KERN_ERR KBUILD_MODNAME ": %s - error, can't find device for minor %d\n", __func__, iminor(inode)); + unlock_kernel(); return -ENODEV; } vstdev = usb_get_intfdata(interface); - if (!vstdev) + if (!vstdev) { + unlock_kernel(); return -ENODEV; + } /* lock this device */ mutex_lock(&vstdev->lock); @@ -123,6 +128,7 @@ static int vstusb_open(struct inode *inode, struct file *file) /* can only open one time */ if ((!vstdev->present) || (vstdev->isopen)) { mutex_unlock(&vstdev->lock); + unlock_kernel(); return -EBUSY; } @@ -137,6 +143,7 @@ static int vstusb_open(struct inode *inode, struct file *file) dev_dbg(&vstdev->usb_dev->dev, "%s: opened\n", __func__); mutex_unlock(&vstdev->lock); + unlock_kernel(); return 0; } diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c index 61522787f39c..e94176bfd272 100644 --- a/drivers/usb/usb-skeleton.c +++ b/drivers/usb/usb-skeleton.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -90,6 +91,7 @@ static int skel_open(struct inode *inode, struct file *file) int subminor; int retval = 0; + lock_kernel(); subminor = iminor(inode); interface = usb_find_interface(&skel_driver, subminor); @@ -135,6 +137,7 @@ static int skel_open(struct inode *inode, struct file *file) mutex_unlock(&dev->io_mutex); exit: + unlock_kernel(); return retval; } -- 2.20.1