{"id":24688,"date":"2026-09-16T20:32:38","date_gmt":"2026-09-16T12:32:38","guid":{"rendered":"https:\/\/www.54iter.cn\/?vuln=cve-2026-90000"},"modified":"2026-09-16T20:32:38","modified_gmt":"2026-09-16T12:32:38","slug":"cve-2026-90000","status":"publish","type":"vuln","link":"https:\/\/www.54iter.cn\/?vuln=cve-2026-90000","title":{"rendered":"CVE-2026-90000 &#8211; In the Linux kernel, the following vulnerability has been resolved:\n\nHID: rmi: fix OOB acc"},"content":{"rendered":"<p>In the Linux kernel, the following vulnerability has been resolved:<\/p>\n<p>HID: rmi: fix OOB access with undersized RMI reports<\/p>\n<p>The hid-rmi driver sizes its writeReport\/readReport buffer purely from<br \/>\nthe report descriptor supplied by the device, with no minimum bound:<\/p>\n<p>\tdata-&gt;input_report_size  = hid_report_len(input_report);<br \/>\n\tdata-&gt;output_report_size = hid_report_len(output_report);<br \/>\n\talloc_size = data-&gt;output_report_size + data-&gt;input_report_size;<br \/>\n\tdata-&gt;writeReport = devm_kzalloc(&amp;hdev-&gt;dev, alloc_size, GFP_KERNEL);<br \/>\n\tdata-&gt;readReport = data-&gt;writeReport + data-&gt;output_report_size;<\/p>\n<p>but then reads and writes fixed offsets into it.  A device declaring a<br \/>\n1-byte output and a 1-byte input report makes hid_report_len() return 2<br \/>\nfor each, so alloc_size is 4, while rmi_set_page() &#8212; reached<br \/>\nunconditionally at probe time through rmi_input_configured() &#8212; stores<br \/>\nwriteReport[4] and rmi_hid_read_block() stores writeReport[0..5].  Since<br \/>\nreadReport lives at writeReport + output_report_size, those stores also<br \/>\ncorrupt the window the next reply is parsed out of.<\/p>\n<p>The read path is worse: the copy length comes from readReport[1], which<br \/>\nthe device fills in and can be up to 255, and the copy starts at<br \/>\n&amp;readReport[2] with no regard for input_report_size, so it runs past the<br \/>\nend of the allocation into adjacent slab objects.  This does not even<br \/>\nneed a lying device &#8212; rmi_f01_probe() issues a fixed 21-byte register<br \/>\nread, so any device declaring an input report smaller than 23 bytes<br \/>\nreads out of bounds even when it answers truthfully.  Those bytes become<br \/>\nthe register values the RMI core acts on: rmi_f01_probe() prints them to<br \/>\nthe kernel log as the product id and exports them through the mode 0444<br \/>\nsysfs attribute of the same name, and rmi_driver_set_irq_bits() sends<br \/>\nthem back to the device as the interrupt mask, so an undersized report<br \/>\ndescriptor leaks heap contents both to unprivileged userspace and to the<br \/>\ndevice itself.<\/p>\n<p>The write path has no bound either: rmi_hid_write_block() copies an<br \/>\nunbounded len to &amp;writeReport[4], and the largest caller a device can<br \/>\ndrive at probe time is rmi_driver_set_irq_bits(), whose length is<br \/>\nderived from the interrupt source counts the device declares in its Page<br \/>\nDescription Table.<\/p>\n<p>Finally, the read loop cannot terminate on a zero-length reply: such a<br \/>\nreply copies nothing and advances neither bytes_read nor bytes_needed,<br \/>\nand because a reply did arrive the one second wait_event_timeout() does<br \/>\nnot fire either, so a device answering 0 forever keeps the loop running<br \/>\ninside the probe worker with page_mutex held.  khungtaskd does not<br \/>\nnotice, because every reply wakes the task.<\/p>\n<p>Reject reports too small for what the driver builds &#8212; 6 output bytes<br \/>\nfor the write reports and 3 input bytes for the read handshake &#8212; at<br \/>\nprobe time, clamp the write and the read copy to the report sizes the<br \/>\ndevice declared, and treat a zero-length reply as an error.  A device<br \/>\nrefused this way is started as an ordinary HID device, like one that<br \/>\ndoes not carry the RMI report ids at all.<\/p>\n<p>RMI_DEVICE must not be left set in device_flags on that path, because<br \/>\nrmi_input_configured() would then run the RMI setup and reach<br \/>\nrmi_set_page(), which writes the writeReport buffer the refusal just<br \/>\nskipped allocating.  The bit can arrive set: rmi_probe() copies<br \/>\nid-&gt;driver_data into device_flags before the report checks, and a bind<br \/>\nthrough the new_id sysfs attribute can supply driver_data with<br \/>\nRMI_DEVICE (BIT(0)) set.  Strip the bit where driver_data is copied, so<br \/>\nRMI_DEVICE keeps meaning exactly &#8220;this probe validated the reports&#8221;; the<br \/>\nthree jumps to start that predate this patch are covered as well.<\/p>\n<p>The error path also clears RMI_READ_DATA_PENDING on its way out, because<br \/>\nthat flag is what the wait at the top of the loop tests: leaving it set<br \/>\nwould make every later wait_event_timeout() return immediately on the<br \/>\nstale reply and kill the read path for the rest of the device&#8217;s life.<\/p>\n<p>Clamping does not regress working hardware: the read loop already<br \/>\nhandles<br \/>\n&#8212;truncated&#8212;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the Linux kernel, the following vulnerability has been resolved:<\/p>\n<p>HID: rmi: fix OOB access with undersized RMI reports<\/p>\n<p>The hid-rmi driver sizes its writeReport\/readReport buffer purely from<br \/>\nthe re<\/p>\n","protected":false},"template":"","meta":[],"categories":[],"tags":[],"class_list":["post-24688","vuln","type-vuln","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/vuln\/24688","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/vuln"}],"about":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/types\/vuln"}],"wp:attachment":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=24688"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=24688"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=24688"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}