[PATCH] HID: core: fix device cleanup on allocation failure
From: Tristan Madani
Date: Fri Sep 04 2026 - 04:11:56 EST
From: Tristan Madani <tristan@xxxxxxxxxxxxxxxxxxx>
hid_allocate_device() calls hid_destroy_device() in its error path when
hid_bpf_device_init() fails. hid_destroy_device() in turn calls
hid_bpf_destroy_device() which invokes synchronize_srcu() and
cleanup_srcu_struct() on the SRCU structure. However, at this point
init_srcu_struct() has not been called (or has failed), so the SRCU
internal pointers are all zeroed from kzalloc. Dereferencing them
causes a general protection fault:
general protection fault in check_init_srcu_struct
KASAN: null-ptr-deref in range [0x00000000000001c0-0x00000000000001c7]
Call Trace:
synchronize_srcu+0x1c/0x2b0
hid_bpf_destroy_device+0x64/0x90
hid_destroy_device+0x29/0x240
hid_allocate_device+0x420/0x4e0
uhid_dev_create2+0x161/0x890
Fix this by replacing hid_destroy_device() with put_device() in the
error path. At this point in hid_allocate_device(), the device has
been initialized (device_initialize) but not yet added (device_add),
so put_device() is the correct cleanup call. It triggers the release
callback which frees the hid_device without attempting to clean up
resources that were never set up.
Found by syzkaller on Ubuntu 6.14.11 KASAN.
Fixes: 6cd735f0e57a ("HID: bpf: protect HID-BPF prog_list access by a SRCU")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Tristan Madani <tristan@xxxxxxxxxxxxxxxxxxx>
---
drivers/hid/hid-core.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index a3ff0514f9cdf..d8df23f67f1fd 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -3115,7 +3115,12 @@ struct hid_device *hid_allocate_device(void)
return hdev;
out_err:
- hid_destroy_device(hdev);
+ /*
+ * hid_destroy_device() cannot be used here because
+ * hid_bpf_device_init() failed and the SRCU struct was never
+ * initialized. Release the device directly.
+ */
+ put_device(&hdev->dev);
return ERR_PTR(ret);
}
EXPORT_SYMBOL_GPL(hid_allocate_device);
--
2.47.3