[PATCH 2/2] HID: bpf: reject struct_ops registration during device destruction

From: Yifan Zhang

Date: Mon Nov 02 2026 - 07:05:26 EST


hid_bpf_reg() can obtain a device reference before hid_destroy_device()
removes the device from the bus, then block on prog_list_lock while HID-BPF
destruction cleans the device's SRCU state. The registration path does not
check the destroyed flag after taking the lock, so it can publish a new
struct_ops entry and call synchronize_srcu() on the cleaned SRCU object.

KASAN reports:

BUG: KASAN: slab-use-after-free in check_init_srcu_struct
Read of size 8
check_init_srcu_struct
synchronize_srcu
hid_bpf_reg
bpf_struct_ops_link_create

Check destroyed while holding prog_list_lock. The preceding teardown
serialization change sets the flag while holding the same lock, so either a
registration completes before destruction starts or it fails with -ENODEV
without accessing SRCU.

The reproducer no longer triggers a KASAN report with this change.

Fixes: ebc0d8093e8c ("HID: bpf: implement HID-BPF through bpf_struct_ops")
Closes: https://lore.kernel.org/linux-input/179317460937.87455.1799017093083467190@xxxxxxxxxxxxxx/
Signed-off-by: Yifan Zhang <yfzhang23@xxxxxxxxxxxxxx>
---
drivers/hid/bpf/hid_bpf_struct_ops.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/drivers/hid/bpf/hid_bpf_struct_ops.c b/drivers/hid/bpf/hid_bpf_struct_ops.c
index c90b68956cb3b..4c433f419c85e 100644
--- a/drivers/hid/bpf/hid_bpf_struct_ops.c
+++ b/drivers/hid/bpf/hid_bpf_struct_ops.c
@@ -201,6 +201,11 @@ static int hid_bpf_reg(void *kdata, struct bpf_link *link)

mutex_lock(&hdev->bpf.prog_list_lock);

+ if (READ_ONCE(hdev->bpf.destroyed)) {
+ err = -ENODEV;
+ goto out_unlock;
+ }
+
count = list_count_nodes(&hdev->bpf.prog_list);
if (count >= HID_BPF_MAX_PROGS_PER_DEV) {
err = -E2BIG;
--
2.39.5 (Apple Git-154)