Re: [PATCH] HID: core: fix device cleanup on allocation failure
Greg KH <[email protected]>
| Newsgroups | org.kernel.vger.linux-input,org.kernel.vger.stable |
|---|---|
| Message-ID | <2026081930-nutlike-jalapeno-1910@gregkh> |
On Wed, Aug 19, 2026 at 01:31:49AM +0000, Tristan Madani wrote: > From: Tristan Madani <[email protected]> > > 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: [email protected] > Signed-off-by: Tristan Madani <[email protected]> > --- > 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 cf123347a2af7..9534de5317783 100644 > --- a/drivers/hid/hid-core.c > +++ b/drivers/hid/hid-core.c > @@ -3060,7 +3060,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. That should be in the changelog, not in the code, as it can, and will, change over time. thanks, greg k-h