Commit Graph

26 Commits

Author SHA1 Message Date
Benjamin Tisssoires 42c22dbf81 HID: logitech-dj: Fix USB 3.0 issue
This fix (not very clean though) should fix the long time USB3
issue that was spotted last year. The rational has been given by
Hans de Goede:

 ----

I think the most likely cause for this is a firmware bug
in the unifying receiver, likely a race condition.

The most prominent difference between having a USB-2 device
plugged into an EHCI (so USB-2 only) port versus an XHCI
port will be inter packet timing. Specifically if you
send packets (ie hid reports) one at a time, then with
the EHCI controller their will be a significant pause
between them, where with XHCI they will be very close
together in time.

The reason for this is the difference in EHCI / XHCI
controller OS <-> driver interfaces.

For non periodic endpoints (control, bulk) the EHCI uses a
circular linked-list of commands in dma-memory, which it
follows to execute commands, if the list is empty, it
will go into an idle state and re-check periodically.

The XHCI uses a ring of commands per endpoint, and if the OS
places anything new on the ring it will do an ioport write,
waking up the XHCI making it send the new packet immediately.

For periodic transfers (isoc, interrupt) the delay between
packets when sending one at a time (rather then queuing them
up) will be even larger, because they need to be inserted into
the EHCI schedule 2 ms in the future so the OS driver can be
sure that the EHCI driver does not try to start executing the
time slot in question before the insertion has completed.

So a possible fix may be to insert a delay between packets
being send to the receiver.

 ----

I tested this on a buggy Haswell USB 3.0 motherboard, and I always
get the notification after adding the msleep.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2014-01-16 22:48:21 +01:00
Dan Carpenter 6d60332610 HID: logitech-dj: small cleanup in rdcat()
We could pass the "rdsec" pointer instead of the address of the "rdesc"
and it's a little simpler.

Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2013-10-30 14:43:29 +01:00
Kees Cook 297502abb3 HID: logitech-dj: validate output report details
A HID device could send a malicious output report that would cause the
logitech-dj HID driver to leak kernel memory contents to the device, or
trigger a NULL dereference during initialization:

[  304.424553] usb 1-1: New USB device found, idVendor=046d, idProduct=c52b
...
[  304.780467] BUG: unable to handle kernel NULL pointer dereference at 0000000000000028
[  304.781409] IP: [<ffffffff815d50aa>] logi_dj_recv_send_report.isra.11+0x1a/0x90

CVE-2013-2895

Signed-off-by: Kees Cook <keescook@chromium.org>
Cc: stable@vger.kernel.org
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2013-09-13 15:13:32 +02:00
Jiri Kosina 63faf15dba Merge branches 'for-3.12/devm', 'for-3.12/i2c-hid', 'for-3.12/i2c-hid-dt', 'for-3.12/logitech', 'for-3.12/multitouch-win8', 'for-3.12/trasnport-driver-cleanup', 'for-3.12/uhid', 'for-3.12/upstream' and 'for-3.12/wiimote' into for-linus 2013-09-06 11:58:37 +02:00
Jiri Kosina efd15f5f4f Merge branch 'master' into for-3.12/upstream
Sync with Linus' tree to be able to apply fixup patch on top
of 9d9a04ee75 ("HID: apple: Add support for the 2013 Macbook Air")

Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2013-09-04 10:49:57 +02:00
Jiri Kosina 8e5654ce69 Revert "HID: hid-logitech-dj: querying_devices was never set"
This reverts commit 407a2c2a4d.

Explanation provided by Benjamin Tissoires:

Commit "HID: hid-logitech-dj, querying_devices was never set" activate
a flag which guarantees that we do not ask the receiver for too many
enumeration. When the flag is set, each following enumeration call is
discarded (the usb request is not forwarded to the receiver). The flag
is then released when the driver receive a pairing information event,
which normally follows the enumeration request.
However, the USB3 bug makes the driver think the enumeration request
has been forwarded to the receiver. However, it is actually not the
case because the USB stack returns -EPIPE. So, when a new unknown
device appears, the workaround consisting in asking for a new
enumeration is not working anymore: this new enumeration is discarded
because of the flag, which is never reset.

A solution could be to trigger a timeout before releasing it, but for
now, let's just revert the patch.

Reported-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
Tested-by: Sune Mølgaard <sune@molgaard.org>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2013-08-09 11:34:19 +02:00
Peter Hurley ce7373685e HID: logitech-dj: Fix non-atomic kmalloc in logi_dj_ll_input_event()
The ll_driver's .hidinput_input_event() method is called from
atomic context [1]. Use GFP_ATOMIC for allocation of the
synthesized hid report.

