CVE-2025-38016

Severity CVSS v4.0:
Pending analysis
Type:
Unavailable / Other
Publication date:
18/06/2025
Last modified:
18/06/2025

Description

In the Linux kernel, the following vulnerability has been resolved:<br /> <br /> HID: bpf: abort dispatch if device destroyed<br /> <br /> The current HID bpf implementation assumes no output report/request will<br /> go through it after hid_bpf_destroy_device() has been called. This leads<br /> to a bug that unplugging certain types of HID devices causes a cleaned-<br /> up SRCU to be accessed. The bug was previously a hidden failure until a<br /> recent x86 percpu change [1] made it access not-present pages.<br /> <br /> The bug will be triggered if the conditions below are met:<br /> <br /> A) a device under the driver has some LEDs on<br /> B) hid_ll_driver-&gt;request() is uninplemented (e.g., logitech-djreceiver)<br /> <br /> If condition A is met, hidinput_led_worker() is always scheduled *after*<br /> hid_bpf_destroy_device().<br /> <br /> hid_destroy_device<br /> ` hid_bpf_destroy_device<br /> ` cleanup_srcu_struct(&amp;hdev-&gt;bpf.srcu)<br /> ` hid_remove_device<br /> ` ...<br /> ` led_classdev_unregister<br /> ` led_trigger_set(led_cdev, NULL)<br /> ` led_set_brightness(led_cdev, LED_OFF)<br /> ` ...<br /> ` input_inject_event<br /> ` input_event_dispose<br /> ` hidinput_input_event<br /> ` schedule_work(&amp;hid-&gt;led_work) [hidinput_led_worker]<br /> <br /> This is fine when condition B is not met, where hidinput_led_worker()<br /> calls hid_ll_driver-&gt;request(). This is the case for most HID drivers,<br /> which implement it or use the generic one from usbhid. The driver itself<br /> or an underlying driver will then abort processing the request.<br /> <br /> Otherwise, hidinput_led_worker() tries hid_hw_output_report() and leads<br /> to the bug.<br /> <br /> hidinput_led_worker<br /> ` hid_hw_output_report<br /> ` dispatch_hid_bpf_output_report<br /> ` srcu_read_lock(&amp;hdev-&gt;bpf.srcu)<br /> ` srcu_read_unlock(&amp;hdev-&gt;bpf.srcu, idx)<br /> <br /> The bug has existed since the introduction [2] of<br /> dispatch_hid_bpf_output_report(). However, the same bug also exists in<br /> dispatch_hid_bpf_raw_requests(), and I&amp;#39;ve reproduced (no visible effect<br /> because of the lack of [1], but confirmed bpf.destroyed == 1) the bug<br /> against the commit (i.e., the Fixes:) introducing the function. This is<br /> because hidinput_led_worker() falls back to hid_hw_raw_request() when<br /> hid_ll_driver-&gt;output_report() is uninplemented (e.g., logitech-<br /> djreceiver).<br /> <br /> hidinput_led_worker<br /> ` hid_hw_output_report: -ENOSYS<br /> ` hid_hw_raw_request<br /> ` dispatch_hid_bpf_raw_requests<br /> ` srcu_read_lock(&amp;hdev-&gt;bpf.srcu)<br /> ` srcu_read_unlock(&amp;hdev-&gt;bpf.srcu, idx)<br /> <br /> Fix the issue by returning early in the two mentioned functions if<br /> hid_bpf has been marked as destroyed. Though<br /> dispatch_hid_bpf_device_event() handles input events, and there is no<br /> evidence that it may be called after the destruction, the same check, as<br /> a safety net, is also added to it to maintain the consistency among all<br /> dispatch functions.<br /> <br /> The impact of the bug on other architectures is unclear. Even if it acts<br /> as a hidden failure, this is still dangerous because it corrupts<br /> whatever is on the address calculated by SRCU. Thus, CC&amp;#39;ing the stable<br /> list.<br /> <br /> [1]: commit 9d7de2aa8b41 ("x86/percpu/64: Use relative percpu offsets")<br /> [2]: commit 9286675a2aed ("HID: bpf: add HID-BPF hooks for<br /> hid_hw_output_report")

Impact