1. 24 6月, 2016 1 次提交
  2. 25 2月, 2013 2 次提交
  3. 28 11月, 2012 1 次提交
    • J
      HID: hiddev: fix nonblocking read semantics wrt EIO/ERESTARTSYS · 13f19624
      Jiri Kosina 提交于
      When the file has been open in non-blocking mode, EIO or ERESTARTSYS
      would never be returned even if they should (for example when device
      has been unplugged, you want EIO and not EAGAIN to be returned).
      
      Move the O_NONBLOCK check after other checks have been performed.
      
      Base on similar patch done to hidraw by
      Founder Fang <founder.fang@gmail.com>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      13f19624
  4. 16 11月, 2012 1 次提交
  5. 27 4月, 2012 1 次提交
  6. 02 2月, 2012 1 次提交
    • M
      HID: usbhid: fix dead lock between open and disconect · ba18311d
      Ming Lei 提交于
      There is no reason to hold hiddev->existancelock before
      calling usb_deregister_dev, so move it out of the lock.
      
      The patch fixes the lockdep warning below.
      
      [ 5733.386271] ======================================================
      [ 5733.386274] [ INFO: possible circular locking dependency detected ]
      [ 5733.386278] 3.2.0-custom-next-20120111+ #1 Not tainted
      [ 5733.386281] -------------------------------------------------------
      [ 5733.386284] khubd/186 is trying to acquire lock:
      [ 5733.386288]  (minor_rwsem){++++.+}, at: [<ffffffffa0011a04>] usb_deregister_dev+0x37/0x9e [usbcore]
      [ 5733.386311]
      [ 5733.386312] but task is already holding lock:
      [ 5733.386315]  (&hiddev->existancelock){+.+...}, at: [<ffffffffa0094d17>] hiddev_disconnect+0x26/0x87 [usbhid]
      [ 5733.386328]
      [ 5733.386329] which lock already depends on the new lock.
      [ 5733.386330]
      [ 5733.386333]
      [ 5733.386334] the existing dependency chain (in reverse order) is:
      [ 5733.386336]
      [ 5733.386337] -> #1 (&hiddev->existancelock){+.+...}:
      [ 5733.386346]        [<ffffffff81082d26>] lock_acquire+0xcb/0x10e
      [ 5733.386357]        [<ffffffff813df961>] __mutex_lock_common+0x60/0x465
      [ 5733.386366]        [<ffffffff813dfe4d>] mutex_lock_nested+0x36/0x3b
      [ 5733.386371]        [<ffffffffa0094ad6>] hiddev_open+0x113/0x193 [usbhid]
      [ 5733.386378]        [<ffffffffa0011971>] usb_open+0x66/0xc2 [usbcore]
      [ 5733.386390]        [<ffffffff8111a8b5>] chrdev_open+0x12b/0x154
      [ 5733.386402]        [<ffffffff811159a8>] __dentry_open.isra.16+0x20b/0x355
      [ 5733.386408]        [<ffffffff811165dc>] nameidata_to_filp+0x43/0x4a
      [ 5733.386413]        [<ffffffff81122ed5>] do_last+0x536/0x570
      [ 5733.386419]        [<ffffffff8112300b>] path_openat+0xce/0x301
      [ 5733.386423]        [<ffffffff81123327>] do_filp_open+0x33/0x81
      [ 5733.386427]        [<ffffffff8111664d>] do_sys_open+0x6a/0xfc
      [ 5733.386431]        [<ffffffff811166fb>] sys_open+0x1c/0x1e
      [ 5733.386434]        [<ffffffff813e7c79>] system_call_fastpath+0x16/0x1b
      [ 5733.386441]
      [ 5733.386441] -> #0 (minor_rwsem){++++.+}:
      [ 5733.386448]        [<ffffffff8108255d>] __lock_acquire+0xa80/0xd74
      [ 5733.386454]        [<ffffffff81082d26>] lock_acquire+0xcb/0x10e
      [ 5733.386458]        [<ffffffff813e01f5>] down_write+0x44/0x77
      [ 5733.386464]        [<ffffffffa0011a04>] usb_deregister_dev+0x37/0x9e [usbcore]
      [ 5733.386475]        [<ffffffffa0094d2d>] hiddev_disconnect+0x3c/0x87 [usbhid]
      [ 5733.386483]        [<ffffffff8132df51>] hid_disconnect+0x3f/0x54
      [ 5733.386491]        [<ffffffff8132dfb4>] hid_device_remove+0x4e/0x7a
      [ 5733.386496]        [<ffffffff812c0957>] __device_release_driver+0x81/0xcd
      [ 5733.386502]        [<ffffffff812c09c3>] device_release_driver+0x20/0x2d
      [ 5733.386507]        [<ffffffff812c0564>] bus_remove_device+0x114/0x128
      [ 5733.386512]        [<ffffffff812bdd6f>] device_del+0x131/0x183
      [ 5733.386519]        [<ffffffff8132def3>] hid_destroy_device+0x1e/0x3d
      [ 5733.386525]        [<ffffffffa00916b0>] usbhid_disconnect+0x36/0x42 [usbhid]
      [ 5733.386530]        [<ffffffffa000fb60>] usb_unbind_interface+0x57/0x11f [usbcore]
      [ 5733.386542]        [<ffffffff812c0957>] __device_release_driver+0x81/0xcd
      [ 5733.386547]        [<ffffffff812c09c3>] device_release_driver+0x20/0x2d
      [ 5733.386552]        [<ffffffff812c0564>] bus_remove_device+0x114/0x128
      [ 5733.386557]        [<ffffffff812bdd6f>] device_del+0x131/0x183
      [ 5733.386562]        [<ffffffffa000de61>] usb_disable_device+0xa8/0x1d8 [usbcore]
      [ 5733.386573]        [<ffffffffa0006bd2>] usb_disconnect+0xab/0x11f [usbcore]
      [ 5733.386583]        [<ffffffffa0008aa0>] hub_thread+0x73b/0x1157 [usbcore]
      [ 5733.386593]        [<ffffffff8105dc0f>] kthread+0x95/0x9d
      [ 5733.386601]        [<ffffffff813e90b4>] kernel_thread_helper+0x4/0x10
      [ 5733.386607]
      [ 5733.386608] other info that might help us debug this:
      [ 5733.386609]
      [ 5733.386612]  Possible unsafe locking scenario:
      [ 5733.386613]
      [ 5733.386615]        CPU0                    CPU1
      [ 5733.386618]        ----                    ----
      [ 5733.386620]   lock(&hiddev->existancelock);
      [ 5733.386625]                                lock(minor_rwsem);
      [ 5733.386630]                                lock(&hiddev->existancelock);
      [ 5733.386635]   lock(minor_rwsem);
      [ 5733.386639]
      [ 5733.386640]  *** DEADLOCK ***
      [ 5733.386641]
      [ 5733.386644] 6 locks held by khubd/186:
      [ 5733.386646]  #0:  (&__lockdep_no_validate__){......}, at: [<ffffffffa00084af>] hub_thread+0x14a/0x1157 [usbcore]
      [ 5733.386661]  #1:  (&__lockdep_no_validate__){......}, at: [<ffffffffa0006b77>] usb_disconnect+0x50/0x11f [usbcore]
      [ 5733.386677]  #2:  (hcd->bandwidth_mutex){+.+.+.}, at: [<ffffffffa0006bc8>] usb_disconnect+0xa1/0x11f [usbcore]
      [ 5733.386693]  #3:  (&__lockdep_no_validate__){......}, at: [<ffffffff812c09bb>] device_release_driver+0x18/0x2d
      [ 5733.386704]  #4:  (&__lockdep_no_validate__){......}, at: [<ffffffff812c09bb>] device_release_driver+0x18/0x2d
      [ 5733.386714]  #5:  (&hiddev->existancelock){+.+...}, at: [<ffffffffa0094d17>] hiddev_disconnect+0x26/0x87 [usbhid]
      [ 5733.386727]
      [ 5733.386727] stack backtrace:
      [ 5733.386731] Pid: 186, comm: khubd Not tainted 3.2.0-custom-next-20120111+ #1
      [ 5733.386734] Call Trace:
      [ 5733.386741]  [<ffffffff81062881>] ? up+0x34/0x3b
      [ 5733.386747]  [<ffffffff813d9ef3>] print_circular_bug+0x1f8/0x209
      [ 5733.386752]  [<ffffffff8108255d>] __lock_acquire+0xa80/0xd74
      [ 5733.386756]  [<ffffffff810808b4>] ? trace_hardirqs_on_caller+0x15d/0x1a3
      [ 5733.386763]  [<ffffffff81043a3f>] ? vprintk+0x3f4/0x419
      [ 5733.386774]  [<ffffffffa0011a04>] ? usb_deregister_dev+0x37/0x9e [usbcore]
      [ 5733.386779]  [<ffffffff81082d26>] lock_acquire+0xcb/0x10e
      [ 5733.386789]  [<ffffffffa0011a04>] ? usb_deregister_dev+0x37/0x9e [usbcore]
      [ 5733.386797]  [<ffffffff813e01f5>] down_write+0x44/0x77
      [ 5733.386807]  [<ffffffffa0011a04>] ? usb_deregister_dev+0x37/0x9e [usbcore]
      [ 5733.386818]  [<ffffffffa0011a04>] usb_deregister_dev+0x37/0x9e [usbcore]
      [ 5733.386825]  [<ffffffffa0094d2d>] hiddev_disconnect+0x3c/0x87 [usbhid]
      [ 5733.386830]  [<ffffffff8132df51>] hid_disconnect+0x3f/0x54
      [ 5733.386834]  [<ffffffff8132dfb4>] hid_device_remove+0x4e/0x7a
      [ 5733.386839]  [<ffffffff812c0957>] __device_release_driver+0x81/0xcd
      [ 5733.386844]  [<ffffffff812c09c3>] device_release_driver+0x20/0x2d
      [ 5733.386848]  [<ffffffff812c0564>] bus_remove_device+0x114/0x128
      [ 5733.386854]  [<ffffffff812bdd6f>] device_del+0x131/0x183
      [ 5733.386859]  [<ffffffff8132def3>] hid_destroy_device+0x1e/0x3d
      [ 5733.386865]  [<ffffffffa00916b0>] usbhid_disconnect+0x36/0x42 [usbhid]
      [ 5733.386876]  [<ffffffffa000fb60>] usb_unbind_interface+0x57/0x11f [usbcore]
      [ 5733.386882]  [<ffffffff812c0957>] __device_release_driver+0x81/0xcd
      [ 5733.386886]  [<ffffffff812c09c3>] device_release_driver+0x20/0x2d
      [ 5733.386890]  [<ffffffff812c0564>] bus_remove_device+0x114/0x128
      [ 5733.386895]  [<ffffffff812bdd6f>] device_del+0x131/0x183
      [ 5733.386905]  [<ffffffffa000de61>] usb_disable_device+0xa8/0x1d8 [usbcore]
      [ 5733.386916]  [<ffffffffa0006bd2>] usb_disconnect+0xab/0x11f [usbcore]
      [ 5733.386921]  [<ffffffff813dff82>] ? __mutex_unlock_slowpath+0x130/0x141
      [ 5733.386929]  [<ffffffffa0008aa0>] hub_thread+0x73b/0x1157 [usbcore]
      [ 5733.386935]  [<ffffffff8106a51d>] ? finish_task_switch+0x78/0x150
      [ 5733.386941]  [<ffffffff8105e396>] ? __init_waitqueue_head+0x4c/0x4c
      [ 5733.386950]  [<ffffffffa0008365>] ? usb_remote_wakeup+0x56/0x56 [usbcore]
      [ 5733.386955]  [<ffffffff8105dc0f>] kthread+0x95/0x9d
      [ 5733.386961]  [<ffffffff813e90b4>] kernel_thread_helper+0x4/0x10
      [ 5733.386966]  [<ffffffff813e24b8>] ? retint_restore_args+0x13/0x13
      [ 5733.386970]  [<ffffffff8105db7a>] ? __init_kthread_worker+0x55/0x55
      [ 5733.386974]  [<ffffffff813e90b0>] ? gs_change+0x13/0x13
      Signed-off-by: NMing Lei <ming.lei@canonical.com>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      ba18311d
  7. 04 1月, 2012 1 次提交
  8. 27 9月, 2011 1 次提交
    • D
      HID: hiddev: potential info leak in hiddev_ioctl() · 9561f7fa
      Dan Carpenter 提交于
      Smatch has a new check for Rosenberg type information leaks where
      structs are copied to the user with uninitialized stack data in them.
      
      In this case, the hiddev_devinfo struct has a two byte hole.
      
      struct hiddev_devinfo {
              __u32                      bustype;              /*     0     4 */
              __u32                      busnum;               /*     4     4 */
              __u32                      devnum;               /*     8     4 */
              __u32                      ifnum;                /*    12     4 */
              __s16                      vendor;               /*    16     2 */
              __s16                      product;              /*    18     2 */
              __s16                      version;              /*    20     2 */
      
              /* XXX 2 bytes hole, try to pack */
      
              __u32                      num_applications;     /*    24     4 */
      Signed-off-by: NDan Carpenter <dan.carpenter@oracle.com>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      9561f7fa
  9. 26 5月, 2011 1 次提交
  10. 24 5月, 2011 1 次提交
    • J
      HID: hiddev: fix potential use-after-free · 7f77897e
      Jiri Kosina 提交于
      Commit 6cb4b040 ("HID: hiddev: fix race between hiddev_disconnect
      and hiddev_release") made it possible to access hiddev (for unlocking
      the existance mutex) once hiddev has been kfreed.
      
      Change the order so that this can not happen (always unlock the mutex first,
      it is needed only to protect access to ->exist and ->open).
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      7f77897e
  11. 20 5月, 2011 1 次提交
    • J
      HID: hiddev: fix race between hiddev_disconnect and hiddev_release · 6cb4b040
      Jiri Kosina 提交于
      When hiddev_disconnect() runs with chardev open, it will proceed with
      usbhid_close(). When userspace in parallel runs the hiddev_release(),
      it sees !hiddev->exists (as it has been already set so by
      hiddev_disconnect()) and kfrees hiddev while hiddev_disconnect() hasn't
      finished yet.
      
      Serialize the access to hiddev->exists and hiddev->open by existancelock.
      
      Reported-by: mike-@cinci.rr.com
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      6cb4b040
  12. 18 5月, 2011 1 次提交
  13. 29 4月, 2011 1 次提交
  14. 27 3月, 2011 1 次提交
  15. 10 12月, 2010 1 次提交
    • J
      HID: Add and use hid_<level>: dev_<level> equivalents · 4291ee30
      Joe Perches 提交于
      Neaten current uses of dev_<level> by adding and using
      hid specific hid_<level> macros.
      
      Convert existing uses of dev_<level> uses to hid_<level>.
      Convert hid-pidff printk uses to hid_<level>.
      
      Remove err_hid and use hid_err instead.
      
      Add missing newlines to logging messages where necessary.
      Coalesce format strings.
      
      Add and use pr_fmt(fmt) KBUILD_MODNAME ": " fmt
      
      Other miscellaneous changes:
      
      Add const struct hid_device * argument to hid-core functions
      extract() and implement() so hid_<level> can be used by them.
      Fix bad indentation in hid-core hid_input_field function
      that calls extract() function above.
      Signed-off-by: NJoe Perches <joe@perches.com>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      4291ee30
  16. 07 12月, 2010 2 次提交
    • V
      HID: Consolidate device existence checks in hiddev_ioctl · 33d6eb57
      Valentine Barshak 提交于
      Currently, if the device has been removed before hiddev_ioctl(),
      the -EIO is returned. If it's removed while hiddev_ioctl() is in
      progress, some commands are still processed fine, others
      return -ENODEV. This change takes the "existancelock" before
      processing ioctl commands and releases it at the end.
      If the device has been removed, always returns -ENODEV.
      Signed-off-by: NValentine Barshak <vbarshak@mvista.com>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      33d6eb57
    • V
      HID: Fix race between disconnect and hiddev_ioctl · 1a8e8fab
      Valentine Barshak 提交于
      A USB HID device can be disconnected at any time.
      If this happens right before or while hiddev_ioctl is in progress,
      the hiddev_ioctl tries to access invalid hiddev->hid pointer.
      When the hid device is disconnected, the hiddev_disconnect()
      ends up with a call to hid_device_release() which frees
      hid_device, but doesn't set the hiddev->hid pointer to NULL.
      If the deallocated memory region has been re-used by the kernel,
      this can cause a crash or memory corruption.
      
      Since disconnect can happen at any time, we can't initialize
      struct hid_device *hid = hiddev->hid at the beginning of ioctl
      and then use it.
      
      This change checks hiddev->exist flag while holding
      the existancelock and uses hid_device only if it exists.
      Signed-off-by: NValentine Barshak <vbarshak@mvista.com>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      1a8e8fab
  17. 18 11月, 2010 1 次提交
  18. 15 10月, 2010 1 次提交
    • A
      llseek: automatically add .llseek fop · 6038f373
      Arnd Bergmann 提交于
      All file_operations should get a .llseek operation so we can make
      nonseekable_open the default for future file operations without a
      .llseek pointer.
      
      The three cases that we can automatically detect are no_llseek, seq_lseek
      and default_llseek. For cases where we can we can automatically prove that
      the file offset is always ignored, we use noop_llseek, which maintains
      the current behavior of not returning an error from a seek.
      
      New drivers should normally not use noop_llseek but instead use no_llseek
      and call nonseekable_open at open time.  Existing drivers can be converted
      to do the same when the maintainer knows for certain that no user code
      relies on calling seek on the device file.
      
      The generated code is often incorrectly indented and right now contains
      comments that clarify for each added line why a specific variant was
      chosen. In the version that gets submitted upstream, the comments will
      be gone and I will manually fix the indentation, because there does not
      seem to be a way to do that using coccinelle.
      
      Some amount of new code is currently sitting in linux-next that should get
      the same modifications, which I will do at the end of the merge window.
      
      Many thanks to Julia Lawall for helping me learn to write a semantic
      patch that does all this.
      
      ===== begin semantic patch =====
      // This adds an llseek= method to all file operations,
      // as a preparation for making no_llseek the default.
      //
      // The rules are
      // - use no_llseek explicitly if we do nonseekable_open
      // - use seq_lseek for sequential files
      // - use default_llseek if we know we access f_pos
      // - use noop_llseek if we know we don't access f_pos,
      //   but we still want to allow users to call lseek
      //
      @ open1 exists @
      identifier nested_open;
      @@
      nested_open(...)
      {
      <+...
      nonseekable_open(...)
      ...+>
      }
      
      @ open exists@
      identifier open_f;
      identifier i, f;
      identifier open1.nested_open;
      @@
      int open_f(struct inode *i, struct file *f)
      {
      <+...
      (
      nonseekable_open(...)
      |
      nested_open(...)
      )
      ...+>
      }
      
      @ read disable optional_qualifier exists @
      identifier read_f;
      identifier f, p, s, off;
      type ssize_t, size_t, loff_t;
      expression E;
      identifier func;
      @@
      ssize_t read_f(struct file *f, char *p, size_t s, loff_t *off)
      {
      <+...
      (
         *off = E
      |
         *off += E
      |
         func(..., off, ...)
      |
         E = *off
      )
      ...+>
      }
      
      @ read_no_fpos disable optional_qualifier exists @
      identifier read_f;
      identifier f, p, s, off;
      type ssize_t, size_t, loff_t;
      @@
      ssize_t read_f(struct file *f, char *p, size_t s, loff_t *off)
      {
      ... when != off
      }
      
      @ write @
      identifier write_f;
      identifier f, p, s, off;
      type ssize_t, size_t, loff_t;
      expression E;
      identifier func;
      @@
      ssize_t write_f(struct file *f, const char *p, size_t s, loff_t *off)
      {
      <+...
      (
        *off = E
      |
        *off += E
      |
        func(..., off, ...)
      |
        E = *off
      )
      ...+>
      }
      
      @ write_no_fpos @
      identifier write_f;
      identifier f, p, s, off;
      type ssize_t, size_t, loff_t;
      @@
      ssize_t write_f(struct file *f, const char *p, size_t s, loff_t *off)
      {
      ... when != off
      }
      
      @ fops0 @
      identifier fops;
      @@
      struct file_operations fops = {
       ...
      };
      
      @ has_llseek depends on fops0 @
      identifier fops0.fops;
      identifier llseek_f;
      @@
      struct file_operations fops = {
      ...
       .llseek = llseek_f,
      ...
      };
      
      @ has_read depends on fops0 @
      identifier fops0.fops;
      identifier read_f;
      @@
      struct file_operations fops = {
      ...
       .read = read_f,
      ...
      };
      
      @ has_write depends on fops0 @
      identifier fops0.fops;
      identifier write_f;
      @@
      struct file_operations fops = {
      ...
       .write = write_f,
      ...
      };
      
      @ has_open depends on fops0 @
      identifier fops0.fops;
      identifier open_f;
      @@
      struct file_operations fops = {
      ...
       .open = open_f,
      ...
      };
      
      // use no_llseek if we call nonseekable_open
      ////////////////////////////////////////////
      @ nonseekable1 depends on !has_llseek && has_open @
      identifier fops0.fops;
      identifier nso ~= "nonseekable_open";
      @@
      struct file_operations fops = {
      ...  .open = nso, ...
      +.llseek = no_llseek, /* nonseekable */
      };
      
      @ nonseekable2 depends on !has_llseek @
      identifier fops0.fops;
      identifier open.open_f;
      @@
      struct file_operations fops = {
      ...  .open = open_f, ...
      +.llseek = no_llseek, /* open uses nonseekable */
      };
      
      // use seq_lseek for sequential files
      /////////////////////////////////////
      @ seq depends on !has_llseek @
      identifier fops0.fops;
      identifier sr ~= "seq_read";
      @@
      struct file_operations fops = {
      ...  .read = sr, ...
      +.llseek = seq_lseek, /* we have seq_read */
      };
      
      // use default_llseek if there is a readdir
      ///////////////////////////////////////////
      @ fops1 depends on !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
      identifier fops0.fops;
      identifier readdir_e;
      @@
      // any other fop is used that changes pos
      struct file_operations fops = {
      ... .readdir = readdir_e, ...
      +.llseek = default_llseek, /* readdir is present */
      };
      
      // use default_llseek if at least one of read/write touches f_pos
      /////////////////////////////////////////////////////////////////
      @ fops2 depends on !fops1 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
      identifier fops0.fops;
      identifier read.read_f;
      @@
      // read fops use offset
      struct file_operations fops = {
      ... .read = read_f, ...
      +.llseek = default_llseek, /* read accesses f_pos */
      };
      
      @ fops3 depends on !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
      identifier fops0.fops;
      identifier write.write_f;
      @@
      // write fops use offset
      struct file_operations fops = {
      ... .write = write_f, ...
      +	.llseek = default_llseek, /* write accesses f_pos */
      };
      
      // Use noop_llseek if neither read nor write accesses f_pos
      ///////////////////////////////////////////////////////////
      
      @ fops4 depends on !fops1 && !fops2 && !fops3 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
      identifier fops0.fops;
      identifier read_no_fpos.read_f;
      identifier write_no_fpos.write_f;
      @@
      // write fops use offset
      struct file_operations fops = {
      ...
       .write = write_f,
       .read = read_f,
      ...
      +.llseek = noop_llseek, /* read and write both use no f_pos */
      };
      
      @ depends on has_write && !has_read && !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
      identifier fops0.fops;
      identifier write_no_fpos.write_f;
      @@
      struct file_operations fops = {
      ... .write = write_f, ...
      +.llseek = noop_llseek, /* write uses no f_pos */
      };
      
      @ depends on has_read && !has_write && !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
      identifier fops0.fops;
      identifier read_no_fpos.read_f;
      @@
      struct file_operations fops = {
      ... .read = read_f, ...
      +.llseek = noop_llseek, /* read uses no f_pos */
      };
      
      @ depends on !has_read && !has_write && !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
      identifier fops0.fops;
      @@
      struct file_operations fops = {
      ...
      +.llseek = noop_llseek, /* no read or write fn */
      };
      ===== End semantic patch =====
      Signed-off-by: NArnd Bergmann <arnd@arndb.de>
      Cc: Julia Lawall <julia@diku.dk>
      Cc: Christoph Hellwig <hch@infradead.org>
      6038f373
  19. 24 9月, 2010 1 次提交
  20. 14 9月, 2010 1 次提交
    • G
      HID: fix hiddev's use of usb_find_interface · 8fe294ca
      Guillaume Chazarain 提交于
      My macbook infrared remote control was broken by commit
      bd25f4dd ("HID: hiddev: use
      usb_find_interface, get rid of BKL").
      
      This device appears in dmesg as:
      apple 0003:05AC:8242.0001: hiddev0,hidraw0: USB HID v1.11 Device
      [Apple Computer, Inc. IR Receiver] on usb-0000:00:1d.2-1/input0
      
      It stopped working as lircd was getting ENODEV when opening /dev/usb/hiddev0.
      
      AFAICS hiddev_driver is a dummy driver so usb_find_interface(&hiddev_driver)
      does not find anything.
      
      The device is associated with the usbhid driver, so let's do
      usb_find_interface(&hid_driver) instead.
      
      $ ls -l /sys/devices/pci0000:00/0000:00:1d.2/usb7/7-1/7-1:1.0/usb/hiddev0/device/driver
      lrwxrwxrwx 1 root root 0 2010-09-12 16:28 /sys/devices/pci0000:00/0000:00:1d.2/usb7/7-1/7-1:1.0/usb/hiddev0/device/driver -> ../../../../../../bus/usb/drivers/usbhid
      Signed-off-by: NGuillaume Chazarain <guichaz@gmail.com>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      8fe294ca
  21. 13 8月, 2010 2 次提交
  22. 14 7月, 2010 1 次提交
    • A
      HID: hiddev: use usb_find_interface, get rid of BKL · bd25f4dd
      Arnd Bergmann 提交于
      This removes the private hiddev_table in the usbhid
      driver and changes it to use usb_find_interface
      instead.
      
      The advantage is that we can avoid the race between
      usb_register_dev and usb_open and no longer need the
      big kernel lock.
      
      This doesn't introduce race condition -- the intf pointer could be
      invalidated only in hiddev_disconnect() through usb_deregister_dev(),
      but that will block on minor_rwsem and not actually remove the device
      until usb_open().
      Signed-off-by: NArnd Bergmann <arnd@arndb.de>
      Cc: Jiri Kosina <jkosina@suse.cz>
      Cc: "Greg Kroah-Hartman" <gregkh@suse.de>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      bd25f4dd
  23. 30 3月, 2010 1 次提交
  24. 03 3月, 2010 1 次提交
  25. 06 11月, 2009 1 次提交
  26. 20 9月, 2009 1 次提交
  27. 20 8月, 2009 1 次提交
    • J
      HID: support larger reports than 64 bytes in hiddev · affbb8c6
      Jiri Kosina 提交于
      hiddev userspace driver uses a rignbuffer to store the parsed usages
      that should be returned through read(). This buffer is 64 bytes long,
      which is sufficient for queueing single USB 1.0 low-speed report, which
      is of maximum size 48 bytes.
      
      There are however USB HID devices which are full-speed USB devices, and
      therefore they are free to produce reports 64 bytes long. This is correctly
      handled by HID core, but read() on hiddev node gets stuck forever, because
      the ring buffer loops infinitely (as it is exactly 64 bytes long as well),
      never advancing the buffer pointer.
      
      Plus, the core driver is ready to handle highspeed devices, so we should be
      able to handle reports from such devices in the hiddev driver as well, which
      means we need larger ringbuffer.
      Reported-by: NMichael Zeisel <michael.zeisel@philips.com>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      affbb8c6
  28. 22 6月, 2009 1 次提交
  29. 16 6月, 2009 1 次提交
  30. 30 3月, 2009 1 次提交
    • O
      HID: fix race between usb_register_dev() and hiddev_open() · e43bd67d
      Oliver Neukum 提交于
      upon further thought this code is still racy.
      
      	retval = usb_register_dev(usbhid->intf, &hiddev_class);
      
      here you open a window during which open can happen
      
      	if (retval) {
      		err_hid("Not able to get a minor for this device.");
      		hid->hiddev = NULL;
      		kfree(hiddev);
      		return -1;
      	} else {
      		hid->minor = usbhid->intf->minor;
      		hiddev_table[usbhid->intf->minor - HIDDEV_MINOR_BASE] = hiddev;
      
      and will fail because hiddev_table hasn't been updated
      
      The obvious fix of using a mutex to guard hiddev_table doesn't work because
      usb_open() and usb_register_dev() take minor_rwsem and we'd have an AB-BA
      deadlock. We need a lock usb_open() also takes in the right order and that leaves
      only one option, BKL. I don't like it but I see no alternative.
      
      Once the usb_open() implements something better than lock_kernel(), we could also
      do so.
      Signed-off-by: NOliver Neukum <oneukum@suse.de>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      e43bd67d
  31. 26 3月, 2009 1 次提交
    • O
      HID: autosuspend support for USB HID · 0361a28d
      Oliver Neukum 提交于
      This uses the USB busy mechanism for aggessive autosuspend of USB
      HID devices. It autosuspends all opened devices supporting remote wakeup
      after a timeout unless
      
      - output is being done to the device
      - a key is being held down (remote wakeup isn't triggered upon key release)
      - LED(s) are lit
      - hiddev is opened
      
      As in the current driver closed devices will be autosuspended even if they
      don't support remote wakeup.
      
      The patch is quite large because output to devices is done in hard interrupt
      context meaning a lot a queuing and locking had to be touched. The LED stuff
      has been solved by means of a simple counter. Additions to the generic HID code
      could be avoided. In addition it now covers hidraw. It contains an embryonic
      version of an API to let the generic HID code tell the lower levels which
      capabilities with respect to power management are needed.
      Signed-off-by: NOliver Neukum <oneukum@suse.de>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      0361a28d
  32. 16 3月, 2009 1 次提交
    • J
      Rationalize fasync return values · 60aa4924
      Jonathan Corbet 提交于
      Most fasync implementations do something like:
      
           return fasync_helper(...);
      
      But fasync_helper() will return a positive value at times - a feature used
      in at least one place.  Thus, a number of other drivers do:
      
           err = fasync_helper(...);
           if (err < 0)
                   return err;
           return 0;
      
      In the interests of consistency and more concise code, it makes sense to
      map positive return values onto zero where ->fasync() is called.
      
      Cc: Al Viro <viro@ZenIV.linux.org.uk>
      Signed-off-by: NJonathan Corbet <corbet@lwn.net>
      60aa4924
  33. 11 3月, 2009 2 次提交
    • J
      HID: fix waitqueue usage in hiddev · 96fe2ab8
      Johannes Weiner 提交于
      DECLARE_WAITQUEUE doesn't initialize the wait descriptor's task_list
      to 'empty' but to zero.
      
      prepare_to_wait() will not enqueue the descriptor to the waitqueue and
      finish_wait() will do list_del_init() on a list head that contains
      NULL pointers, which oopses.
      
      This was introduced by 07903407 "HID: hiddev cleanup -- handle all
      error conditions properly".
      
      The prior code used an unconditional add_to_waitqueue() which didn't
      care about the wait descriptor's list head and enqueued the thing
      unconditionally.
      
      The new code uses prepare_to_wait() which DOES check the prior list
      state, so use DEFINE_WAIT instead.
      Signed-off-by: NJohannes Weiner <hannes@cmpxchg.org>
      Cc: Oliver Neukum <oliver@neukum.name>
      Cc: Jiri Kosina <jkosina@suse.cz>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      96fe2ab8
    • J
      HID: fix incorrect free in hiddev · 48e7a3c9
      Johannes Weiner 提交于
      If hiddev_open() fails, it wrongly frees the shared hiddev structure
      kept in hiddev_table instead of the hiddev_list structure allocated
      for the opened file descriptor.  Existing references to this structure
      will then accessed free memory.
      
      This was introduced by 07903407 "HID: hiddev cleanup -- handle all
      error conditions properly".
      Signed-off-by: NJohannes Weiner <hannes@cmpxchg.org>
      Cc: Oliver Neukum <oliver@neukum.name>
      Cc: Jiri Kosina <jkosina@suse.cz>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      48e7a3c9
  34. 29 1月, 2009 1 次提交
  35. 08 1月, 2009 1 次提交
  36. 04 1月, 2009 1 次提交
    • O
      HID: hiddev cleanup -- handle all error conditions properly · 07903407
      Oliver Neukum 提交于
      This is a cleanup of hiddev and fixes the following issues:
      
      - thread safety by locking in read & ioctl, introducing a per device mutex
      - race between ioctl and disconnect, introducing a flag and locking
        in form of a per low level device mutex
      - race between open and other methods, making sure only successfully
        opened devices are put on the list, changing order of events
      - range checking both upper and lower limits of the minor range
      - make sure further calls to open fail for unplugged devices even if
        the device still has opened files
      - error checking for low level open
      - possible loss of wakeup events, using standard waiting macros
      - race in initialisation by moving registration after full initialisation
      Signed-off-by: NOliver Neukum <oneukum@suse.de>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      07903407