BUG: sleeping function called from invalid context at /home/peter/src/kernels/next/mm/slub.c:941
in_atomic(): 1, irqs_disabled(): 1, pid: 2095, name: Xorg
INFO: lockdep is turned off.
irq event stamp: 1502178
hardirqs last  enabled at (1502177): [<ffffffff81785e55>] _raw_spin_unlock_irqrestore+0x65/0x80
hardirqs last disabled at (1502178): [<ffffffff8178632a>] common_interrupt+0x6a/0x6f
softirqs last  enabled at (1501802): [<ffffffff81051ed3>] __do_softirq+0x183/0x420
softirqs last disabled at (1501799): [<ffffffff81052315>] irq_exit+0xb5/0xc0
CPU: 3 PID: 2095 Comm: Xorg Not tainted 3.11-next-20130725-xeon+lockdep #20130725
Hardware name: Dell Inc. Precision WorkStation T5400  /0RW203, BIOS A11 04/30/2012
 ffffffff81a662e0 ffff8802adcf9ca8 ffffffff8177c330 0000000000000000
 ffff8802a76d2440 ffff8802adcf9cd8 ffffffff810867d0 ffff8802a7ac8000
 0000000000000010 00000000ffffffff 00000000000000d0 ffff8802adcf9d38
Call Trace:
 [<ffffffff8177c330>] dump_stack+0x4f/0x84
 [<ffffffff810867d0>] __might_sleep+0x140/0x1f0
 [<ffffffff811ad93b>] __kmalloc+0x6b/0x2e0
 [<ffffffffa026cb08>] ? hid_alloc_report_buf+0x28/0x30 [hid]
 [<ffffffffa026cb08>] hid_alloc_report_buf+0x28/0x30 [hid]
 [<ffffffffa00700b0>] logi_dj_ll_input_event+0xb0/0x1b0 [hid_logitech_dj]
 [<ffffffff815a559e>] input_handle_event+0x8e/0x540
 [<ffffffff815a5aad>] ? input_inject_event+0x5d/0x220
 [<ffffffff815a5c10>] input_inject_event+0x1c0/0x220
 [<ffffffff815a5a94>] ? input_inject_event+0x44/0x220
 [<ffffffff81181660>] ? might_fault+0xa0/0xb0
 [<ffffffff81181617>] ? might_fault+0x57/0xb0
 [<ffffffff815a909e>] evdev_write+0xde/0x160
 [<ffffffff811c0ad8>] vfs_write+0xc8/0x1f0
 [<ffffffff811c0fe5>] SyS_write+0x55/0xa0
 [<ffffffff8178e682>] system_call_fastpath+0x16/0x1b

Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2013-08-01 00:45:52 +02:00
Nestor Lopez Casado 407a2c2a4d HID: hid-logitech-dj: querying_devices was never set
Set querying_devices flag to true when we start the enumeration
process.

This was missing from the original patch. It never produced
undesirable effects as it is highly improbable to have a second
enumeration triggered while a first one was still in progress.

Signed-off-by: Nestor Lopez Casado <nlopezcasad@logitech.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2013-07-22 16:32:24 +02:00
Nestor Lopez Casado c63e0e3700 HID: Revert "Revert "HID: Fix logitech-dj: missing Unifying device issue""
This reverts commit 8af6c08830.

This patch re-adds the workaround introduced by 596264082f
which was reverted by 8af6c08830.

The original patch 596264 was needed to overcome a situation where
the hid-core would drop incoming reports while probe() was being
executed.

This issue was solved by c849a6143b which added
hid_device_io_start() and hid_device_io_stop() that enable a specific
hid driver to opt-in for input reports while its probe() is being
executed.

Commit a9dd22b730 modified hid-logitech-dj so as to use the
functionality added to hid-core. Having done that, workaround 596264
was no longer necessary and was reverted by 8af6c08.

We now encounter a different problem that ends up 'again' thwarting
the Unifying receiver enumeration. The problem is time and usb controller
dependent. Ocasionally the reports sent to the usb receiver to start
the paired devices enumeration fail with -EPIPE and the receiver never
gets to enumerate the paired devices.

With dcd9006b1b the problem was "hidden" as the call to the usb
driver became asynchronous and none was catching the error from the
failing URB.

As the root cause for this failing SET_REPORT is not understood yet,
-possibly a race on the usb controller drivers or a problem with the
Unifying receiver- reintroducing this workaround solves the problem.

Overall what this workaround does is: If an input report from an
unknown device is received, then a (re)enumeration is performed.

related bug:
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1194649

