1. 29 8月, 2013 1 次提交
    • K
      HID: validate HID report id size · 43622021
      Kees Cook 提交于
      The "Report ID" field of a HID report is used to build indexes of
      reports. The kernel's index of these is limited to 256 entries, so any
      malicious device that sets a Report ID greater than 255 will trigger
      memory corruption on the host:
      
      [ 1347.156239] BUG: unable to handle kernel paging request at ffff88094958a878
      [ 1347.156261] IP: [<ffffffff813e4da0>] hid_register_report+0x2a/0x8b
      
      CVE-2013-2888
      Signed-off-by: NKees Cook <keescook@chromium.org>
      Cc: stable@kernel.org
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      43622021
  2. 22 7月, 2013 1 次提交
    • J
      HID: fix data access in implement() · 27ce4050
      Jiri Kosina 提交于
      implement() is setting bytes in LE data stream. In case the data is not
      aligned to 64bits, it reads past the allocated buffer. It doesn't really
      change any value there (it's properly bitmasked), but in case that this
      read past the boundary hits a page boundary, pagefault happens when
      accessing 64bits of 'x' in implement(), and kernel oopses.
      
      This happens much more often when numbered reports are in use, as the
      initial 8bit skip in the buffer makes the whole process work on values
      which are not aligned to 64bits.
      
      This problem dates back to attempts in 2005 and 2006 to make implement()
      and extract() as generic as possible, and even back then the problem
      was realized by Adam Kroperlin, but falsely assumed to be impossible
      to cause any harm:
      
        http://www.mail-archive.com/linux-usb-devel@lists.sourceforge.net/msg47690.html
      
      I have made several attempts at fixing it "on the spot" directly in
      implement(), but the results were horrible; the special casing for processing
      last 64bit chunk and switching to different math makes it unreadable mess.
      
      I therefore took a path to allocate a few bytes more which will never make
      it into final report, but are there as a cushion for all the 64bit math
      operations happening in implement() and extract().
      
      All callers of hid_output_report() are converted at the same time to allocate
      the buffer by newly introduced hid_alloc_report_buf() helper.
      
      Bruno noticed that the whole raw_size test can be dropped as well, as
      hid_alloc_report_buf() makes sure that the buffer is always of a proper
      size.
      Reviewed-by: NBenjamin Tissoires <benjamin.tissoires@redhat.com>
      Acked-by: NGustavo Padovan <gustavo.padovan@collabora.co.uk>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      27ce4050
  3. 06 5月, 2013 1 次提交
    • J
      HID: debug: fix RCU preemption issue · 1deb9d34
      Jiri Kosina 提交于
      Commit 2353f2be ("HID: protect hid_debug_list") introduced mutex
      locking around debug_list access to prevent SMP races when debugfs
      nodes are being operated upon by multiple userspace processess.
      
      mutex is not a proper synchronization primitive though, as the hid-debug
      callbacks are being called from atomic contexts.
      
      We also have to be careful about disabling IRQs when taking the lock
      to prevent deadlock against IRQ handlers.
      
      Benjamin reports this has also been reported in RH bugzilla as bug #958935.
      
       ===============================
       [ INFO: suspicious RCU usage. ]
       3.9.0+ #94 Not tainted
       -------------------------------
       include/linux/rcupdate.h:476 Illegal context switch in RCU read-side critical section!
      
       other info that might help us debug this:
      
       rcu_scheduler_active = 1, debug_locks = 0
       4 locks held by Xorg/5502:
        #0:  (&evdev->mutex){+.+...}, at: [<ffffffff81512c3d>] evdev_write+0x6d/0x160
        #1:  (&(&dev->event_lock)->rlock#2){-.-...}, at: [<ffffffff8150dd9b>] input_inject_event+0x5b/0x230
        #2:  (rcu_read_lock){.+.+..}, at: [<ffffffff8150dd82>] input_inject_event+0x42/0x230
        #3:  (&(&usbhid->lock)->rlock){-.....}, at: [<ffffffff81565289>] usb_hidinput_input_event+0x89/0x120
      
       stack backtrace:
       CPU: 0 PID: 5502 Comm: Xorg Not tainted 3.9.0+ #94
       Hardware name: Dell Inc. OptiPlex 390/0M5DCD, BIOS A09 07/24/2012
        0000000000000001 ffff8800689c7c38 ffffffff816f249f ffff8800689c7c68
        ffffffff810acb1d 0000000000000000 ffffffff81a03ac7 000000000000019d
        0000000000000000 ffff8800689c7c90 ffffffff8107cda7 0000000000000000
       Call Trace:
        [<ffffffff816f249f>] dump_stack+0x19/0x1b
        [<ffffffff810acb1d>] lockdep_rcu_suspicious+0xfd/0x130
        [<ffffffff8107cda7>] __might_sleep+0xc7/0x230
        [<ffffffff816f7770>] mutex_lock_nested+0x40/0x3a0
        [<ffffffff81312ac4>] ? vsnprintf+0x354/0x640
        [<ffffffff81553cc4>] hid_debug_event+0x34/0x100
        [<ffffffff81554197>] hid_dump_input+0x67/0xa0
        [<ffffffff81556430>] hid_set_field+0x50/0x120
        [<ffffffff8156529a>] usb_hidinput_input_event+0x9a/0x120
        [<ffffffff8150d89e>] input_handle_event+0x8e/0x530
        [<ffffffff8150df10>] input_inject_event+0x1d0/0x230
        [<ffffffff8150dd82>] ? input_inject_event+0x42/0x230
        [<ffffffff81512cae>] evdev_write+0xde/0x160
        [<ffffffff81185038>] vfs_write+0xc8/0x1f0
        [<ffffffff81185535>] SyS_write+0x55/0xa0
        [<ffffffff81704482>] system_call_fastpath+0x16/0x1b
       BUG: sleeping function called from invalid context at kernel/mutex.c:413
       in_atomic(): 1, irqs_disabled(): 1, pid: 5502, name: Xorg
       INFO: lockdep is turned off.
       irq event stamp: 1098574
       hardirqs last  enabled at (1098573): [<ffffffff816fb53f>] _raw_spin_unlock_irqrestore+0x3f/0x70
       hardirqs last disabled at (1098574): [<ffffffff816faaf5>] _raw_spin_lock_irqsave+0x25/0xa0
       softirqs last  enabled at (1098306): [<ffffffff8104971f>] __do_softirq+0x18f/0x3c0
       softirqs last disabled at (1097867): [<ffffffff81049ad5>] irq_exit+0xa5/0xb0
       CPU: 0 PID: 5502 Comm: Xorg Not tainted 3.9.0+ #94
       Hardware name: Dell Inc. OptiPlex 390/0M5DCD, BIOS A09 07/24/2012
        ffffffff81a03ac7 ffff8800689c7c68 ffffffff816f249f ffff8800689c7c90
        ffffffff8107ce60 0000000000000000 ffff8800689c7fd8 ffff88006a62c800
        ffff8800689c7d10 ffffffff816f7770 ffff8800689c7d00 ffffffff81312ac4
       Call Trace:
        [<ffffffff816f249f>] dump_stack+0x19/0x1b
        [<ffffffff8107ce60>] __might_sleep+0x180/0x230
        [<ffffffff816f7770>] mutex_lock_nested+0x40/0x3a0
        [<ffffffff81312ac4>] ? vsnprintf+0x354/0x640
        [<ffffffff81553cc4>] hid_debug_event+0x34/0x100
        [<ffffffff81554197>] hid_dump_input+0x67/0xa0
        [<ffffffff81556430>] hid_set_field+0x50/0x120
        [<ffffffff8156529a>] usb_hidinput_input_event+0x9a/0x120
        [<ffffffff8150d89e>] input_handle_event+0x8e/0x530
        [<ffffffff8150df10>] input_inject_event+0x1d0/0x230
        [<ffffffff8150dd82>] ? input_inject_event+0x42/0x230
        [<ffffffff81512cae>] evdev_write+0xde/0x160
        [<ffffffff81185038>] vfs_write+0xc8/0x1f0
        [<ffffffff81185535>] SyS_write+0x55/0xa0
        [<ffffffff81704482>] system_call_fastpath+0x16/0x1b
      Reported-by: Nmajianpeng <majianpeng@gmail.com>
      Reported-by: NBenjamin Tissoires <benjamin.tissoires@gmail.com>
      Reviewed-by: NDmitry Torokhov <dmitry.torokhov@gmail.com>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      1deb9d34
  4. 30 4月, 2013 1 次提交
    • J
      HID: protect hid_debug_list · 2353f2be
      Jiri Kosina 提交于
      Accesses to hid_device->hid_debug_list are not serialized properly, which
      could result in SMP concurrency issues when HID debugfs events are accessesed
      by multiple userspace processess.
      
      Serialize all the list operations by a mutex.
      
      Spotted by Al Viro.
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      2353f2be
  5. 27 3月, 2013 1 次提交
  6. 07 3月, 2013 1 次提交
  7. 01 3月, 2013 1 次提交
    • A
      HID: Separate struct hid_device's driver_lock into two locks. · c849a614
      Andrew de los Reyes 提交于
      This patch separates struct hid_device's driver_lock into two. The
      goal is to allow hid device drivers to receive input during their
      probe() or remove() function calls. This is necessary because some
      drivers need to communicate with the device to determine parameters
      needed during probe (e.g., size of a multi-touch surface), and if
      possible, may perfer to communicate with a device on host-initiated
      disconnect (e.g., to put it into a low-power state).
      
      Historically, three functions used driver_lock:
      
      - hid_device_probe: blocks to acquire lock
      - hid_device_remove: blocks to acquire lock
      - hid_input_report: if locked returns -EBUSY, else acquires lock
      
      This patch adds another lock (driver_input_lock) which is used to
      block input from occurring. The lock behavior is now:
      
      - hid_device_probe: blocks to acq. driver_lock, then driver_input_lock
      - hid_device_remove: blocks to acq. driver_lock, then driver_input_lock
      - hid_input_report: if driver_input_lock locked returns -EBUSY, else
        acquires driver_input_lock
      
      This patch also adds two helper functions to be called during probe()
      or remove(): hid_device_io_start() and hid_device_io_stop(). These
      functions lock and unlock, respectively, driver_input_lock; they also
      make a note of whether they did so that hid-core knows if a driver has
      changed the lock state.
      
      This patch results in no behavior change for existing devices and
      drivers. However, during a probe() or remove() function call in a
      driver, that driver may now selectively call hid_device_io_start() to
      let input events come through, then optionally call
      hid_device_io_stop() to stop them.
      Signed-off-by: NAndrew de los Reyes <adlr@chromium.org>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      c849a614
  8. 25 2月, 2013 2 次提交
  9. 05 2月, 2013 1 次提交
  10. 03 1月, 2013 2 次提交
  11. 12 12月, 2012 1 次提交
  12. 07 12月, 2012 1 次提交
  13. 15 11月, 2012 3 次提交
  14. 13 10月, 2012 1 次提交
  15. 20 9月, 2012 2 次提交
  16. 09 7月, 2012 1 次提交
  17. 01 5月, 2012 5 次提交
  18. 28 4月, 2012 1 次提交
  19. 08 1月, 2012 4 次提交
    • J
      hid-input/battery: remove battery_val · ce63920b
      Jeremy Fitzhardinge 提交于
      hidinput_get_battery_property() now directly polls the device for the
      current battery strength, so there's no need for battery_val, or the
      code to set it on the input event path.
      Signed-off-by: NJeremy Fitzhardinge <jeremy@goop.org>
      ce63920b
    • J
      hid-input/battery: deal with both FEATURE and INPUT report batteries · fb8ac91b
      Jeremy Fitzhardinge 提交于
      Some devices seem to report batteries as FEATUREs, others as INPUTs.
      Signed-off-by: NJeremy Fitzhardinge <jeremy@goop.org>
      fb8ac91b
    • J
      hid-input/battery: add quirks for battery · bbc21cfd
      Jeremy Fitzhardinge 提交于
      Some devices always report percentage, despite having 0/255 as their
      min/max, so add a quirk for them.
      Signed-off-by: NJeremy Fitzhardinge <jeremy@goop.org>
      bbc21cfd
    • D
      hid-input: add support for HID devices reporting Battery Strength · c5a92aa3
      Daniel Nicoletti 提交于
      I've sent an email earlier asking for help with a GetFeature code, and now I
      have a second patch on top of Jeremy's to provide the battery functionality
      for devices that support reporting it.
      
      If I understood correctly when talking to Jeremy he said his device
      never actually reported the status as an input event (sorry if I didn't
      understand it correctly), and after reading HID specs I believe it's
      really because it was meant to be probed, I have an Apple Keyboard and
      Magic Trackpad both bluetooth batteries operated, so using PacketLogger
      I saw that Mac OSX always ask the battery status using the so called
      GetFeature.
      
      What my patch does is basically:
      - store the report id that matches the battery_strength
      - setup the battery if 0x6.0x20 is found, even if that is reported as a feature
        (as it was meant to be but only the MagicTrackpad does)
      - when upower or someone access /sys/class/power_supply/hid-*/capacity it
        will probe the device and return it's status.
      
      It works great for both devices, but I have two concerns:
      - the report_features function has a duplicated code
      - it would be nice if it was possible for specific drivers to provide their own
        probe as there might be some strange devices... (but maybe it's
      already possible)
      
      I've talked to the upower dev and he fixed it to be able to show the
      right percentage.
      
      Here how the uevent file (in /sys/class/power_supply/hid-*/) looks like:
      POWER_SUPPLY_NAME=hid-00:22:41:D9:18:E7-battery
      POWER_SUPPLY_PRESENT=1
      POWER_SUPPLY_ONLINE=1
      POWER_SUPPLY_CAPACITY=66
      POWER_SUPPLY_MODEL_NAME=MacAdmin’s keyboard
      POWER_SUPPLY_STATUS=Discharging
      
      POWER_SUPPLY_NAME=hid-70:CD:60:F5:FF:3F-battery
      POWER_SUPPLY_PRESENT=1
      POWER_SUPPLY_ONLINE=1
      POWER_SUPPLY_CAPACITY=62
      POWER_SUPPLY_MODEL_NAME=nexx’s Trackpad
      POWER_SUPPLY_STATUS=Discharging
      Signed-off-by: NDaniel Nicoletti <dantti12@gmail.com>
      c5a92aa3
  20. 21 12月, 2011 1 次提交
  21. 28 11月, 2011 1 次提交
    • J
      HID: hid-input: add support for HID devices reporting Battery Strength · 4f5ca836
      Jeremy Fitzhardinge 提交于
      Some HID devices, such as my Bluetooth mouse, report their battery
      strength as an event.  Rather than passing it through as a strange
      absolute input event, this patch registers it with the power_supply
      subsystem as a battery, so that the device's Battery Strength can be
      reported to usermode.
      
      The battery appears in sysfs names
      /sys/class/power_supply/hid-<UNIQ>-battery, and it is a child of the
      battery-containing device, so it should be clear what it's the battery of.
      
      Unfortunately on my current Fedora 16 system, while the battery does
      appear in the UI, it is listed as a Laptop Battery with 0% charge (since
      it ignores the "capacity" property of the battery and instead computes
      it from the "energy*" fields, which we can't supply given the limited
      information contained within the HID Report).
      
      Still, this patch is the first step.
      Signed-off-by: NJeremy Fitzhardinge <jeremy@goop.org>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      4f5ca836
  22. 01 11月, 2011 1 次提交
    • P
      include: convert various register fcns to macros to avoid include chaining · eb5589a8
      Paul Gortmaker 提交于
      The original implementations reference THIS_MODULE in an inline.
      We could include <linux/export.h>, but it is better to avoid chaining.
      
      Fortunately someone else already thought of this, and made a similar
      inline into a #define in <linux/device.h> for device_schedule_callback(),
      [see commit 523ded71] so follow that precedent here.
      
      Also bubble up any __must_check that were used on the prev. wrapper inline
      functions up one to the real __register functions, to preserve any prev.
      sanity checks that were used in those instances.
      Signed-off-by: NPaul Gortmaker <paul.gortmaker@windriver.com>
      eb5589a8
  23. 26 9月, 2011 1 次提交
  24. 10 8月, 2011 1 次提交
    • D
      HID: Fix race condition between driver core and ll-driver · 4ea54542
      David Herrmann 提交于
      HID low level drivers register new devices with the HID core which then
      adds the devices to the HID bus. The HID bus normally immediately probes
      an appropriate driver which then handles HID input for this device.
      The ll driver now uses the hid_input_report() function to report input
      events for a specific device. However, if the HID bus unloads the driver
      at the same time (for instance via a call to
       /sys/bus/hid/devices/<dev>/unbind) then the hdev->driver pointer may be
      used by hid_input_report() and hid_device_remove() at the same time
      which may cause hdev->driver to point to invalid memory.
      
      This fix adds a semaphore to every hid device which protects
      hdev->driver from asynchronous access. This semaphore is locked during
      driver *_probe and *_remove and also inside hid_input_report(). The
      *_probe and *_remove functions may sleep so the semaphore is good here,
      however, hid_input_report() is in atomic context and hence only uses
      down_trylock(). If it cannot acquire the lock it simply drops the input
      package.
      
      The low-level drivers report input events synchronously so
      hid_input_report() should never be entered twice at the same time on the
      same device. Hence, the lock should always be available. But if the
      driver is currently probed/removed then the lock is not available and
      dropping the package should be safe because this is what would have
      happened if the package arrived some milliseconds earlier/later.
      
      This also fixes another race condition while probing drivers:
      First the *_probe function of the driver is called and only if that
      succeeds, the related input device of hidinput is registered. If the low
      level driver reports input events after the *_probe function returned
      but before the input device is registered, then a NULL pointer
      dereference will occur. (Equivalently on driver remove function).
      This is not possible anymore, since the semaphore lock drops all
      incoming packages until the driver/device is fully initialized.
      Signed-off-by: NDavid Herrmann <dh.herrmann@googlemail.com>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      4ea54542
  25. 07 6月, 2011 1 次提交
    • T
      HID: yurex: recognize GeneralKeys wireless presenter as generic HID · 6dc1418e
      Tomoki Sekiyama 提交于
      Unfortunately, the device seems to have the same Vendor ID and Product ID
      as YUREX leg-shakes sensors, and the commit 6bc235a2 ("USB: add driver
      for Meywa-Denki & Kayac YUREX") added the ID to hid_ignore_list.
      
      I believe that we can distinguish YUREX and the Wireless Presenter by
      device type.  The patch below makes the driver ignore only YUREX
      (bInterfaceProtocol==0), and recognize Wireless Presenter
      (bInterfaceProtocol is keyboard or mouse) as generic HID.  (I don't have
      the Wireless Presenter, so not yet ested.)
      
      ** YUREX lsusb information:
      Bus 002 Device 007: ID 0c45:1010 Microdia
      Device Descriptor:
         bLength                18
         bDescriptorType         1
         bcdUSB               1.10
         bDeviceClass            0 (Defined at Interface level)
         bDeviceSubClass         0
         bDeviceProtocol         0
         bMaxPacketSize0         8
         idVendor           0x0c45 Microdia
         idProduct          0x1010
         bcdDevice            0.03
         iManufacturer           1 JESS
         iProduct                2 YUREX
         iSerial                 3 10000269
         bNumConfigurations      1
         Configuration Descriptor:
           bLength                 9
           bDescriptorType         2
           wTotalLength           34
           bNumInterfaces          1
           bConfigurationValue     1
           iConfiguration          0
           bmAttributes         0xa0
             (Bus Powered)
             Remote Wakeup
           MaxPower              100mA
           Interface Descriptor:
             bLength                 9
             bDescriptorType         4
             bInterfaceNumber        0
             bAlternateSetting       0
             bNumEndpoints           1
             bInterfaceClass         3 Human Interface Device
             bInterfaceSubClass      1 Boot Interface Subclass
             bInterfaceProtocol      0 None
             iInterface              0
               HID Device Descriptor:
                 bLength                 9
                 bDescriptorType        33
                 bcdHID               1.10
                 bCountryCode            0 Not supported
                 bNumDescriptors         1
                 bDescriptorType        34 Report
                 wDescriptorLength      31
                Report Descriptors:
                  ** UNAVAILABLE **
             Endpoint Descriptor:
               bLength                 7
               bDescriptorType         5
               bEndpointAddress     0x81  EP 1 IN
               bmAttributes            3
                 Transfer Type            Interrupt
                 Synch Type               None
                 Usage Type               Data
               wMaxPacketSize     0x0008  1x 8 bytes
               bInterval              10
      Device Status:     0x0002
         (Bus Powered)
         Remote Wakeup Enabled
      
      Addresses https://bugzilla.kernel.org/show_bug.cgi?id=26922Signed-off-by: NTomoki Sekiyama <tomoki.sekiyama@gmail.com>
      Cc: Greg KH <gregkh@suse.de>
      Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
      Cc: Maciej Rutecki <maciej.rutecki@gmail.com>
      Reported-by: NThomas B?chler <thomas@archlinux.org>
      Tested-by: NThomas B?chler <thomas@archlinux.org>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NJiri Kosina <jkosina@suse.cz>
      6dc1418e
  26. 31 3月, 2011 1 次提交
  27. 02 3月, 2011 1 次提交
  28. 11 2月, 2011 1 次提交