13 Sep, 2013

1 commit

  • Many drivers need to validate the characteristics of their HID report
    during initialization to avoid misusing the reports. This adds a common
    helper to perform validation of the report exisitng, the field existing,
    and the expected number of values within the field.

    Signed-off-by: Kees Cook
    Cc: stable@vger.kernel.org
    Reviewed-by: Benjamin Tissoires
    Signed-off-by: Jiri Kosina

    Kees Cook
     

06 Sep, 2013

1 commit


04 Sep, 2013

2 commits


29 Aug, 2013

1 commit

  • 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: [] hid_register_report+0x2a/0x8b

    CVE-2013-2888

    Signed-off-by: Kees Cook
    Cc: stable@kernel.org
    Signed-off-by: Jiri Kosina

    Kees Cook
     

27 Aug, 2013

2 commits

  • Some multitouch screens do not like to be polled for input reports.
    However, the Win8 spec says that all touches should be sent during
    each report, making the initialization of reports unnecessary.
    The Win7 spec is less precise, so do not use this for those devices.

    Add the quirk HID_QUIRK_NO_INIT_INPUT_REPORTS so that we do not have to
    introduce a quirk for each problematic device. This quirk makes the driver
    behave the same way the Win 8 does. It actually retrieves the features,
    but not the inputs.

    Signed-off-by: Benjamin Tissoires
    Reviewed-by: Henrik Rydberg
    Tested-by: Srinivas Pandruvada
    Signed-off-by: Jiri Kosina

    Benjamin Tissoires
     
  • Detecting Win 8 multitouch devices in core allows us to set quirks
    before the device is parsed through hid_hw_start().
    It also simplifies the detection of those devices in hid-multitouch and
    makes the handling of those devices cleaner.

    As Win 8 multitouch panels are in the group multitouch and rely on a
    special feature to be detected, this patch adds a bitfield in the parser.

    Signed-off-by: Benjamin Tissoires
    Reviewed-by: Henrik Rydberg
    Tested-by: Srinivas Pandruvada
    Signed-off-by: Jiri Kosina

    Benjamin Tissoires
     

31 Jul, 2013

2 commits

  • The hidinput_input_event() callback converts input events written from
    userspace into HID reports and sends them to the device. We currently
    implement this in every HID transport driver, even though most of them do
    the same.

    This provides a generic hidinput_input_event() implementation which is
    mostly copied from usbhid. It uses a delayed worker to allow multiple LED
    events to be collected into a single output event.
    We use the custom ->request() transport driver callback to allow drivers
    to adjust the outgoing report and handle the request asynchronously. If no
    custom ->request() callback is available, we fall back to the generic raw
    output report handler (which is synchronous).

    Drivers can still provide custom hidinput_input_event() handlers (see
    logitech-dj) if the generic implementation doesn't fit their needs.

    Signed-off-by: David Herrmann
    Signed-off-by: Jiri Kosina

    David Herrmann
     
  • usbhid_set_leds() is only used inside of usbhid/hid-core.c so no need to
    export it.

    Signed-off-by: David Herrmann
    Reviewed-by: Benjamin Tissoires
    Signed-off-by: Jiri Kosina

    David Herrmann
     

22 Jul, 2013

1 commit

  • 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: Benjamin Tissoires
    Acked-by: Gustavo Padovan
    Signed-off-by: Jiri Kosina

    Jiri Kosina
     

06 May, 2013

1 commit

  • Commit 2353f2bea ("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: [] evdev_write+0x6d/0x160
    #1: (&(&dev->event_lock)->rlock#2){-.-...}, at: [] input_inject_event+0x5b/0x230
    #2: (rcu_read_lock){.+.+..}, at: [] input_inject_event+0x42/0x230
    #3: (&(&usbhid->lock)->rlock){-.....}, at: [] 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:
    [] dump_stack+0x19/0x1b
    [] lockdep_rcu_suspicious+0xfd/0x130
    [] __might_sleep+0xc7/0x230
    [] mutex_lock_nested+0x40/0x3a0
    [] ? vsnprintf+0x354/0x640
    [] hid_debug_event+0x34/0x100
    [] hid_dump_input+0x67/0xa0
    [] hid_set_field+0x50/0x120
    [] usb_hidinput_input_event+0x9a/0x120
    [] input_handle_event+0x8e/0x530
    [] input_inject_event+0x1d0/0x230
    [] ? input_inject_event+0x42/0x230
    [] evdev_write+0xde/0x160
    [] vfs_write+0xc8/0x1f0
    [] SyS_write+0x55/0xa0
    [] 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): [] _raw_spin_unlock_irqrestore+0x3f/0x70
    hardirqs last disabled at (1098574): [] _raw_spin_lock_irqsave+0x25/0xa0
    softirqs last enabled at (1098306): [] __do_softirq+0x18f/0x3c0
    softirqs last disabled at (1097867): [] 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:
    [] dump_stack+0x19/0x1b
    [] __might_sleep+0x180/0x230
    [] mutex_lock_nested+0x40/0x3a0
    [] ? vsnprintf+0x354/0x640
    [] hid_debug_event+0x34/0x100
    [] hid_dump_input+0x67/0xa0
    [] hid_set_field+0x50/0x120
    [] usb_hidinput_input_event+0x9a/0x120
    [] input_handle_event+0x8e/0x530
    [] input_inject_event+0x1d0/0x230
    [] ? input_inject_event+0x42/0x230
    [] evdev_write+0xde/0x160
    [] vfs_write+0xc8/0x1f0
    [] SyS_write+0x55/0xa0
    [] system_call_fastpath+0x16/0x1b

    Reported-by: majianpeng
    Reported-by: Benjamin Tissoires
    Reviewed-by: Dmitry Torokhov
    Signed-off-by: Jiri Kosina

    Jiri Kosina
     

