Commit graph

218 commits

Author SHA1 Message Date
Jiri Kosina
5a59f62cc0 Merge branch 'for-7.2/logitech' into for-linus
- fix for high resolution scrolling for Logitech HID++ 2.0 devices (Lauri Saurus)
2026-06-16 21:52:56 +02:00
Jiri Kosina
6df6b1f2c4 HID: hidpp: fix potential UAF in hidpp_connect_event()
If input_register_device() fails, we call input_free_device(), but keep
stale pointer to the old device in hidpp->input, which could potentially
lead to UAF. Fix that by resetting it to NULL before returning from
hidpp_connect_event().

Reported-by: zdi-disclosures@trendmicro.com
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-15 14:57:04 +02:00
Lauri Saurus
f0866517be HID: logitech-hidpp: sync wheel multiplier on wheel mode changes
The hid-logitech-hidpp driver enables high resolution scrolling on
device connect for capable HID++ 2.0 devices. Driver also reads the
wheel capability and caches the returned high resolution wheel scroll
multiplier, that is used for scroll scaling when handling wheel scroll
events.

Wheel mode can also be set externally through HID++ requests, which
can leave the cached multiplier stale and cause incorrect scroll
scaling. If external SetWheelMode HID++ request sets the mode to
low resolution, the cached multiplier is not updated accordingly. This
causes extremely slow scrolling since driver expects multiple wheel
scroll events per detent but is only getting one.

The fix listens for HID++ SetWheelMode request responses and updates
the wheel scroll multiplier based on the set high resolution scroll
mode. The fix has been tested with Logitech G502X lightspeed mouse.

Signed-off-by: Lauri Saurus <saurla@saurla.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-06-11 15:56:09 +02:00
Rosen Penev
f22a5db8a7 HID: logitech-hidpp: remove excess kernel-doc member in hidpp_scroll_counter
The @dev member described in the kernel-doc does not exist in the
struct. Remove the stale entry.

Fixes: 0610430e3d ("HID: logitech-hidpp: add input_device ptr to struct hidpp_device")
Assisted-by: opencode:big-pickle

Signed-off-by: Rosen Penev <rosenp@gmail.com>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2026-06-01 18:41:14 +02:00
Alain Michaud
64ffa2e5e0 HID: logitech-hidpp: Add support for newer Bluetooth keyboards
Add product IDs (PIDs) for several newer Logitech Bluetooth keyboards
to the hidpp_devices matching table, enabling full HID++ support for
them.

The added keyboards are:
- Logitech Signature K650 & B2B
- Logitech Pebble Keys 2 K380S
- Logitech Casa Pop-Up Desk & B2B
- Logitech Wave Keys & B2B
- Logitech Signature Slim K950 & B2B
- Logitech MX Keys S & B2B
- Logitech Keys-To-Go 2
- Logitech Pop Icon Keys
- Logitech MX Keys Mini & B2B
- Logitech Signature Slim Solar+ K980 B2B
- Logitech Bluetooth Keyboard K250/K251
- Logitech Signature Comfort K880 & B2B

