Age | Commit message (Collapse) | Author |
|
The current HID bpf implementation assumes no output report/request will
go through it after hid_bpf_destroy_device() has been called. This leads
to a bug that unplugging certain types of HID devices causes a cleaned-
up SRCU to be accessed. The bug was previously a hidden failure until a
recent x86 percpu change [1] made it access not-present pages.
The bug will be triggered if the conditions below are met:
A) a device under the driver has some LEDs on
B) hid_ll_driver->request() is uninplemented (e.g., logitech-djreceiver)
If condition A is met, hidinput_led_worker() is always scheduled *after*
hid_bpf_destroy_device().
hid_destroy_device
` hid_bpf_destroy_device
` cleanup_srcu_struct(&hdev->bpf.srcu)
` hid_remove_device
` ...
` led_classdev_unregister
` led_trigger_set(led_cdev, NULL)
` led_set_brightness(led_cdev, LED_OFF)
` ...
` input_inject_event
` input_event_dispose
` hidinput_input_event
` schedule_work(&hid->led_work) [hidinput_led_worker]
This is fine when condition B is not met, where hidinput_led_worker()
calls hid_ll_driver->request(). This is the case for most HID drivers,
which implement it or use the generic one from usbhid. The driver itself
or an underlying driver will then abort processing the request.
Otherwise, hidinput_led_worker() tries hid_hw_output_report() and leads
to the bug.
hidinput_led_worker
` hid_hw_output_report
` dispatch_hid_bpf_output_report
` srcu_read_lock(&hdev->bpf.srcu)
` srcu_read_unlock(&hdev->bpf.srcu, idx)
The bug has existed since the introduction [2] of
dispatch_hid_bpf_output_report(). However, the same bug also exists in
dispatch_hid_bpf_raw_requests(), and I've reproduced (no visible effect
because of the lack of [1], but confirmed bpf.destroyed == 1) the bug
against the commit (i.e., the Fixes:) introducing the function. This is
because hidinput_led_worker() falls back to hid_hw_raw_request() when
hid_ll_driver->output_report() is uninplemented (e.g., logitech-
djreceiver).
hidinput_led_worker
` hid_hw_output_report: -ENOSYS
` hid_hw_raw_request
` dispatch_hid_bpf_raw_requests
` srcu_read_lock(&hdev->bpf.srcu)
` srcu_read_unlock(&hdev->bpf.srcu, idx)
Fix the issue by returning early in the two mentioned functions if
hid_bpf has been marked as destroyed. Though
dispatch_hid_bpf_device_event() handles input events, and there is no
evidence that it may be called after the destruction, the same check, as
a safety net, is also added to it to maintain the consistency among all
dispatch functions.
The impact of the bug on other architectures is unclear. Even if it acts
as a hidden failure, this is still dangerous because it corrupts
whatever is on the address calculated by SRCU. Thus, CC'ing the stable
list.
[1]: commit 9d7de2aa8b41 ("x86/percpu/64: Use relative percpu offsets")
[2]: commit 9286675a2aed ("HID: bpf: add HID-BPF hooks for
hid_hw_output_report")
Closes: https://lore.kernel.org/all/20250506145548.GGaBoi9Jzp3aeJizTR@fat_crate.local/
Fixes: 8bd0488b5ea5 ("HID: bpf: add HID-BPF hooks for hid_hw_raw_requests")
Cc: stable@vger.kernel.org
Signed-off-by: Rong Zhang <i@rong.moe>
Tested-by: Petr Tesarik <petr@tesarici.cz>
Link: https://patch.msgid.link/20250512152420.87441-1-i@rong.moe
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
Usage_Dig_BarrelSwitch was applied in the UsagePage_Button
which incorrectly mapped to BTN_TOOL_PENCIL
Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/193
Fixes: 834da375 ("bpf: add a v6.11+ compatible BPF fixup for the XPPen ACK05 remote")
Link: https://patchwork.kernel.org/project/linux-input/patch/20250207-bpf-import-2025-02-07-v1-7-6048fdd5a206@kernel.org/
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
|
|
With v6.11+, we can actually call hid_hw_output_report() and put the device
into raw mode, thus getting accurate events without being messed up.
Technically we could do the same on v6.10, but given that wayland, gnome
and KDE are still not capable of handling the dial, and that v6.10 is EOL,
we can safely save a little bit of compilation by only allowing v6.11+.
We can easily export the battery information to userspace by adding a
dedicated report. However, we need to cheat on the kernel to force it
not to query the battery by making the physical collection a stylus. The
kernel will then only rely on the events it gets from the device.
Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/133
Acked-by: Jiri Kosina <jkosina@suse.com>
Link: https://patch.msgid.link/20250207-bpf-import-2025-02-07-v1-7-6048fdd5a206@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
The purpose is to simplify the use of bpf_wq to defer blocking
operations in a sleepable context. Compared to a more "classic"
async approach, there is no sync mechanism to wait for the async
to finish.
The "simple" API is the following:
```
static int HID_BPF_ASYNC(async_fun)(struct hid_bpf_ctx *hctx)
{
bpf_printk("%s", __fun__);
return 0;
}
SEC("syscall")
int probe(struct hid_bpf_probe_args *ctx)
{
ctx->retval = HID_BPF_ASYNC_INIT(async_fun);
return 0;
}
SEC(HID_BPF_DEVICE_EVENT)
int BPF_PROG(event_handler, struct hid_bpf_ctx *hctx)
{
/* async_fun() can be called now, it's not a sleepable
* function in this example
*/
async_fun(hctx);
/* but we can also delay the call by 10 ms */
HID_BPF_ASYNC_DELAYED_CALL(async_fun, hctx, 10);
return 0;
}
HID_BPF_OPS(xppen_ack05_remote) = {
.hid_device_event = (void *)event_handler,
};
```
Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/133
Acked-by: Jiri Kosina <jkosina@suse.com>
Link: https://patch.msgid.link/20250207-bpf-import-2025-02-07-v1-6-6048fdd5a206@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
These kfunc are all in v6.10 except for the hid_bpf_try_input_report()
which will be in v6.11. Import their definition once now so we can make
use of it.
Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/114
Acked-by: Jiri Kosina <jkosina@suse.com>
Link: https://patch.msgid.link/20250207-bpf-import-2025-02-07-v1-5-6048fdd5a206@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
The device behaves the same than the 16" and 14" models, so let's just
add support for it too.
Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/145
Acked-by: Jiri Kosina <jkosina@suse.com>
Link: https://patch.msgid.link/20250207-bpf-import-2025-02-07-v1-4-6048fdd5a206@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
This adds an updated HID descriptor for the Huion Kamvas Pro 19 that is
present on newer firmware revisions, while also trying to keep
compat with the older versions.
Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/164
Signed-off-by: Aki Van Ness <aki@lethalbit.net>
Acked-by: Jiri Kosina <jkosina@suse.com>
Link: https://patch.msgid.link/20250207-bpf-import-2025-02-07-v1-3-6048fdd5a206@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
The TUXEDO Sirius 16 Gen1 and the TUXEDO Sirius 16 Gen2 Notebooks have an
additional "fan" key next to F12.
Pressing it alone sends a F14 key press which can be bound by user space.
Pressing it while holding the FN key triggers two things:
- The EC firmware locks the fan speed of the internal fans at 100%
- F13 key press is registered which by default is already bound in xkb and
desktop environments (e.g. in KDE Plasma it launches system settings)
To avoid this unexpected double duty of the FN shortcut, this bpf program
suppresses the F13 key press.
Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/166
Acked-by: Jiri Kosina <jkosina@suse.com>
Link: https://patch.msgid.link/20250207-bpf-import-2025-02-07-v1-2-6048fdd5a206@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
This re-uses the same HID report descriptor that we also use for
the tablet mode after switching the device. The keys send uniquely
identifyable shortcuts so we can map those to buttons.
However the dial and the button inside the dial send events on a
different hidraw node and they are unreliable (e.g. the button does not
get released reliably). So they're ignored in this patch, it's not
worth the effort getting those to work correctly.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/158
Acked-by: Jiri Kosina <jkosina@suse.com>
Link: https://patch.msgid.link/20250207-bpf-import-2025-02-07-v1-1-6048fdd5a206@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
In commit 33c0fb85b571 ("HID: bpf: make part of struct hid_device writable")
the const qualifier was dropped from struct hid_bpf_ctx::hid.
The casts are now unnecessary.
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Link: https://patch.msgid.link/20241127-hid-bpf-cast-v1-1-f26424960e84@weissschuh.net
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
The hid_ops struct is never modified. Mark it as const.
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Link: https://patch.msgid.link/20241127-hid-bpf-ops-v1-1-f9e41bfa3afd@weissschuh.net
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
This reverts commit 6fd47effe92b, and the related self-test update
commit e14e0eaeb040 ("selftests/hid: add test for assigning a given
device to hid-generic").
It results in things like the scroll wheel on Logitech mice not working
after a reboot due to the kernel being confused about the state of the
high-resolution mode.
Quoting Benjamin Tissoires:
"The idea of 6fd47effe92b was to be able to call hid_bpf_rdesc_fixup()
once per reprobe of the device.
However, because the bpf filter can now change the quirk value, the
call had to be moved before the driver gets bound (which was
previously ensuring the unicity of the call).
The net effect is that now, in the case hid-generic gets loaded first
and then the specific driver gets loaded once the disk is available,
the value of ->quirks is not reset, but kept to the value that was set
by hid-generic (HID_QUIRK_INPUT_PER_APP).
Once hid-logitech-hidpp kicks in, that quirk is now set, which creates
two inputs for the single mouse: one keyboard for fancy shortcuts, and
one mouse node.
However, hid-logitech-hidpp expects only one input node to be attached
(it stores it into hidpp->input), and when a wheel event is received,
because there is some processing with high-resolution wheel events,
the wheel event is injected into hidpp->input.
And of course, when HID_QUIRK_INPUT_PER_APP is set, hidpp->input gets
the keyboard node, which doesn't have wheel event type, and the events
are ignored"
Reported-and-bisected-by: Mike Galbraith <efault@gmx.de>
Link: https://lore.kernel.org/all/CAHk-=wiUkQM3uheit2cNM0Y0OOY5qqspJgC8LkmOkJ2p2LDxcw@mail.gmail.com/
Acked-by: Benjamin Tissoires <bentiss@kernel.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
|
Replace with individual Minimum/Maximum calls to match the HID report
descriptor - HID doesn't have a Range field. Abstracting this is good
for hand-written descriptors but almost all tools will output min/max
instead so let's stick with that.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Acked-by: Jiri Kosina <jkosina@suse.com>
Link: https://patch.msgid.link/20241017-import_bpf_6-13-v2-3-6a7acb89a97f@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
The Rapoo M50 Plus Silent mouse has 2 side buttons in addition to the
left, right and middles buttons. However, its original HID descriptor
has a Usage Maximum of 3, preventing the side buttons to work.
This HID-BPF driver changes that usage to 5.
Link: https://gitlab.freedesktop.org/libinput/libinput/-/issues/1015
Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/116
Signed-off-by: José Expósito <jose.exposito89@gmail.com>
Acked-by: Jiri Kosina <jkosina@suse.com>
Link: https://patch.msgid.link/20241017-import_bpf_6-13-v2-2-6a7acb89a97f@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
Mistel MD770 keyboard (using Holtek Semiconductor, Inc. controller) has
a quirk in report descriptor in one of its interfaces (more detail in
the source file). Fix up the descriptor to allow NKRO to work again.
Tested by loading the BPF program and confirming that 8 simultaneous
keypresses work.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=218495
Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/122
Signed-off-by: Tatsuyuki Ishi <ishitatsuyuki@gmail.com>
Acked-by: Jiri Kosina <jkosina@suse.com>
Link: https://patch.msgid.link/20241017-import_bpf_6-13-v2-1-6a7acb89a97f@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
This allows to give more control from BPF during report descriptor fixup.
We already reset the quirks before calling ->probe(), so now we reset
it once before calling hid_bpf_rdesc_fixup().
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Link: https://patch.msgid.link/20241001-hid-bpf-hid-generic-v3-4-2ef1019468df@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
Currently, hid_bpf_rdesc_fixup() is called once the match between the
HID device and the driver is done. This can be problematic in case
the driver selected by the kernel would change the report descriptor
after the fact.
To give a chance for hid_bpf_rdesc_fixup() to provide hints on to how
to select a dedicated driver or not, move the call to that BPF hook
earlier in the .probe() process, when we get the first match.
However, this means that we might get called more than once (typically
once for hid-generic, and once for hid-vendor-specific). So we store the
result of HID-BPF fixup in struct hid_device. Basically, this means that
->bpf_rdesc can replace ->dev_rdesc when it was used in the code.
In order to not grow struct hid_device, some fields are re-ordered. This
was the output of pahole for the first 128 bytes:
struct hid_device {
__u8 * dev_rdesc; /* 0 8 */
unsigned int dev_rsize; /* 8 4 */
/* XXX 4 bytes hole, try to pack */
__u8 * rdesc; /* 16 8 */
unsigned int rsize; /* 24 4 */
/* XXX 4 bytes hole, try to pack */
struct hid_collection * collection; /* 32 8 */
unsigned int collection_size; /* 40 4 */
unsigned int maxcollection; /* 44 4 */
unsigned int maxapplication; /* 48 4 */
__u16 bus; /* 52 2 */
__u16 group; /* 54 2 */
__u32 vendor; /* 56 4 */
__u32 product; /* 60 4 */
/* --- cacheline 1 boundary (64 bytes) --- */
__u32 version; /* 64 4 */
enum hid_type type; /* 68 4 */
unsigned int country; /* 72 4 */
/* XXX 4 bytes hole, try to pack */
struct hid_report_enum report_enum[3]; /* 80 6216 */
Basically, we got three holes of 4 bytes. We can reorder things a little
and makes those 3 holes a continuous 12 bytes hole, which can be replaced
by the new pointer and the new unsigned int we need.
In terms of code allocation, when not using HID-BPF, we are back to kernel
v6.2 in hid_open_report(). These multiple kmemdup() calls will be fixed
in a later commit.
Link: https://patch.msgid.link/20241001-hid-bpf-hid-generic-v3-1-2ef1019468df@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
With the introduction of commit e42ac1418055 ("bpf: Check unsupported ops
from the bpf_struct_ops's cfi_stubs"), a HID-BPF struct_ops containing
a .hid_hw_request() or a .hid_hw_output_report() was failing to load
as the cfi stubs were not defined.
Fix that by defining those simple static functions and restore HID-BPF
functionality.
This was detected with the HID selftests suddenly failing on Linus' tree.
Cc: stable@vger.kernel.org # v6.11+
Fixes: 9286675a2aed ("HID: bpf: add HID-BPF hooks for hid_hw_output_report")
Fixes: 8bd0488b5ea5 ("HID: bpf: add HID-BPF hooks for hid_hw_raw_requests")
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
|
|
The parameter is never modified, so mark it as const.
Also inline the return statement to avoid a type mismatch error.
This is a prerequisite for constification changes in the HID core.
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Link: https://patch.msgid.link/20240803-hid-const-fixup-v2-1-f53d7a7b29d8@weissschuh.net
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
If the struct_ops is already attached, we should bail out or we will
end up in various locks and pointer issues while unregistering.
Link: https://patch.msgid.link/20240723-fix-6-11-bpf-v1-3-b9d770346784@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
The module does not do anything when the JIT is disabled, but instead
causes a warning:
In file included from include/linux/bpf_verifier.h:7,
from drivers/hid/bpf/hid_bpf_struct_ops.c:10:
drivers/hid/bpf/hid_bpf_struct_ops.c: In function 'hid_bpf_struct_ops_init':
include/linux/bpf.h:1853:50: error: statement with no effect [-Werror=unused-value]
1853 | #define register_bpf_struct_ops(st_ops, type) ({ (void *)(st_ops); 0; })
| ^~~~~~~~~~~~~~~~
drivers/hid/bpf/hid_bpf_struct_ops.c:305:16: note: in expansion of macro 'register_bpf_struct_ops'
305 | return register_bpf_struct_ops(&bpf_hid_bpf_ops, hid_bpf_ops);
| ^~~~~~~~~~~~~~~~~~~~~~~
Add a Kconfig dependency to only allow building the HID-BPF support
when a JIT is enabled.
Fixes: ebc0d8093e8c ("HID: bpf: implement HID-BPF through bpf_struct_ops")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Link: https://patch.msgid.link/96a00b6f-eb81-4c67-8c4b-6b1f3f045034@app.fastmail.com
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid
Pull HID updates from Benjamin Tissoires:
- rewrite of the HID-BPF internal implementation to use bpf struct_ops
instead of a tracing endpoint (Benjamin Tissoires)
- add two new HID-BPF hooks to be able to intercept userspace calls
targeting a HID device and filtering them (Benjamin Tissoires)
- add support for various new devices through HID-BPF filters (Benjamin
Tissoires)
- add support for the magic keyboard backlight (Orlando Chamberlain)
- add the missing MODULE_DESCRIPTION() macros in HID drivers (Jeff
Johnson)
- use of kvzalloc in case memory gets too fragmented (Hailong Liu)
- retrieve the device firmware node in the child HID device (Danny
Kaehn)
- some hid-uclogic improvements (José Expósito)
- some more typos, trivial fixes, kernel doctext and unused functions
cleanups
* tag 'for-linus-2024071601' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: (60 commits)
HID: hid-steam: Fix typo in goto label
HID: mcp2221: Remove unnecessary semicolon
HID: Fix spelling mistakes "Kensigton" -> "Kensington"
HID: add more missing MODULE_DESCRIPTION() macros
HID: samples: fix the 2 struct_ops definitions
HID: fix for amples in for-6.11/bpf
HID: apple: Add support for magic keyboard backlight on T2 Macs
HID: bpf: Thrustmaster TCA Yoke Boeing joystick fix
HID: bpf: Add Huion Dial 2 bpf fixup
HID: bpf: Add support for the XP-PEN Deco Mini 4
HID: bpf: move the BIT() macro to hid_bpf_helpers.h
HID: bpf: add a driver for the Huion Inspiroy 2S (H641P)
HID: bpf: Add a HID report composition helper macros
HID: bpf: doc fixes for hid_hw_request() hooks
HID: bpf: doc fixes for hid_hw_request() hooks
HID: bpf: fix gcc warning and unify __u64 into u64
selftests/hid: ensure CKI can compile our new tests on old kernels
selftests/hid: add an infinite loop test for hid_bpf_try_input_report
selftests/hid: add another test for injecting an event from an event hook
HID: bpf: allow hid_device_event hooks to inject input reports on self
...
|
|
This joystick's original HID descriptor is wrong & it shows a
ABS_MISC axis in Linux that doesn't exist on the hardware.
Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/82
Signed-off-by: K S Iyer <kumar.s.iyer65@gmail.com>
Link: https://patch.msgid.link/20240627-import-bpf-v1-6-0dbcda4a5b1f@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
Pretty much similar to the Inspiroy 2, but with 2 wheels and 8 buttons.
This bpf also works in both normal and vendor mode. If the device is
switched into vendor mode by huion-switcher, a udev property is set
which is then retrieved by this bpf object. This allows to hide the now
unused normal collections.
Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/103
Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/104
Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/111
Link: https://patch.msgid.link/20240627-import-bpf-v1-5-0dbcda4a5b1f@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
The XP-PEN Deco Mini 4 is a UGEE device with a frame with 6 buttons.
Its pen has 2 buttons and supports pressure reporting.
Fix their report descriptors and transform the frame button events to
support it.
Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/88
Signed-off-by: José Expósito <jose.exposito89@gmail.com>
Link: https://patch.msgid.link/20240627-import-bpf-v1-4-0dbcda4a5b1f@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
This macro can be useful in mopre than one place
Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/commit/7970a9c17aa0756bad63e89fccb6ee4f2ec83ccc
Signed-off-by: José Expósito <jose.exposito89@gmail.com>
Link: https://patch.msgid.link/20240627-import-bpf-v1-3-0dbcda4a5b1f@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
This is a a driver for the Huion Inspiroy 2S in both modes (firmware mode
and tablet mode). This device has 6 buttons and a wheel, all of which
send key combinations (see the comments for the defaults). Luckily the
device is quite limited in that it only supports one button down at a
time, so with this BPF we can simply remap the 8 possible report IDs to
our own custom-built report descriptor.
If the device is in tablet mode (e.g. using huion-switcher it sends
everything through the vendor report instead). This BPF program converts
both, depending which devices you attach to you get both. Or if you
attach to all hid devices you get a duplicate device but it'll work
either way.
This BPF should be mostly compatible for the M and L as well though they
have more buttons so the rdescs will need some minor rework.
Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/85
Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/109
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Link: https://patch.msgid.link/20240627-import-bpf-v1-2-0dbcda4a5b1f@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
These macros make it slightly easier and more modular to create
a HID report descriptor from scratch. Since they carry the annotation
we don't need to comment it and they cannot get stale.
For comparison, before we had this:
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x95, 0x04, // Report Count (4)
0x75, 0x01, // Report Size (1)
Now we can write this as:
LogicalRange_i8(0, 1)
ReportCount(4)
ReportSize(1)
Because these macros are for creating new report descriptors,
some bits aren't directly exposed. e.g in the example above:
there is a logical range as one macro that sets both min and max.
There is seldom a good use case for skipping either anyway.
These macros will need to be expanded over time.
For Usage Pages and Usage IDs, we use a tool to parse the HUT JSON
(attached to the HUT 1.5 PDF [1]) and generate all #defines for all
usage pages and usages in the form:
#define UsagePage_Foo_Bar
#define Usage_FB_SomeOrOther
Where the FB is simply the acronym based on the capital letters in the
Usage Page name or the first three letters, whichever makes slightly
more sense.
[1] https://usb.org/document-library/hid-usage-tables-15
Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/92
Link: https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/-/merge_requests/96
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Link: https://patch.msgid.link/20240627-import-bpf-v1-1-0dbcda4a5b1f@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
We had the following errors while doing make htmldocs:
Documentation/hid/hid-bpf:185: include/linux/hid_bpf.h:167:
ERROR: Unexpected indentation.
Also ensure consistency with the rest of the __u64 vs u64.
Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
Fixes: 9286675a2aed ("HID: bpf: add HID-BPF hooks for hid_hw_output_report")
Link: https://patch.msgid.link/20240701-fix-cki-v2-4-20564e2e1393@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
I've got multiple reports of:
error: cast from pointer to integer of different size
[-Werror=pointer-to-int-cast].
Let's use the same trick than kernel/bpf/helpers.c to shut up that warning.
Even if we were on an architecture with addresses on more than 64 bits,
this isn't much of an issue as the address is not used as a pointer,
but as an hash and the caller is not supposed to go back to the kernel
address ever.
And while we change those, make sure we use u64 instead of __u64 for
consistency
Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202406280633.OPB5uIFj-lkp@intel.com/
Closes: https://lore.kernel.org/oe-kbuild-all/202406282304.UydSVncq-lkp@intel.com/
Closes: https://lore.kernel.org/oe-kbuild-all/202406282242.Fk738zzy-lkp@intel.com/
Reported-by: Mirsad Todorovac <mtodorovac69@gmail.com>
Fixes: 67eccf151d76 ("HID: add source argument to HID low level functions")
Link: https://patch.msgid.link/20240701-fix-cki-v2-2-20564e2e1393@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
This is the same logic than hid_hw_raw_request or hid_hw_output_report:
we can allow hid_bpf_try_input_report to be called from a hook on
hid_input_report if we ensure that the call can not be made twice in a
row.
There is one extra subtlety in which there is a lock in hid_input_report.
But given that we can detect if we are already in the hook, we can notify
hid_input_report to not take the lock. This is done by checking if
ctx_kern data is valid or null, and if it is equal to the dedicated
incoming data buffer.
In order to have more control on whether the lock needs to be taken or not
we introduce a new kfunc for it: hid_bpf_try_input_report()
Link: https://patch.msgid.link/20240626-hid_hw_req_bpf-v2-11-cfd60fb6c79f@kernel.org
Acked-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
hid_bpf_input_report() is already marked to be used in sleepable context
only. So instead of hammering with timers the device to hopefully get
an available slot where the device is not sending events, we can make
that kfunc wait for the current event to be terminated before it goes in.
This allows to work with the following pseudo code:
in struct_ops/hid_device_event:
- schedule a bpf_wq, which calls hid_bpf_input_report()
- once this struct_ops function terminates, hid_bpf_input_report()
immediately starts before the next event
Link: https://patch.msgid.link/20240626-hid_hw_req_bpf-v2-9-cfd60fb6c79f@kernel.org
Acked-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
We add 3 new tests:
- first, we make sure we can prevent the output_report to happen
- second, we make sure that we can detect that a given hidraw client
was actually doing the request, and for that client only, call ourself
hid_bpf_hw_output_report(), returning a custom value
- last, we ensure that we can not loop between hooks for
hid_hw_output_report() and manual calls to hid_bpf_hw_output_report()
from that same hook
Link: https://patch.msgid.link/20240626-hid_hw_req_bpf-v2-8-cfd60fb6c79f@kernel.org
Acked-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
Same story than hid_hw_raw_requests:
This allows to intercept and prevent or change the behavior of
hid_hw_output_report() from a bpf program.
The intent is to solve a couple of use case:
- firewalling a HID device: a firewall can monitor who opens the hidraw
nodes and then prevent or allow access to write operations on that
hidraw node.
- change the behavior of a device and emulate a new HID feature request
The hook is allowed to be run as sleepable so it can itself call
hid_hw_output_report(), which allows to "convert" one feature request into
another or even call the feature request on a different HID device on the
same physical device.
Link: https://patch.msgid.link/20240626-hid_hw_req_bpf-v2-7-cfd60fb6c79f@kernel.org
Acked-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
When we attach a sleepable hook to hid_hw_raw_requests, we can (and in
many cases should) call ourself hid_bpf_raw_request(), to actually fetch
data from the device itself.
However, this means that we might enter an infinite loop between
hid_hw_raw_requests hooks and hid_bpf_hw_request() call.
To prevent that, if a hid_bpf_hw_request() call is emitted, we prevent
any new call of this kfunc by storing the information in the context.
This way we can always trace/monitor/filter the incoming bpf requests,
while preventing those loops to happen.
I don't think exposing "from_bpf" is very interesting because while
writing such a bpf program, you need to match at least the report number
and/or the source of the call. So a blind "if there is a
hid_hw_raw_request() call, I'm emitting another one" makes no real
sense.
Link: https://patch.msgid.link/20240626-hid_hw_req_bpf-v2-5-cfd60fb6c79f@kernel.org
Acked-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
This allows to intercept and prevent or change the behavior of
hid_hw_raw_request() from a bpf program.
The intent is to solve a couple of use case:
- firewalling a HID device: a firewall can monitor who opens the hidraw
nodes and then prevent or allow access to write operations on that
hidraw node.
- change the behavior of a device and emulate a new HID feature request
The hook is allowed to be run as sleepable so it can itself call
hid_bpf_hw_request(), which allows to "convert" one feature request into
another or even call the feature request on a different HID device on the
same physical device.
Link: https://patch.msgid.link/20240626-hid_hw_req_bpf-v2-4-cfd60fb6c79f@kernel.org
Acked-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
We want to add sleepable callbacks for hid_hw_raw_request() and
hid_hw_output_report(), but we can not use a plain RCU for those.
Prepare for a SRCU so we can extend HID-BPF.
This changes a little bit how hid_bpf_device_init() behaves, as it may
now fail, so there is a tiny hid-core.c change to accommodate for this.
Link: https://patch.msgid.link/20240626-hid_hw_req_bpf-v2-3-cfd60fb6c79f@kernel.org
Acked-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
This allows to know who actually sent what when we process the request
to the device.
This will be useful for a BPF firewall program to allow or not requests
coming from a dedicated hidraw node client.
Link: https://patch.msgid.link/20240626-hid_hw_req_bpf-v2-2-cfd60fb6c79f@kernel.org
Acked-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
Looks like if a bpf program gets inserted and then removed,
hdev->bpf.device_data is then allocated, but the loop iterating
over the bpf program is never assigning ret.
This is a problem and also revealed another bug in which only the last
value of ret was checked. This effectively meant than only the last
program in the chain could change the size of the incoming buffer.
Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
Link: https://lore.kernel.org/all/00f7b624-219f-4a05-a7ad-5335f15a41c7@moroto.mountain
Fixes: 4a86220e046d ("HID: bpf: remove tracing HID-BPF capability")
Link: https://patch.msgid.link/20240626-hid_hw_req_bpf-v2-1-cfd60fb6c79f@kernel.org
Acked-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
* spelling fix: XBox -> Xbox, lowercase 'b' as per Microsoft branding
* rephrase: paddle -> paddles, the controller itself has more than one paddle
* rephrase: replace usage of "those" in favor of explicitly making reference
to the paddles
* grammatical fix: report -> reports, use present tense verb.
* spelling fix: interpret
* consistency: capitalize the first word in bullet points
Signed-off-by: Luis Felipe Hernandez <luis.hernandez093@gmail.com>
Link: https://patch.msgid.link/20240625105553.50830-1-luis.hernandez093@gmail.com
[bentiss: renamed the file into Xbox, not XBox]
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
It is useful to change the name, the phys and/or the uniq of a
struct hid_device during .rdesc_fixup().
For example, hid-uclogic.ko changes the uniq to store the firmware version
to differentiate between 2 devices sharing the same PID. In the same
way, changing the device name is useful when the device export 3 nodes,
all with the same name.
Link: https://lore.kernel.org/r/20240608-hid_bpf_struct_ops-v3-16-6ac6ade58329@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
The idea is to provide a list of stucts and their editable fields.
Currently no functional changes are introduced here, we will add some
more writeable fields in the next patch.
Acked-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/r/20240608-hid_bpf_struct_ops-v3-15-6ac6ade58329@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
Without this helpers like bpf_printk() or bpf_map_update() are not
available, making anything but change of bytes impossible to do.
Link: https://lore.kernel.org/r/20240608-hid_bpf_struct_ops-v3-14-6ac6ade58329@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
There is no real reasons to paper over warnings for such small programs.
Link: https://lore.kernel.org/r/20240608-hid_bpf_struct_ops-v3-13-6ac6ade58329@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
warning: unused variable ‘tilt’ [-Wunused-variable]
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Link: https://lore.kernel.org/r/20240608-hid_bpf_struct_ops-v3-12-6ac6ade58329@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
We can now rely on struct_ops as we cleared the users in-tree.
Link: https://lore.kernel.org/r/20240608-hid_bpf_struct_ops-v3-8-6ac6ade58329@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
Very mechanical:
- Change HID_BPF_DEVICE_EVENT and HID_BPF_RDESC_FIXUP #defines
- add a matching SEC(".struct_ops.link")
- in ArtistPro16Gen2 make the 2 functions static and have a new one
calling them
Link: https://lore.kernel.org/r/20240608-hid_bpf_struct_ops-v3-7-6ac6ade58329@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
We are going to switch over struct_ops, so instead of having to manually
replace all fields one by one, let's have a common place to change it.
Link: https://lore.kernel.org/r/20240608-hid_bpf_struct_ops-v3-6-6ac6ade58329@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
We do this implementation in several steps to not have the CI failing:
- first (this patch), we add struct_ops while keeping the existing infra
available
- then we change the selftests, the examples and the existing in-tree
HID-BPF programs
- then we remove the existing trace points making old HID-BPF obsolete
There are a few advantages of struct_ops over tracing:
- compatibility with sleepable programs (for hid_hw_raw_request() in
a later patch)
- a lot simpler in the kernel: it's a simple rcu protected list
- we can add more parameters to the function called without much trouble
- the "attach" is now generic through BPF-core: the caller just needs to
set hid_id and flags before calling __load().
- all the BPF tough part is not handled in BPF-core through generic
processing
- hid_bpf_ctx is now only writable where it needs be
Acked-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/r/20240608-hid_bpf_struct_ops-v3-3-6ac6ade58329@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|
|
no code change, but this way we reduce code duplication and we
can export it later.
Link: https://lore.kernel.org/r/20240608-hid_bpf_struct_ops-v3-2-6ac6ade58329@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
|