30 Apr, 2013

3 commits


27 Mar, 2013

1 commit

  • There is no need to register an input device containing no events.
    This allows drivers using the quirk MULTI_INPUT to register one input
    per report effectively used.

    For backward compatibility, we need to add a quirk to request
    this behavior.

    Signed-off-by: Benjamin Tissoires
    Signed-off-by: Jiri Kosina

    Benjamin Tissoires
     

07 Mar, 2013

1 commit

  • Some drivers send the idle command directly to underlying device,
    creating an unwanted dependency on the underlying transport layer.
    This patch adds hid_hw_idle() to the interface, thereby removing
    usbhid from the lion share of the drivers.

    Signed-off-by: Benjamin Tissoires
    Reviewed-by: David Herrmann
    Signed-off-by: Jiri Kosina

    Benjamin Tissoires
     

01 Mar, 2013

1 commit

  • 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: Andrew de los Reyes
    Signed-off-by: Jiri Kosina

    Andrew de los Reyes
     

25 Feb, 2013

2 commits

  • Some drivers need to wait for an io from the underlying device, creating
    an unwanted dependency on the underlying transport layer. This patch adds
    wait() to the interface, thereby removing usbhid from the lion share of
    the drivers.

    Signed-off-by: Henrik Rydberg
    Signed-off-by: Benjamin Tissoires
    Reviewed-by: Mika Westerberg
    Signed-off-by: Jiri Kosina

    Henrik Rydberg
     
  • Some drivers send reports directly to underlying device, creating an
    unwanted dependency on the underlying transport layer. This patch adds
    hid_hw_request() to the interface, thereby removing usbhid from the
    lion share of the drivers.

    Signed-off-by: Henrik Rydberg
    Signed-off-by: Benjamin Tissoires
    Reviewed-by: Mika Westerberg
    Signed-off-by: Jiri Kosina

    Henrik Rydberg
     

21 Feb, 2013

1 commit


05 Feb, 2013

1 commit


03 Jan, 2013

2 commits


13 Dec, 2012

1 commit


12 Dec, 2012

1 commit

  • It should not be necessary to add IDs for HID sensor hubs to lists in
    hid-core.c and hid-sensor-hub.c. So instead of a whitelist, autodetect such USB
    HID sensor hubs, based on a collection of type physical inside a useage page of
    type sensor. If some sensor hubs stil must be usable as raw devices, a
    blacklist might be created.

    Signed-off-by: Alexander Holler
    Acked-by: "Pandruvada, Srinivas"
    Signed-off-by: Jiri Kosina

    Alexander Holler
     

07 Dec, 2012

1 commit

  • This patch against kernel 3.7.0-rc8 fixes a kernel oops when turning on the
    bluetooth mouse with id 0458:0058 [1].

    The mouse in question supports both input and hid sessions, however it is
    blacklisted in drivers/hid/hid-core.c so the input session is one that should
    be used. Long ago (around kernel 3.0.0) some changes in the bluetooth
    subsystem made the kernel do not fallback to input session when hid session is
    not supported or blacklisted. This patch restore that behaviour by making the
    kernel try the input session if hid_add_device returns ENODEV.

    The patch exports hid_ignore() from hid-core.c so that it can be used in the
    bluetooth subsystem.

    [1] https://bugzilla.kernel.org/show_bug.cgi?id=39882

    Signed-off-by: Lamarque V. Souza
    Acked-by: Gustavo Padovan
    Signed-off-by: Jiri Kosina

    Lamarque V. Souza
     

15 Nov, 2012