Signed-off-by: Alain Michaud <alainmichaud@google.com>
Reviewed-by: Olivier Gay <ogay@logitech.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-05-12 18:16:46 +02:00
Benjamin Tissoires
2c85c61d13 HID: pass the buffer size to hid_report_raw_event
commit 0a3fe972a7 ("HID: core: Mitigate potential OOB by removing
bogus memset()") enforced the provided data to be at least the size of
the declared buffer in the report descriptor to prevent a buffer
overflow. However, we can try to be smarter by providing both the buffer
size and the data size, meaning that hid_report_raw_event() can make
better decision whether we should plaining reject the buffer (buffer
overflow attempt) or if we can safely memset it to 0 and pass it to the
rest of the stack.

Fixes: 0a3fe972a7 ("HID: core: Mitigate potential OOB by removing bogus memset()")
Cc: stable@vger.kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
Acked-by: Johan Hovold <johan@kernel.org>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-05-12 18:03:37 +02:00
Jiri Kosina
d4eb7b2da6 Merge branch 'for-7.1/core-v2' into for-linus
- fixed handling of 0-sized reports (Dmitry Torokhov)
- convert core code to __free() (Dmitry Torokhov)
- support for multiple batteries per HID device (Lucas Zampieri)
2026-04-16 21:01:18 +02:00
Benoît Sevens
e2aaf2d3ad HID: logitech-hidpp: fix race condition when accessing stale stack pointer
The driver uses hidpp->send_receive_buf to point to a stack-allocated
buffer in the synchronous command path (__do_hidpp_send_message_sync).
However, this pointer is not cleared when the function returns.

If an event is processed (e.g. by a different thread) while the
send_mutex is held by a new command, but before that command has
updated send_receive_buf, the handler (hidpp_raw_hidpp_event) will
observe that the mutex is locked and dereference the stale pointer.

This results in an out-of-bounds access on a different thread's kernel
stack (or a NULL pointer dereference on the very first command).

Fix this by:
1. Clearing hidpp->send_receive_buf to NULL before releasing the mutex
   in the synchronous command path.
2. Moving the assignment of the local 'question' and 'answer' pointers
   inside the mutex_is_locked() block in the handler, and adding
   a NULL check before dereferencing.

Signed-off-by: Benoît Sevens <bsevens@google.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-04-09 19:25:07 +02:00
Günther Noack
e606d8329b HID: logitech-hidpp: Check bounds when deleting force-feedback effects
Without this bounds check, this might otherwise overwrite index -1.

Triggering this condition requires action both from the USB device and from
userspace, which reduces the scenarios in which it can be exploited.

Cc: Lee Jones <lee@kernel.org>
Signed-off-by: Günther Noack <gnoack@google.com>
Reviewed-by: Lee Jones <lee@kernel.org>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-04-09 17:27:37 +02:00
Linus Torvalds
f0caa1d49c hid-for-linus-2026031701
-----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEL65usyKPHcrRDEicpmLzj2vtYEkFAmm5t3QACgkQpmLzj2vt
 YEk90hAArhy85Gy5uTQwdj5TVnGIwVH5+twiOz4S0If396duQGfK3MY+c+jzW2kO
 7UI2uWV4tgXJGSoK1kTuQ3IXGgUDGofbaQ15nltpibQ4c+3whcDmMRICGIA/OqCk
 FmHHAV264Y5y6bapG7VvT8PLv0N+TtGV4G4LhQv90eObnRXXnc0m+H0s2IObr2py
 aBJgmgFQQ3DMWddX5DMatMd6M6e+2kJHY3X/41youvbvVJoWtqrJQEKIB19HDR8o
 9GkEjn4GLMPZ6hPlTJCnkRn7zfRWQ3MvUMft1kCdVtpOlqvftHoBrXvP6X1YDtPR
 Hy07HkH1Jpq0zI6AYyKj7f36oasnnNCm4ZFijn2RBx2chmKEUrpz2fSJ4aS5YU81
 QqhOjVR+euYL7kQ1UtoFGNwOhBHKWcJr5AezxxUNwn4SJ1bl8TGB63OEt2/1GI8/
 L1PMMAgHnxUAlJui38PfeiXboUeS9bfPiJd20FnGzCghsdvk6a+W9oWz+2yhs+Fy
 csm1MvcxhZZ7ugXPmscE/U6iLueaqlj42dQ+wkm6sh8aYKS+9eIlIgNpu4Q9Z//e
 LZGPOjx+jDWiqqTBmXke7hGMXHNXHRbWDLWlE+Du4XS5sfKwTDRKXs+g3MWI/nVf
 gHvuHuKQvrQHiAcnWH0fNJbsHaGExpWWAbb+yoWCJHJAU3vj7ek=
 =1U5m
 -----END PGP SIGNATURE-----

Merge tag 'hid-for-linus-2026031701' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid

Pull HID fixes from Jiri Kosina:

 - various fixes dealing with (intentionally) broken devices in HID
   core, logitech-hidpp and multitouch drivers (Lee Jones)

 - fix for OOB in wacom driver (Benoît Sevens)

 - fix for potentialy HID-bpf-induced buffer overflow in () (Benjamin
   Tissoires)

 - various other small fixes and device ID / quirk additions

* tag 'hid-for-linus-2026031701' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid:
  HID: multitouch: Check to ensure report responses match the request
  HID: logitech-hidpp: Prevent use-after-free on force feedback initialisation failure
  HID: bpf: prevent buffer overflow in hid_hw_request
  selftests/hid: fix compilation when bpf_wq and hid_device are not exported
  HID: core: Mitigate potential OOB by removing bogus memset()
  HID: intel-thc-hid: Set HID_PHYS with PCI BDF
  HID: appletb-kbd: add .resume method in PM
  HID: logitech-hidpp: Enable MX Master 4 over bluetooth
  HID: input: Add HID_BATTERY_QUIRK_DYNAMIC for Elan touchscreens
  HID: input: Drop Asus UX550* touchscreen ignore battery quirks
  HID: asus: add xg mobile 2022 external hardware support
  HID: wacom: fix out-of-bounds read in wacom_intuos_bt_irq
2026-03-17 13:55:51 -07:00
Lee Jones
f7a4c78bfe HID: logitech-hidpp: Prevent use-after-free on force feedback initialisation failure
Presently, if the force feedback initialisation fails when probing the
Logitech G920 Driving Force Racing Wheel for Xbox One, an error number
will be returned and propagated before the userspace infrastructure
(sysfs and /dev/input) has been torn down.  If userspace ignores the
errors and continues to use its references to these dangling entities, a
UAF will promptly follow.

We have 2 options; continue to return the error, but ensure that all of
the infrastructure is torn down accordingly or continue to treat this
condition as a warning by emitting the message but returning success.
It is thought that the original author's intention was to emit the
warning but keep the device functional, less the force feedback feature,
so let's go with that.

Signed-off-by: Lee Jones <lee@kernel.org>
Reviewed-by: Günther Noack <gnoack@google.com>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2026-03-16 16:21:48 +01:00
Adrian Freund
70031e70ca HID: logitech-hidpp: Enable MX Master 4 over bluetooth
The Logitech MX Master 4 can be connected over bluetooth or through a
Logitech Bolt receiver. This change adds support for non-standard HID
features, such as high resolution scrolling when the mouse is connected
over bluetooth.
Because no Logitech Bolt receiver driver exists yet those features
won't be available when the mouse is connected through the receiver.

Signed-off-by: Adrian Freund <adrian@freund.io>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-03-12 13:43:37 +01:00
Linus Torvalds
bf4afc53b7 Convert 'alloc_obj' family to use the new default GFP_KERNEL argument
This was done entirely with mindless brute force, using

    git grep -l '\<k[vmz]*alloc_objs*(.*, GFP_KERNEL)' |
        xargs sed -i 's/\(alloc_objs*(.*\), GFP_KERNEL)/\1)/'

to convert the new alloc_obj() users that had a simple GFP_KERNEL
argument to just drop that argument.

Note that due to the extreme simplicity of the scripting, any slightly
more complex cases spread over multiple lines would not be triggered:
they definitely exist, but this covers the vast bulk of the cases, and
the resulting diff is also then easier to check automatically.

For the same reason the 'flex' versions will be done as a separate
conversion.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2026-02-21 17:09:51 -08:00
Kees Cook
69050f8d6d treewide: Replace kmalloc with kmalloc_obj for non-scalar types
This is the result of running the Coccinelle script from
scripts/coccinelle/api/kmalloc_objs.cocci. The script is designed to
avoid scalar types (which need careful case-by-case checking), and
instead replace kmalloc-family calls that allocate struct or union
object instances:

Single allocations:	kmalloc(sizeof(TYPE), ...)
are replaced with:	kmalloc_obj(TYPE, ...)

Array allocations:	kmalloc_array(COUNT, sizeof(TYPE), ...)
are replaced with:	kmalloc_objs(TYPE, COUNT, ...)

Flex array allocations:	kmalloc(struct_size(PTR, FAM, COUNT), ...)
are replaced with:	kmalloc_flex(*PTR, FAM, COUNT, ...)

(where TYPE may also be *VAR)

The resulting allocations no longer return "void *", instead returning
"TYPE *".

Signed-off-by: Kees Cook <kees@kernel.org>
2026-02-21 01:02:28 -08:00
Bastien Nocera
af4fe07a9d HID: logitech-hidpp: Add support for Logitech K980
Add support for the solar-charging Logitech K980 keyboard, over
Bluetooth. Bolt traffic doesn't get routed through logitech-dj, so
this code isn't triggered when Bolt is used.

Signed-off-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-02-02 13:47:56 +01:00
Günther Noack
1547d41f9f HID: logitech-hidpp: Check maxfield in hidpp_get_report_length()
Do not crash when a report has no fields.

Fake USB gadgets can send their own HID report descriptors and can define report
structures without valid fields.  This can be used to crash the kernel over USB.

Cc: stable@vger.kernel.org
Signed-off-by: Günther Noack <gnoack@google.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-01-10 10:29:37 +01:00
Dennis Marttinen
d7f6629bff HID: logitech: add HID++ support for Logitech MX Anywhere 3S
I've acquired a Logitech MX Anywhere 3S mouse, which supports HID++ over
Bluetooth. Adding its PID 0xb037 to the allowlist enables the additional
features, such as high-resolution scrolling. Tested working across multiple
machines, with a mix of Intel and Mediatek Bluetooth chips.

[jkosina@suse.com: standardize shortlog]
Signed-off-by: Dennis Marttinen <twelho@welho.tech>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2026-01-08 12:22:01 +01:00
Jiri Kosina
4b2dda7374 Merge branch 'for-6.19/logitech' into for-linus
- Support for Logitech G Pro X Superlight 2 receiver (Nathan Rossi)
- Fix for retry logic in hidpp_send_message_sync() (Mavroudis Chatzilazaridis)
- Support for new Lighspeed receiver version (Mavroudis Chatzilazaridis)
- Support for Logitech G13 (Leo L. Schwab)
- Backlight support improvement for Logitech G510 (Hans de Goede)
2025-12-02 14:48:03 +01:00
Stuart Hayhurst
ed80cc4667 HID: logitech-hidpp: Add HIDPP_QUIRK_RESET_HI_RES_SCROLL
The Logitech G502 Hero Wireless's high resolution scrolling resets after
being unplugged without notifying the driver, causing extremely slow
scrolling.

The only indication of this is a battery update packet, so add a quirk to
detect when the device is unplugged and re-enable the scrolling.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=218037
Signed-off-by: Stuart Hayhurst <stuart.a.hayhurst@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2025-10-16 18:19:22 +02:00
Mavroudis Chatzilazaridis
aba7963544 HID: logitech-hidpp: Do not assume FAP in hidpp_send_message_sync()
Currently, hidpp_send_message_sync() retries sending the message when the
device returns a busy error code, specifically HIDPP20_ERROR_BUSY, which
has a different meaning under RAP. This ends up being a problem because
this function is used for both FAP and RAP messages.

This issue is not noticeable on older receivers with unreachable devices
since they return HIDPP_ERROR_RESOURCE_ERROR (0x09), which is not equal to
HIDPP20_ERROR_BUSY (0x08).

However, newer receivers return HIDPP_ERROR_UNKNOWN_DEVICE (0x08) which
happens to equal to HIDPP20_ERROR_BUSY, causing unnecessary retries when
the device is not actually busy.

This is resolved by checking if the error response is FAP or RAP and
picking the respective ERROR_BUSY code.

Fixes: 60165ab774 ("HID: logitech-hidpp: rework one more time the retries attempts")
Signed-off-by: Mavroudis Chatzilazaridis <mavchatz@protonmail.com>
Tested-by: Stuart Hayhurst <stuart.a.hayhurst@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2025-10-14 11:55:15 +02:00
Mavroudis Chatzilazaridis
55cafcac08 HID: logitech-hidpp: Silence protocol errors on newer lightspeed receivers
When logitech-hidpp tries to communicate with an unreachable device paired
to a 046d:c547 lightspeed receiver, the following message is printed to the
console:

hidpp_root_get_protocol_version: received protocol error 0x08

This occurs because this receiver returns 0x08 (HIDPP_ERROR_UNKNOWN_DEVICE)
when a device is unreachable, compared to 0x09 (HIDPP_ERROR_RESOURCE_ERROR)
that the older receivers return.

This patch silences this harmless error by treating
HIDPP_ERROR_UNKNOWN_DEVICE the same as HIDPP_ERROR_RESOURCE_ERROR
in hidpp_root_get_protocol_version().

There are other checks for HIDPP_ERROR_RESOURCE_ERROR found in
battery-related functions, however this receiver does not trigger them when
the device is disconnected.

Signed-off-by: Mavroudis Chatzilazaridis <mavchatz@protonmail.com>
Tested-by: Stuart Hayhurst <stuart.a.hayhurst@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2025-10-14 11:55:02 +02:00
Matt Coffin
ab1bb82f3d HID: logitech: Add ids for G PRO 2 LIGHTSPEED
Adds support for the G PRO 2 LIGHTSPEED Wireless via it's nano receiver
or directly. This nano receiver appears to work identically to the 1_1
receiver for the case I've verified, which is the battery status through
lg-hidpp.

The same appears to be the case wired, sharing much with the Pro X
Superlight 2; differences seemed to lie in userland configuration rather
than in interfaces used by hid_logitech_hidpp on the kernel side.

I verified the sysfs interface for battery charge/discharge status, and
capacity read to be working on my 910-007290 device (white).

Signed-off-by: Matt Coffin <mcoffin13@gmail.com>
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2025-08-20 20:12:42 +02:00
Jiri Kosina
22380b5f03 Merge branch 'for-6.13/core' into for-linus
- assorted cleanups and small code fixes (Dmitry Torokhov, Yan Zhen,
  Nathan Chancellor, Andy Shevchenko)
2024-11-18 21:58:55 +01:00
Jiri Kosina
a737d9d62d Merge branch 'for-6.13/logitech' into for-linus
- unused variable removal in hidpp_root_get_feature() (Bastien Nocera)
2024-11-18 21:52:49 +01:00
Yan Zhen
aa68d2bd9b HID: Fix typo in the comment
Correctly spelled comments make it easier for the reader to understand
the code.

Fix typos:
'mninum' -> 'minimum',
'destoyed' -> 'destroyed',
'thridparty' -> 'thirdparty',
'lowcase' -> 'lowercase',
'idenitifiers' -> 'identifiers',
'exeuction' -> 'execution',
'fregments' -> 'fragments',
'devides' -> 'devices'.

Signed-off-by: Yan Zhen <yanzhen@vivo.com>
Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2024-10-08 08:53:49 +02:00
Bastien Nocera
fb6c0583a1 HID: logitech-hidpp: Remove feature_type from hidpp_root_get_feature()
Nobody uses that variable after it gets assigned, so this saves us from
having to declare it in the first place.

Signed-off-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2024-10-08 08:47:43 +02:00
Dmitry Torokhov
c653ffc283 HID: stop exporting hid_snto32()
The only user of hid_snto32() is Logitech HID++ driver, which always
calls hid_snto32() with valid size (constant, either 12 or 8) and
therefore can simply use sign_extend32().

Make the switch and remove hid_snto32(). Move snto32() and s32ton() to
avoid introducing forward declaration.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Link: https://patch.msgid.link/20241003144656.3786064-2-dmitry.torokhov@gmail.com
[bentiss: fix checkpatch warning]
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-10-04 10:39:00 +02:00
Al Viro
5f60d5f6bb move asm/unaligned.h to linux/unaligned.h
asm/unaligned.h is always an include of asm-generic/unaligned.h;
might as well move that thing to linux/unaligned.h and include
that - there's nothing arch-specific in that header.

auto-generated by the following:

for i in `git grep -l -w asm/unaligned.h`; do
	sed -i -e "s/asm\/unaligned.h/linux\/unaligned.h/" $i
done
for i in `git grep -l -w asm-generic/unaligned.h`; do
	sed -i -e "s/asm-generic\/unaligned.h/linux\/unaligned.h/" $i
done
git mv include/asm-generic/unaligned.h include/linux/unaligned.h
git mv tools/include/asm-generic/unaligned.h tools/include/linux/unaligned.h
sed -i -e "/unaligned.h/d" include/asm-generic/Kbuild
sed -i -e "s/__ASM_GENERIC/__LINUX/" include/linux/unaligned.h tools/include/linux/unaligned.h
2024-10-02 17:23:23 -04:00
Thomas Weißschuh
fe73965d07 HID: change return type of report_fixup() to const
By allowing the drivers to return a "const *" they can constify their
static report arrays.
This makes it clear to driver authors that the HID core will not modify
those reports and they can be reused for multiple devices.
Furthermore security is slightly improved as those reports are protected
against accidental or malicious modifications.

[bentiss: fixup hid-cougar.c and hid-multitouch.c for latest version of
the master branch]

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Link: https://patch.msgid.link/20240803-hid-const-fixup-v2-6-f53d7a7b29d8@weissschuh.net
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2024-08-27 16:29:55 +02:00
Jeff Johnson
9c8f05cf1d HID: logitech-hidpp: add missing MODULE_DESCRIPTION() macro
make allmodconfig && make W=1 C=1 reports:
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/hid/hid-logitech-hidpp.o

Add the missing invocation of the MODULE_DESCRIPTION() macro.

Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2024-06-04 16:16:37 +02:00
Allan Sandfeld Jensen
b88ee22809 HID: logitech: add a few Logitech HID++ device IDs
Adds a few recognized Logitech HID++ capable mice over USB and Bluetooth

Signed-off-by: Allan Sandfeld Jensen <kde@carewolf.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2024-05-06 23:23:27 +02:00
Oleksandr Natalenko
411a20db90 HID: logitech-hidpp: Do not flood kernel log
Since commit 680ee411a9 ("HID: logitech-hidpp: Fix connect event race")
the following messages appear in the kernel log from time to time:

logitech-hidpp-device 0003:046D:408A.0005: HID++ 4.5 device connected.
logitech-hidpp-device 0003:046D:408A.0005: HID++ 4.5 device connected.
logitech-hidpp-device 0003:046D:4051.0006: Disconnected
logitech-hidpp-device 0003:046D:408A.0005: Disconnected

As discussed, print the first per-device "device connected" message
at info level, demoting subsequent messages to debug level. Also,
demote the "Disconnected message" to debug level unconditionally.

Link: https://lore.kernel.org/lkml/3277085.44csPzL39Z@natalenko.name/
Signed-off-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2024-02-06 16:10:50 +01:00
Jiri Kosina
afa6ac2690 HID: logitech-hidpp: add support for Logitech G Pro X Superlight 2
Let logitech-hidpp driver claim Logitech G Pro X Superlight 2.

Reported-by: Marcus Rückert <darix@opensu.se>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
2024-01-22 21:32:01 +01:00
Hans de Goede
3e6b0bb22a HID: logitech-hidpp: Stop IO before calling hid_connect()
hid_connect() will call hid_pidff_init() which does
hid_device_io_start() leading to an "io already started" warning.

To fix this call hid_device_io_stop() before calling hid_connect(),
stopping IO means that connect events may be lost while hid_connect()
runs, re-enable IO and move the hidpp_connect_event() work queuing
after the hid_connect().

Note re-enabling IO is also necessary for the g920_get_config()
call later during hidpp_probe().

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20231025190151.302376-1-hdegoede@redhat.com
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2023-10-26 10:06:34 +02:00
Hans de Goede
9ce363aa00 HID: logitech-hidpp: Drop HIDPP_QUIRK_UNIFYING
HIDPP unifying is only checked once in probe() and it is also
set by probe() itself.

Drop the quirk and replace its one check by the condition which is
used to set the quirk in the first place.

This series has been tested on the following devices:
Logitech Bluetooth Laser Travel Mouse (bluetooth, HID++ 1.0)
Logitech M720 Triathlon (bluetooth, HID++ 4.5)
Logitech M720 Triathlon (unifying, HID++ 4.5)
Logitech K400 Pro (unifying, HID++ 4.1)
Logitech K270 (eQUAD nano Lite, HID++ 2.0)
Logitech M185 (eQUAD nano Lite, HID++ 4.5)
Logitech LX501 keyboard (27 Mhz, HID++ builtin scroll-wheel, HID++ 1.0)
Logitech M-RAZ105 mouse (27 Mhz, HID++ extra mouse buttons, HID++ 1.0)

And by bentiss:
Logitech Touchpad T650 (unifying)
Logitech Touchpad T651 (bluetooth)
Logitech MX Master 3B (BLE)
Logitech G403 (plain USB / Gaming receiver)

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20231010102029.111003-13-hdegoede@redhat.com
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2023-10-25 18:41:44 +02:00
Hans de Goede
f3c4ee7166 HID: logitech-hidpp: Drop delayed_work_cb()
Drop delayed_work_cb() instead make hidpp_connect_event() the workqueue
function itself.

Besides resulting in a small cleanup this will hopefully also make
it clearer that going forward hidpp_connect_event() should only
be run from a workqueue and not be directly invoked.

This series has been tested on the following devices:
Logitech Bluetooth Laser Travel Mouse (bluetooth, HID++ 1.0)
Logitech M720 Triathlon (bluetooth, HID++ 4.5)
Logitech M720 Triathlon (unifying, HID++ 4.5)
Logitech K400 Pro (unifying, HID++ 4.1)
Logitech K270 (eQUAD nano Lite, HID++ 2.0)
Logitech M185 (eQUAD nano Lite, HID++ 4.5)
Logitech LX501 keyboard (27 Mhz, HID++ builtin scroll-wheel, HID++ 1.0)
Logitech M-RAZ105 mouse (27 Mhz, HID++ extra mouse buttons, HID++ 1.0)

And by bentiss:
Logitech Touchpad T650 (unifying)
Logitech Touchpad T651 (bluetooth)
Logitech MX Master 3B (BLE)
Logitech G403 (plain USB / Gaming receiver)

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20231010102029.111003-12-hdegoede@redhat.com
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2023-10-25 18:41:39 +02:00
Hans de Goede
680ee411a9 HID: logitech-hidpp: Fix connect event race
There is a connect event race in hidpp_probe() in these 2 lines:

	connected = hidpp_root_get_protocol_version(hidpp) == 0;
	atomic_set(&hidpp->connected, connected);

Specifically the following can happen:

1. This line from hidpp_probe() is executed:
	connected = hidpp_root_get_protocol_version(hidpp) == 0;
   and sets connected to false;

2. A connect-event packet is received and does:
	atomic_set(&hidpp->connected, true);

3. The next line from hidpp_probe() is executed:
	atomic_set(&hidpp->connected, connected);
   and sets the atomic_t back to 0 again.

4. hidpp_connect_event() runs and sees the connected device
   as disconnected because of this.

To fix this make hidpp_connect_event() query the connection status
of the device itself instead of having it rely on possibly stale
data cached in struct hidpp_device.

This series has been tested on the following devices:
Logitech Bluetooth Laser Travel Mouse (bluetooth, HID++ 1.0)
Logitech M720 Triathlon (bluetooth, HID++ 4.5)
Logitech M720 Triathlon (unifying, HID++ 4.5)
Logitech K400 Pro (unifying, HID++ 4.1)
Logitech K270 (eQUAD nano Lite, HID++ 2.0)
Logitech M185 (eQUAD nano Lite, HID++ 4.5)
Logitech LX501 keyboard (27 Mhz, HID++ builtin scroll-wheel, HID++ 1.0)
Logitech M-RAZ105 mouse (27 Mhz, HID++ extra mouse buttons, HID++ 1.0)

And by bentiss:
Logitech Touchpad T650 (unifying)
Logitech Touchpad T651 (bluetooth)
Logitech MX Master 3B (BLE)
Logitech G403 (plain USB / Gaming receiver)

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20231010102029.111003-11-hdegoede@redhat.com
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2023-10-25 18:41:24 +02:00
Hans de Goede
bb17b2c6dd HID: logitech-hidpp: Remove unused connected param from *_connect()
Remove the unused connected function parameter from wtp_connect(),
m560_send_config_command() and k400_connect().

This is a preparation patch for moving all connected state handling
to hidpp_connect_event().

This series has been tested on the following devices:
Logitech Bluetooth Laser Travel Mouse (bluetooth, HID++ 1.0)
Logitech M720 Triathlon (bluetooth, HID++ 4.5)
Logitech M720 Triathlon (unifying, HID++ 4.5)
Logitech K400 Pro (unifying, HID++ 4.1)
Logitech K270 (eQUAD nano Lite, HID++ 2.0)
Logitech M185 (eQUAD nano Lite, HID++ 4.5)
Logitech LX501 keyboard (27 Mhz, HID++ builtin scroll-wheel, HID++ 1.0)
Logitech M-RAZ105 mouse (27 Mhz, HID++ extra mouse buttons, HID++ 1.0)

And by bentiss:
Logitech Touchpad T650 (unifying)
Logitech Touchpad T651 (bluetooth)
Logitech MX Master 3B (BLE)
Logitech G403 (plain USB / Gaming receiver)

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20231010102029.111003-10-hdegoede@redhat.com
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2023-10-25 18:41:19 +02:00
Hans de Goede
6f335b47ad HID: logitech-hidpp: Remove connected check for non-unifying devices
Non-unifying devices (USB, Bluetooth) are always connected during
probe(), remove the unnecessary connected check.

This is a preparation patch for moving all connected state handling
to hidpp_connect_event().

This series has been tested on the following devices:
Logitech Bluetooth Laser Travel Mouse (bluetooth, HID++ 1.0)
Logitech M720 Triathlon (bluetooth, HID++ 4.5)
Logitech M720 Triathlon (unifying, HID++ 4.5)
Logitech K400 Pro (unifying, HID++ 4.1)
Logitech K270 (eQUAD nano Lite, HID++ 2.0)
Logitech M185 (eQUAD nano Lite, HID++ 4.5)
Logitech LX501 keyboard (27 Mhz, HID++ builtin scroll-wheel, HID++ 1.0)
Logitech M-RAZ105 mouse (27 Mhz, HID++ extra mouse buttons, HID++ 1.0)

And by bentiss:
Logitech Touchpad T650 (unifying)
Logitech Touchpad T651 (bluetooth)
Logitech MX Master 3B (BLE)
Logitech G403 (plain USB / Gaming receiver)

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20231010102029.111003-9-hdegoede@redhat.com
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2023-10-25 18:41:15 +02:00
Hans de Goede
c14f1485c6 HID: logitech-hidpp: Add hidpp_non_unifying_init() helper
Turn hidpp_overwrite_name() into a hidpp_non_unifying_init() helper
which takes care of setting both the name and the serial for non
unifying devices.

This mirrors the hidpp_unifying_init() helper for unifying devices.

This series has been tested on the following devices:
Logitech Bluetooth Laser Travel Mouse (bluetooth, HID++ 1.0)
Logitech M720 Triathlon (bluetooth, HID++ 4.5)
Logitech M720 Triathlon (unifying, HID++ 4.5)
Logitech K400 Pro (unifying, HID++ 4.1)
Logitech K270 (eQUAD nano Lite, HID++ 2.0)
Logitech M185 (eQUAD nano Lite, HID++ 4.5)
Logitech LX501 keyboard (27 Mhz, HID++ builtin scroll-wheel, HID++ 1.0)
Logitech M-RAZ105 mouse (27 Mhz, HID++ extra mouse buttons, HID++ 1.0)

And by bentiss:
Logitech Touchpad T650 (unifying)
Logitech Touchpad T651 (bluetooth)
Logitech MX Master 3B (BLE)
Logitech G403 (plain USB / Gaming receiver)

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20231010102029.111003-8-hdegoede@redhat.com
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2023-10-25 18:41:11 +02:00
Hans de Goede
8954dac18c HID: logitech-hidpp: Move hidpp_overwrite_name() to before connect check
Move the hidpp_overwrite_name() call to before the connect check, this
puts it at the same place in the probe() order as hidpp_serial_init()
which seems more logical. This should not make a difference since this
is in the non-unifying path and only unifying devices can be probed
in non-connected state.

This is a preparation patch for moving all connected state handling
to hidpp_connect_event().

Doing this before the connect check requires dropping the protocol
version check since protocol_major is not set yet now. Instead
this relies on hidpp_root_get_feature(HIDPP_PAGE_GET_DEVICE_NAME_TYPE)
failing on older devices, just like how hidpp_get_serial() relies on
hidpp_root_get_feature(HIDPP_PAGE_DEVICE_INFORMATION) failing on older
devices. So this again makes the code more consistent.

Also stop printing an error on failure now, since with the proto
version check gone failures are expected to happen on older devices.

This series has been tested on the following devices:
Logitech Bluetooth Laser Travel Mouse (bluetooth, HID++ 1.0)
Logitech M720 Triathlon (bluetooth, HID++ 4.5)
Logitech M720 Triathlon (unifying, HID++ 4.5)
Logitech K400 Pro (unifying, HID++ 4.1)
Logitech K270 (eQUAD nano Lite, HID++ 2.0)
Logitech M185 (eQUAD nano Lite, HID++ 4.5)
Logitech LX501 keyboard (27 Mhz, HID++ builtin scroll-wheel, HID++ 1.0)
Logitech M-RAZ105 mouse (27 Mhz, HID++ extra mouse buttons, HID++ 1.0)

And by bentiss:
Logitech Touchpad T650 (unifying)
Logitech Touchpad T651 (bluetooth)
Logitech MX Master 3B (BLE)
Logitech G403 (plain USB / Gaming receiver)

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20231010102029.111003-7-hdegoede@redhat.com
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2023-10-25 18:41:05 +02:00
Hans de Goede
219ccfb600 HID: logitech-hidpp: Move g920_get_config() to just before hidpp_ff_init()
The data retrieved by g920_get_config() is only used by hidpp_ff_init().

Now that the hw is kept open till the end of probe() the g920_get_config()
call can be moved to just before hidpp_ff_init() to have all
the HIDPP_QUIRK_CLASS_G920 together in a single place.

This series has been tested on the following devices:
Logitech Bluetooth Laser Travel Mouse (bluetooth, HID++ 1.0)
Logitech M720 Triathlon (bluetooth, HID++ 4.5)
Logitech M720 Triathlon (unifying, HID++ 4.5)
Logitech K400 Pro (unifying, HID++ 4.1)
Logitech K270 (eQUAD nano Lite, HID++ 2.0)
Logitech M185 (eQUAD nano Lite, HID++ 4.5)
Logitech LX501 keyboard (27 Mhz, HID++ builtin scroll-wheel, HID++ 1.0)
Logitech M-RAZ105 mouse (27 Mhz, HID++ extra mouse buttons, HID++ 1.0)

And by bentiss:
Logitech Touchpad T650 (unifying)
Logitech Touchpad T651 (bluetooth)
Logitech MX Master 3B (BLE)
Logitech G403 (plain USB / Gaming receiver)

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20231010102029.111003-6-hdegoede@redhat.com
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2023-10-25 18:41:01 +02:00
Hans de Goede
a3643036d7 HID: logitech-hidpp: Remove wtp_get_config() call from probe()
For WTP devices which start disconnected (paired with the unifying
receiver, but not connected atm) hidpp_connect_event() takes care
of calling wtp_get_config() when the device later connects.

There is no need to have a separate code path for WTP devices which
are connected at probe() time, these can use the same code-path since
probe() will queue hidpp_connect_event() for those at probe time.

Drop the unnecessary wtp_get_config() call from probe().

This series has been tested on the following devices:
Logitech Bluetooth Laser Travel Mouse (bluetooth, HID++ 1.0)
Logitech M720 Triathlon (bluetooth, HID++ 4.5)
Logitech M720 Triathlon (unifying, HID++ 4.5)
Logitech K400 Pro (unifying, HID++ 4.1)
Logitech K270 (eQUAD nano Lite, HID++ 2.0)
Logitech M185 (eQUAD nano Lite, HID++ 4.5)
Logitech LX501 keyboard (27 Mhz, HID++ builtin scroll-wheel, HID++ 1.0)
Logitech M-RAZ105 mouse (27 Mhz, HID++ extra mouse buttons, HID++ 1.0)

And by bentiss:
Logitech Touchpad T650 (unifying)
Logitech Touchpad T651 (bluetooth)
Logitech MX Master 3B (BLE)
Logitech G403 (plain USB / Gaming receiver)

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20231010102029.111003-5-hdegoede@redhat.com
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2023-10-25 18:40:56 +02:00
Hans de Goede
ba9de35050 HID: logitech-hidpp: Move get_wireless_feature_index() check to hidpp_connect_event()
Calling get_wireless_feature_index() from probe() causes
the wireless_feature_index to only get set for unifying devices which
are already connected at probe() time. It does not get set for devices
which connect later.

Fix this by moving get_wireless_feature_index() to hidpp_connect_event(),
this does not make a difference for devices connected at probe() since
probe() will queue the hidpp_connect_event() for those at probe time.

This series has been tested on the following devices:
Logitech Bluetooth Laser Travel Mouse (bluetooth, HID++ 1.0)
Logitech M720 Triathlon (bluetooth, HID++ 4.5)
Logitech M720 Triathlon (unifying, HID++ 4.5)
Logitech K400 Pro (unifying, HID++ 4.1)
Logitech K270 (eQUAD nano Lite, HID++ 2.0)
Logitech M185 (eQUAD nano Lite, HID++ 4.5)
Logitech LX501 keyboard (27 Mhz, HID++ builtin scroll-wheel, HID++ 1.0)
Logitech M-RAZ105 mouse (27 Mhz, HID++ extra mouse buttons, HID++ 1.0)

And by bentiss:
Logitech Touchpad T650 (unifying)
Logitech Touchpad T651 (bluetooth)
Logitech MX Master 3B (BLE)
Logitech G403 (plain USB / Gaming receiver)

Fixes: 0da0a63b7c ("HID: logitech-hidpp: Support WirelessDeviceStatus connect events")
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20231010102029.111003-4-hdegoede@redhat.com
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2023-10-25 18:40:50 +02:00
Hans de Goede
55bf70362f HID: logitech-hidpp: Revert "Don't restart communication if not necessary"
Commit 91cf9a98ae ("HID: logitech-hidpp: make .probe usbhid capable")
makes hidpp_probe() first call hid_hw_start(hdev, 0) to allow IO
without connecting any hid subdrivers (hid-input, hidraw).

This is done to allow to retrieve the device's name and serial number
and store these in hdev->name and hdev->uniq.

Then later on IO was stopped and started again with hid_hw_start(hdev,
HID_CONNECT_DEFAULT) connecting hid-input and hidraw after the name
and serial number have been setup.

Commit 498ba20690 ("HID: logitech-hidpp: Don't restart communication
if not necessary") changed the probe() code to only do the start with
a 0 connect-mask + restart later for unifying devices.

But for non unifying devices hdev->name and hdev->uniq are updated too.
So this change re-introduces the problem for which the start with
a 0 connect-mask + restart later behavior was introduced.

The previous patch in this series changes the unifying path to instead of
restarting IO only call hid_connect() later. This avoids possible issues
with restarting IO seen on non unifying devices.

Revert the change to limit the restart behavior to unifying devices to
fix hdev->name changing after userspace facing devices have already been
registered.

This series has been tested on the following devices:
Logitech Bluetooth Laser Travel Mouse (bluetooth, HID++ 1.0)
Logitech M720 Triathlon (bluetooth, HID++ 4.5)
Logitech M720 Triathlon (unifying, HID++ 4.5)
Logitech K400 Pro (unifying, HID++ 4.1)
Logitech K270 (eQUAD nano Lite, HID++ 2.0)
Logitech M185 (eQUAD nano Lite, HID++ 4.5)
Logitech LX501 keyboard (27 Mhz, HID++ builtin scroll-wheel, HID++ 1.0)
Logitech M-RAZ105 mouse (27 Mhz, HID++ extra mouse buttons, HID++ 1.0)

And by bentiss:
Logitech Touchpad T650 (unifying)
Logitech Touchpad T651 (bluetooth)
Logitech MX Master 3B (BLE)
Logitech G403 (plain USB / Gaming receiver)

Fixes: 498ba20690 ("HID: logitech-hidpp: Don't restart communication if not necessary")
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20231010102029.111003-3-hdegoede@redhat.com
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2023-10-25 18:40:39 +02:00
Hans de Goede
11ca0322a4 HID: logitech-hidpp: Don't restart IO, instead defer hid_connect() only
Restarting IO causes 2 problems:

1. Some devices do not like IO being restarted this was addressed in
   commit 498ba20690 ("HID: logitech-hidpp: Don't restart communication
   if not necessary"), but that change has issues of its own and needs to
   be reverted.

2. Restarting IO and specifically calling hid_device_io_stop() causes
   received packets to be missed, which may cause connect-events to
   get missed.

Restarting IO was introduced in commit 91cf9a98ae ("HID: logitech-hidpp:
make .probe usbhid capable") to allow to retrieve the device's name and
serial number and store these in hdev->name and hdev->uniq before
connecting any hid subdrivers (hid-input, hidraw) exporting this info
to userspace.

But this does not require restarting IO, this merely requires deferring
calling hid_connect(). Calling hid_hw_start() with a connect-mask of
0 makes it skip calling hid_connect(), so hidpp_probe() can simply call
hid_connect() later without needing to restart IO.

Remove the stop + restart of IO and instead just call hid_connect() later
to avoid the issues caused by restarting IO.

Now that IO is no longer stopped, hid_hw_close() must be called at the end
of probe() to balance the hid_hw_open() done at the beginning probe().

This series has been tested on the following devices:
Logitech Bluetooth Laser Travel Mouse (bluetooth, HID++ 1.0)
Logitech M720 Triathlon (bluetooth, HID++ 4.5)
Logitech M720 Triathlon (unifying, HID++ 4.5)
Logitech K400 Pro (unifying, HID++ 4.1)
Logitech K270 (eQUAD nano Lite, HID++ 2.0)
Logitech M185 (eQUAD nano Lite, HID++ 4.5)
Logitech LX501 keyboard (27 Mhz, HID++ builtin scroll-wheel, HID++ 1.0)
Logitech M-RAZ105 mouse (27 Mhz, HID++ extra mouse buttons, HID++ 1.0)

And by bentiss:
Logitech Touchpad T650 (unifying)
Logitech Touchpad T651 (bluetooth)
Logitech MX Master 3B (BLE)
Logitech G403 (plain USB / Gaming receiver)

Fixes: 498ba20690 ("HID: logitech-hidpp: Don't restart communication if not necessary")
Suggested-by: Benjamin Tissoires <bentiss@kernel.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20231010102029.111003-2-hdegoede@redhat.com
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2023-10-25 18:36:37 +02:00
Hans de Goede
dac501397b HID: logitech-hidpp: Fix kernel crash on receiver USB disconnect
hidpp_connect_event() has *four* time-of-check vs time-of-use (TOCTOU)
races when it races with itself.

hidpp_connect_event() primarily runs from a workqueue but it also runs
on probe() and if a "device-connected" packet is received by the hw
when the thread running hidpp_connect_event() from probe() is waiting on
the hw, then a second thread running hidpp_connect_event() will be
started from the workqueue.

This opens the following races (note the below code is simplified):

1. Retrieving + printing the protocol (harmless race):

	if (!hidpp->protocol_major) {
		hidpp_root_get_protocol_version()
		hidpp->protocol_major = response.rap.params[0];
	}

We can actually see this race hit in the dmesg in the abrt output
attached to rhbz#2227968:

[ 3064.624215] logitech-hidpp-device 0003:046D:4071.0049: HID++ 4.5 device connected.
[ 3064.658184] logitech-hidpp-device 0003:046D:4071.0049: HID++ 4.5 device connected.

Testing with extra logging added has shown that after this the 2 threads
take turn grabbing the hw access mutex (send_mutex) so they ping-pong
through all the other TOCTOU cases managing to hit all of them:

2. Updating the name to the HIDPP name (harmless race):

	if (hidpp->name == hdev->name) {
		...
		hidpp->name = new_name;
	}

3. Initializing the power_supply class for the battery (problematic!):

hidpp_initialize_battery()
{
        if (hidpp->battery.ps)
                return 0;

	probe_battery(); /* Blocks, threads take turns executing this */

	hidpp->battery.desc.properties =
		devm_kmemdup(dev, hidpp_battery_props, cnt, GFP_KERNEL);

	hidpp->battery.ps =
		devm_power_supply_register(&hidpp->hid_dev->dev,
					   &hidpp->battery.desc, cfg);
}

4. Creating delayed input_device (potentially problematic):

	if (hidpp->delayed_input)
		return;

	hidpp->delayed_input = hidpp_allocate_input(hdev);

The really big problem here is 3. Hitting the race leads to the following
sequence:

	hidpp->battery.desc.properties =
		devm_kmemdup(dev, hidpp_battery_props, cnt, GFP_KERNEL);

	hidpp->battery.ps =
		devm_power_supply_register(&hidpp->hid_dev->dev,
					   &hidpp->battery.desc, cfg);

	...

	hidpp->battery.desc.properties =
		devm_kmemdup(dev, hidpp_battery_props, cnt, GFP_KERNEL);

	hidpp->battery.ps =
		devm_power_supply_register(&hidpp->hid_dev->dev,
					   &hidpp->battery.desc, cfg);

So now we have registered 2 power supplies for the same battery,
which looks a bit weird from userspace's pov but this is not even
the really big problem.

Notice how:

1. This is all devm-maganaged
2. The hidpp->battery.desc struct is shared between the 2 power supplies
3. hidpp->battery.desc.properties points to the result from the second
   devm_kmemdup()

This causes a use after free scenario on USB disconnect of the receiver:
1. The last registered power supply class device gets unregistered
2. The memory from the last devm_kmemdup() call gets freed,
   hidpp->battery.desc.properties now points to freed memory
3. The first registered power supply class device gets unregistered,
   this involves sending a remove uevent to userspace which invokes
   power_supply_uevent() to fill the uevent data
4. power_supply_uevent() uses hidpp->battery.desc.properties which
   now points to freed memory leading to backtraces like this one:

Sep 22 20:01:35 eric kernel: BUG: unable to handle page fault for address: ffffb2140e017f08
...
Sep 22 20:01:35 eric kernel: Workqueue: usb_hub_wq hub_event
Sep 22 20:01:35 eric kernel: RIP: 0010:power_supply_uevent+0xee/0x1d0
...
Sep 22 20:01:35 eric kernel:  ? asm_exc_page_fault+0x26/0x30
Sep 22 20:01:35 eric kernel:  ? power_supply_uevent+0xee/0x1d0
Sep 22 20:01:35 eric kernel:  ? power_supply_uevent+0x10d/0x1d0
Sep 22 20:01:35 eric kernel:  dev_uevent+0x10f/0x2d0
Sep 22 20:01:35 eric kernel:  kobject_uevent_env+0x291/0x680
Sep 22 20:01:35 eric kernel:  power_supply_unregister+0x8e/0xa0
Sep 22 20:01:35 eric kernel:  release_nodes+0x3d/0xb0
Sep 22 20:01:35 eric kernel:  devres_release_group+0xfc/0x130
Sep 22 20:01:35 eric kernel:  hid_device_remove+0x56/0xa0
Sep 22 20:01:35 eric kernel:  device_release_driver_internal+0x19f/0x200
Sep 22 20:01:35 eric kernel:  bus_remove_device+0xc6/0x130
Sep 22 20:01:35 eric kernel:  device_del+0x15c/0x3f0
Sep 22 20:01:35 eric kernel:  ? __queue_work+0x1df/0x440
Sep 22 20:01:35 eric kernel:  hid_destroy_device+0x4b/0x60
Sep 22 20:01:35 eric kernel:  logi_dj_remove+0x9a/0x100 [hid_logitech_dj 5c91534a0ead2b65e04dd799a0437e3b99b21bc4]
Sep 22 20:01:35 eric kernel:  hid_device_remove+0x44/0xa0
Sep 22 20:01:35 eric kernel:  device_release_driver_internal+0x19f/0x200
Sep 22 20:01:35 eric kernel:  bus_remove_device+0xc6/0x130
Sep 22 20:01:35 eric kernel:  device_del+0x15c/0x3f0
Sep 22 20:01:35 eric kernel:  ? __queue_work+0x1df/0x440
Sep 22 20:01:35 eric kernel:  hid_destroy_device+0x4b/0x60
Sep 22 20:01:35 eric kernel:  usbhid_disconnect+0x47/0x60 [usbhid 727dcc1c0b94e6b4418727a468398ac3bca492f3]
Sep 22 20:01:35 eric kernel:  usb_unbind_interface+0x90/0x270
Sep 22 20:01:35 eric kernel:  device_release_driver_internal+0x19f/0x200
Sep 22 20:01:35 eric kernel:  bus_remove_device+0xc6/0x130
Sep 22 20:01:35 eric kernel:  device_del+0x15c/0x3f0
Sep 22 20:01:35 eric kernel:  ? kobject_put+0xa0/0x1d0
Sep 22 20:01:35 eric kernel:  usb_disable_device+0xcd/0x1e0
Sep 22 20:01:35 eric kernel:  usb_disconnect+0xde/0x2c0
Sep 22 20:01:35 eric kernel:  usb_disconnect+0xc3/0x2c0
Sep 22 20:01:35 eric kernel:  hub_event+0xe80/0x1c10

There have been quite a few bug reports (see Link tags) about this crash.

Fix all the TOCTOU issues, including the really bad power-supply related
system crash on USB disconnect, by making probe() use the workqueue for
running hidpp_connect_event() too, so that it can never run more then once.

Link: https://bugzilla.redhat.com/show_bug.cgi?id=2227221
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2227968
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2227968
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2242189
Link: https://bugzilla.kernel.org/show_bug.cgi?id=217412#c58
Cc: stable@vger.kernel.org
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20231005182638.3776-1-hdegoede@redhat.com
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2023-10-06 16:09:14 +02:00
Hans de Goede
2d866603e2 HID: logitech-hidpp: Add Bluetooth ID for the Logitech M720 Triathlon mouse
Using hidpp for the M720 adds battery info reporting and hires
scrolling support.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2023-09-18 16:48:19 +02:00
Benjamin Tissoires
60165ab774 HID: logitech-hidpp: rework one more time the retries attempts
Extract the internal code inside a helper function, fix the
initialization of the parameters used in the helper function
(`hidpp->answer_available` was not reset and `*response` wasn't either),
and use a `do {...} while();` loop.

Fixes: 586e8fede7 ("HID: logitech-hidpp: Retry commands when device is busy")
Cc: stable@vger.kernel.org
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Link: https://lore.kernel.org/r/20230621-logitech-fixes-v2-1-3635f7f9c8af@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
2023-08-25 10:40:32 +02:00
Maxim Mikityanskiy
ed1fb63b6e HID: logitech-hidpp: Add support for Logitech MX Anywhere 3 mouse
Add Logitech MX Anywhere 3 connected over Bluetooth to the device table
to get hidpi scroll supported. USB connection over the Unifying receiver
is already supported by the wildcard entry LDJ_DEVICE(HID_ANY_ID).

Signed-off-by: Maxim Mikityanskiy <maxtram95@gmail.com>
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2023-08-14 11:46:31 +02:00