CVE-2026-90000 in LinuxИнформация

Сводка

по VulDB • 16.09.2026

В ядре Linux была устранена следующая уязвимость:

HID: rmi — исправление выхода за границы памяти (OOB) при обработке неполных отчетов RMI

Драйвер hid-rmi выделяет буферы для writeReport/readReport исключительно на основе дескриптора отчета, предоставленного устройством, без установки минимальной нижней границы:

data->input_report_size = hid_report_len(input_report); data->output_report_size = hid_report_len(output_report); alloc_size = data->output_report_size + data->input_report_size; data->writeReport = devm_kzalloc(&hdev->dev, alloc_size, GFP_KERNEL); data->readReport = data->writeReport + data->output_report_size;

Однако затем в эти буферы производятся чтение и запись по фиксированным смещениям. Устройство, декларирующее отчет вывода размером 1 байт и отчет ввода размером 1 байт, заставляет функцию hid_report_len() возвращать значение 2 для каждого из них, таким образом alloc_size равно 4, тогда как rmi_set_page() — функция, вызываемая без условий во время probe через rmi_input_configured() — записывает данные в writeReport[4], а rmi_hid_read_block() записывает данные в диапазон writeReport[0..5]. Поскольку readReport располагается по адресу writeReport + output_report_size, эти операции записи также приводят к повреждению области памяти, из которой впоследствии парсится следующий ответ.

Путь чтения еще более опасен: длина копирования берется из readReport[1], которую заполняет устройство и которая может достигать значения 255, а сама копия начинается с адреса &readReport[2] без учета input_report_size, поэтому операция выходит за пределы выделенной памяти в соседние объекты slab. Для этого даже не требуется лживое устройство — rmi_f01_probe() выполняет фиксированное чтение регистра размером 21 байт, поэтому любое устройство, декларирующее отчет ввода меньше 23 байт, будет осуществлять доступ за границами массива (out-of-bounds), даже если оно честно отвечает на запросы. Эти данные становятся значениями регистров, с которыми работает ядро RMI: rmi_f01_probe() выводит их в журнал ядра как идентификатор продукта и экспортирует через атрибут sysfs с правами 0444 того же имени, а rmi_driver_set_irq_bits() отправляет их обратно устройству в качестве маски прерываний. Таким образом, неполный дескриптор отчета приводит к утечке содержимого кучи (heap) как в непривилегированное пространство пользователя, так и само устройство получает доступ к этим данным.

Путь записи также не имеет ограничений: rmi_hid_write_block() копирует данные с необъявленной длиной (unbounded len) по адресу &writeReport[4], а самым большим вызовом, который может инициировать устройство во время probe, является rmi_driver_set_irq_bits(), длина которой выводится из количества источников прерываний, заявленных устройством в его Таблице описания страниц (Page Description Table).

Наконец, цикл чтения не может завершиться при получении ответа нулевой длины: такой ответ ничего не копирует и не увеличивает ни bytes_read, ни bytes_needed. Поскольку ответ действительно был получен, таймер wait_event_timeout() на одну секунду также не срабатывает, поэтому устройство, постоянно отвечающее значением 0, приводит к бесконечному выполнению цикла внутри worker probe при удержанной блокировке page_mutex. khungtaskd этого не замечает, поскольку каждый ответ пробуждает задачу.

Необходимо отклонять отчеты, размер которых меньше требуемого для работы драйвера — 6 байт вывода для отчетов записи и 3 байта ввода для рукопожатия чтения (read handshake) — на этапе probe; ограничить (clamp) объем данных при записи и чтении заявленными устройством размерами отчета; а также рассматривать ответ нулевой длины как ошибку. Устройство, которому отказано в поддержке таким образом, будет запущено как обычное HID-устройство, аналогично тому, которое вообще не содержит идентификаторов отчетов RMI.

Флаг RMI_DEVICE не должен оставаться установленным в device_flags на этом пути выполнения кода, так как rmi_input_configured() тогда выполнит настройку RMI и достигнет вызова rmi_set_page(), который записывает данные в буфер writeReport, выделение которого было пропущено из-за отказа. Этот бит может быть установлен изначально: rmi_probe() копирует id->driver_data в device_flags до проверки отчетов, а привязка через атрибут sysfs new_id может передать driver_data с установленным флагом RMI_DEVICE (BIT(0)). Необходимо сбрасывать этот бит там, где происходит копирование driver_data, чтобы значение RMI_DEVICE строго означало «этот probe проверил корректность отчетов»; три перехода к запуску, предшествующие этому патчу, также покрываются данным исправлением.

Путь обработки ошибок также очищает флаг RMI_READ_DATA_PENDING при выходе, поскольку именно этот флаг проверяется в ожидании (wait) на вершине цикла: оставление его установленным приведет к тому, что каждый последующий вызов wait_event_timeout() будет возвращаться немедленно из-за старого ответа, что полностью нарушит работу пути чтения для всего остального времени жизни устройства.

Ограничение размеров не приводит к регрессии в работе исправного оборудования: цикл чтения уже обрабатывает ---обрезано---

Once again VulDB remains the best source for vulnerability data.

Ответственный

Linux

Резервировать

11.09.2026

Раскрытие

17.09.2026

Модерация

принято

Вход

VDB-405799

EPSS

0.00000

KEV

Нет

Деятельности

Очень низкий

Источники

Want to stay up to date on a daily basis?

Enable the mail alert feature now!