3 commits

  • Currently, there is no way to know the index of the current field
    in the .input_mapping and .event callbacks when this field is inside
    an array of HID fields.
    This patch adds this index to the struct hid_usage so that this
    information is available to input_mapping and event callbacks.

    Signed-off-by: Benjamin Tissoires
    Acked-by: Jiri Kosina
    Signed-off-by: Jiri Kosina

    Benjamin Tissoires
     
  • HID spec details special values for the HID field unit exponent.
    Basically, the range [0x8..0xf] correspond to [-8..-1], so this is
    a standard two's complement on a half-byte.

    Signed-off-by: Benjamin Tissoires
    Acked-by: Jiri Kosina
    Signed-off-by: Jiri Kosina

    Benjamin Tissoires
     
  • Exporting the function allows us to calculate the resolution in third
    party drivers like hid-multitouch.
    This patch also complete the function with additional valid axes.

    Signed-off-by: Benjamin Tissoires
    Acked-by: Jiri Kosina
    Signed-off-by: Jiri Kosina

    Benjamin Tissoires
     

13 Oct, 2012

1 commit


20 Sep, 2012

2 commits

  • Some recent hardware define more than 128 fields in the report
    descriptor. Increase the limit to 256. This adds another kilobyte of
    memory per report.

    Tested-by: Ping Cheng
    Acked-by: Jiri Kosina
    Signed-off-by: Henrik Rydberg

    Henrik Rydberg
     
  • A hid device may create several input devices, and a driver may need
    to prepare or finalize the configuration per input device. Currently,
    there is no sane way for a driver to know when a device has been
    configured. This patch adds a callback providing that information.

    Reviewed-and-tested-by: Benjamin Tissoires
    Tested-by: Ping Cheng
    Acked-by: Jiri Kosina
    Signed-off-by: Henrik Rydberg

    Henrik Rydberg
     

09 Jul, 2012

1 commit


22 May, 2012

1 commit


01 May, 2012

5 commits

  • Switch the driver over to device group handling. By adding the
    HID_GROUP_MULTITOUCH group to hid-core, hid-generic will no longer
    match multitouch devices. By adding the HID_GROUP_MULTITOUCH entry to
    the device list, hid-multitouch will match all unknown multitouch
    devices, and udev will automatically load the module.

    Since HID_QUIRK_MULTITOUCH never gets set, the special quirks handling
    can be removed. Since all HID MT devices have HID_DG_CONTACTID, they
    can be removed from the hid_have_special_driver list.

    With this patch, the unknown device ids are no longer NULL, so the code
    is modified to check for the generic entry instead.

    Signed-off-by: Henrik Rydberg
    Acked-by: Benjamin Tissoires
    Signed-off-by: Jiri Kosina

    Henrik Rydberg
     
  • Devices that do not have a special driver are handled by the generic
    driver. This patch does the same thing using device groups; Instead of
    forcing a particular driver, the appropriate driver is picked up by
    udev. As a consequence, one can now move a device from generic to
    specific handling by a simple rebind. By adding a new device id to the
    generic driver, the same thing can be done in reverse.

    Signed-off-by: Henrik Rydberg
    Acked-by: Benjamin Tissoires
    Signed-off-by: Jiri Kosina

    Henrik Rydberg
     
  • In order to allow the report descriptor to influence the hid device
    properties, one needs to parse the descriptor early, without reference
    to any driver. Scan the descriptor for group information during device
    add, before the device has been broadcast to userland. The device
    modalias will contain group information which can be used to
    differentiate between modules. For starters, just handle the generic
    group.

    Signed-off-by: Henrik Rydberg
    Acked-by: Benjamin Tissoires
    Signed-off-by: Jiri Kosina

    Henrik Rydberg
     
  • HID devices are only partially presented to userland. Hotplugged
    devices emit events containing a modalias based on the basic bus,
    vendor and product entities. However, in practise a hid device can
    depend on details such as a single usb interface or a particular item
    in a report descriptor.

    This patch adds a device group to the hid device id, and broadcasts it
    using uevent and the device modalias. The module alias generation is
    modified to match. As a consequence, a device with a non-zero group
    will be processed by the corresponding group driver instead of by the
    generic hid driver.

    Signed-off-by: Henrik Rydberg
    Acked-by: Benjamin Tissoires
    Signed-off-by: Jiri Kosina

    Henrik Rydberg
     
  • The low-level driver can read the report descriptor, but it cannot
    determine driver-specific changes to it. The hid core can fixup
    and parse the report descriptor during driver attach, but does
    not have direct access to the descriptor when doing so.

    To be able to handle attach/detach of hid drivers properly,
    a semantic change to hid_parse_report() is needed. This function has
    been used in two ways, both as descriptor reader in the ll drivers and
    as a parsor in the probe of the drivers. This patch splits the usage
    by introducing hid_open_report(), and modifies the hid_parse() macro
    to call hid_open_report() instead. The only usage of hid_parse_report()
    is then to read and store the device descriptor. As a consequence, we
    can handle the report fixups automatically inside the hid core.

    Signed-off-by: Henrik Rydberg
    Tested-by: Nikolai Kondrashov
    Tested-by: Benjamin Tissoires
    Signed-off-by: Jiri Kosina

    Henrik Rydberg
     

28 Apr, 2012

1 commit