Signed-off-by: Nestor Lopez Casado <nlopezcasad@logitech.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2013-07-22 16:32:24 +02:00
Jiri Kosina 27ce405039 HID: fix data access in implement()
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 <benjamin.tissoires@redhat.com>
Acked-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2013-07-22 16:16:40 +02:00
Benjamin Tissoires ddf7540e9c HID: logitech-dj: use inlined helpers hid_hw_open/close
Use the inlined helpers hid_hw_open/close instead of direct calls to
->ll_driver->open() and ->ll_driver->close().

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2013-07-12 11:40:17 +02:00
Jiri Kosina 4f5a810429 Merge branches 'for-3.10/appleir', 'for-3.10/hid-debug', 'for-3.10/hid-driver-transport-cleanups', 'for-3.10/i2c-hid' and 'for-3.10/logitech' into for-linus 2013-04-30 10:12:44 +02:00
Jiri Kosina 83a44ac8bf HID: Merge branch 'master' into for-3.10/hid-driver-transport-cleanups
Sync with Linus' tree. This is necessary to resolve build conflict
caused by dcd9006b1b ("HID: logitech-dj: do not directly call
hid_output_raw_report() during probe") which issues direct call to
usbhid_submit_report(), but that is gone in this branch and
hid_hw_request() has to be used instead.

Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2013-03-09 11:01:06 +01:00
Benjamin Tissoires dcd9006b1b HID: logitech-dj: do not directly call hid_output_raw_report() during probe
hid_output_raw_report() makes a direct call to usb_control_msg(). However,
some USB3 boards have shown that the usb device is not ready during the
.probe(). This blocks the entire usb device, and the paired mice, keyboards
are not functional. The dmesg output is the following:

[   11.912287] logitech-djreceiver 0003:046D:C52B.0003: hiddev0,hidraw0: USB HID v1.11 Device [Logitech USB Receiver] on usb-0000:00:14.0-2/input2
[   11.912537] logitech-djreceiver 0003:046D:C52B.0003: logi_dj_probe:logi_dj_recv_query_paired_devices error:-32
[   11.912636] logitech-djreceiver: probe of 0003:046D:C52B.0003 failed with error -32

Relying on the scheduled call to usbhid_submit_report() fixes the problem.

related bugs:
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1072082
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1039143
https://bugzilla.redhat.com/show_bug.cgi?id=840391
https://bugzilla.kernel.org/show_bug.cgi?id=49781

Reported-and-tested-by: Bob Bowles <bobjohnbowles@gmail.com>
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2013-03-07 16:06:55 +01:00
Andrew de los Reyes 8af6c08830 Revert "HID: Fix logitech-dj: missing Unifying device issue"
This reverts commit 596264082f.

The reverted commit was a workaround needed when drivers became unable
to communicate with devices during probe(). Now that such
communication is possible, the workaround is not needed.

Signed-off-by: Andrew de los Reyes <adlr@chromium.org>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2013-03-01 14:14:59 +01:00
Andrew de los Reyes a9dd22b730 HID: logitech-dj: Allow incoming packets during probe().
Historically, logitech-dj communicated with the device during probe()
to query the list of devices attached. Later, a change was introduced
to hid-core that prevented incoming packets for a device during
probe(), as many drivers are unable to handle such input. That change
broke the device enumeration in logitech-dj, so commit
596264082f was introduced to workaround that by waiting for
normal input before enumerating devices.

Now that drivers can opt-in to receive input during probe, this patch
changes logitech-dj to do that, so that it can successfully complete
enumeration of devices during probe().

Signed-off-by: Andrew de los Reyes <adlr@chromium.org>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2013-03-01 14:14:35 +01:00
Benjamin Tissoires d881427253 HID: use hid_hw_request() instead of direct call to usbhid
This allows the hid drivers to be independent from the transport layer.

The patch was constructed by replacing all occurences of
usbhid_submit_report() by its hid_hw_request() counterpart.
Then, drivers not requiring USB_HID anymore have their USB_HID
dependency cleaned in the Kconfig file.

Finally, few drivers still depends on USB_HID. Many of them
are requiring the io wait callback. They are found in the next patch.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>

For the sensor-hub part:
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2013-02-25 13:26:41 +01:00
Nestor Lopez Casado 596264082f HID: Fix logitech-dj: missing Unifying device issue
This patch fixes an issue introduced after commit 4ea5454203
("HID: Fix race condition between driver core and ll-driver").

After that commit, hid-core discards any incoming packet that arrives while
hid driver's probe function is being executed.

This broke the enumeration process of hid-logitech-dj, that must receive
control packets in-band with the mouse and keyboard packets. Discarding mouse
or keyboard data at the very begining is usually fine, but it is not the case
for control packets.

This patch forces a re-enumeration of the paired devices when a packet arrives
that comes from an unknown device.

Based on a patch originally written by Benjamin Tissoires.

Cc: stable@vger.kernel.org   # v3.2+
Signed-off-by: Nestor Lopez Casado <nlopezcasad@logitech.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2012-09-22 10:58:48 +02:00
Alan Cox 8a55ade765 dj: memory scribble in logi_dj
Allocate a structure not a pointer to it !

Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2012-09-05 19:37:08 -07:00
Marc Dionne d8dc3494f7 HID: logitech: don't use stack based dj_report structures
On a system with a logitech wireless keyboard/mouse and DMA-API debugging
enabled, this warning appears at boot:

kernel: WARNING: at lib/dma-debug.c:929 check_for_stack.part.12+0x70/0xa7()
kernel: Hardware name: MS-7593
kernel: uhci_hcd 0000:00:1d.1: DMA-API: device driver maps memory fromstack [addr=ffff8801b0079c29]

Make logi_dj_recv_query_paired_devices and logi_dj_recv_switch_to_dj_mode
use a structure allocated with kzalloc rather than a stack based one.

Signed-off-by: Marc Dionne <marc.c.dionne@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2012-06-03 15:11:43 +02:00
Jiri Kosina 99ce58ddc4 Merge branches 'upstream-fixes', 'wacom' and 'waltop' into for-linus
Conflicts:
	drivers/hid/hid-core.c
2012-05-22 11:35:11 +02:00
Jonathan Nieder 44d27f7dfe HID: logitech: read all 32 bits of report type bitfield
On big-endian systems (e.g., Apple PowerBook), trying to use a
logitech wireless mouse with the Logitech Unifying Receiver does not
work with v3.2 and later kernels.  The device doesn't show up in
/dev/input.  Older kernels work fine.

That is because the new hid-logitech-dj driver claims the device.  The
device arrival notification appears:

	20 00 41 02 00 00 00 00 00 00 00 00 00 00 00

and we read the report_types bitfield (02 00 00 00) to find out what
kind of device it is.  Unfortunately the driver only reads the first 8
bits and treats that value as a 32-bit little-endian number, so on a
powerpc the report type seems to be 0x02000000 and is not recognized.

Even on little-endian machines, connecting a media center remote
control (report type 00 01 00 00) with this driver loaded would
presumably fail for the same reason.

Fix both problems by using get_unaligned_le32() to read all four
bytes, which is a little clearer anyway.  After this change, the
wireless mouse works on Hugo's PowerBook again.

Based on a patch by Nestor Lopez Casado.
Addresses http://bugs.debian.org/671292

Reported-by: Hugo Osvaldo Barrera <hugo@osvaldobarrera.com.ar>
Inspired-by: Nestor Lopez Casado <nlopezcasad@logitech.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Nestor Lopez Casado <nlopezcasad@logitech.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2012-05-11 16:31:21 +02:00
Henrik Rydberg 2a039bf5a6 HID: hid-logitech: Collect report descriptors before sending
The current code allows several consecutive calls to hid_parse_report(),
which may have happened to work before, but would cause a memory leak
and generally be incorrect. This patch collects all the reports
before sending them once.

Cc: Nestor Lopez Casado <nlopezcasad@logitech.com>
Tested-by: Benjamin Tissoires <benjamin.tissoires@gmail.com
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2012-05-01 12:54:53 +02:00
Nestor Lopez Casado 765031668f HID: logitech: fix mask to enable DJ mode
The user can only experience the bug if she pairs 6 devices to a Unifying
receiver. The sixth paired device would not work.

The value changed is actually a bitmask that enables reporting from each
paired device. As the sixth bit was not set, the sixth device reports are
ignored by the receiver and never get to the driver.

Signed-off-by: Nestor Lopez Casado <nlopezcasad@logitech.com>

 drivers/hid/hid-logitech-dj.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2012-02-02 10:54:14 +01:00
Nestor Lopez Casado 844580ff63 HID: hid-logitech-dj: fix off by one
There is a bug where a device with index 6 would write out of bounds in
the array of paired devices.
This patch fixes that problem.

Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
Reviewed-by: Olivier Gay <ogay@logitech.com>
Signed-off-by: Nestor Lopez Casado <nlopezcasad@logitech.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2011-09-20 16:09:22 +02:00
Nestor Lopez Casado 534a7b8e10 HID: Add full support for Logitech Unifying receivers
With this driver, all the devices paired to a single Unifying
receiver are exposed to user processes in separated /input/dev
nodes.

Keyboards with different layouts can be treated differently,
Multiplayer games on single PC (like home theater PC) can
differentiate input coming from different kbds paired to the
same receiver.

Up to now, when Logitech Unifying receivers are connected to a
Linux based system, a single keyboard and a single mouse are
presented to the HID Layer, even if the Unifying receiver can
pair up to six compatible devices. The Unifying receiver by default
multiplexes all incoming events (from multiple keyboards/mice)
into these two.

Signed-off-by: Nestor Lopez Casado <nlopezcasad@logitech.com>
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2011-09-15 11:34:49 +02:00