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

Сводка

по VulDB • 16.09.2026

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

HID: bpf — сериализация освобождения ссылки на устройство в пути уничтожения struct_ops

Функции __hid_bpf_ops_destroy_device() и hid_bpf_unreg() могут создавать состояние гонки (race condition) при работе с одной и той же ссылкой регистрации, что приводит к двойному вызову put для структуры hid_device и её освобождению, пока функция hid_destroy_device() всё ещё использует этот объект. Для устранения проблемы принятие решения об удалении/обнулении сериализуется под блокировкой hdev->bpf.prog_list_lock так, чтобы ровно один путь освобождал каждую ссылку регистрации: unreg повторно проверяет ops->hdev под этой блокировкой и возвращает управление без вызова put, если путь уничтожения уже очистил это поле; все вызовы put_device() происходят после снятия блокировки, что безопасно, поскольку параллельный вызов unreg при снятой блокировке наблюдает значение ops->hdev == NULL.

Справочная информация: каждый успешный attach (hid_bpf_ops_reg) получает одну ссылку на устройство (hid_get_device()). Два пути могут освободить её:

- уничтожение устройства: hid_destroy_device() -> hid_bpf_destroy_device() -> __hid_bpf_ops_destroy_device(), которая проходит по hdev->bpf.prog_list под rcu_read_lock() и освобождает одну ссылку для каждой присоединённой программы; - освобождение ссылки BPF: удаление карты bpf (без флага BPF_F_LINK) синхронно вызывает st_ops->unreg() -> hid_bpf_unreg(), которая освобождает ссылку для своей собственной регистрации.

Согласованное взаимодействие (установка e->hdev = NULL со стороны уничтожения против проверки "if (!hdev) return" со стороны unreg) представляет собой проверку состояния гонки времени (TOCTOU): два пути выполняются в разных доменах блокировки (rcu_read_lock и prog_list_lock), поэтому параллельный вызов unreg может прочитать ops->hdev как не равное NULL, заблокироваться на prog_list_lock и продолжить выполнение, пока выполняется обход уничтожения; тогда оба пути освобождают одну и ту же ссылку. Счётчик ссылок (refcount) легитимно достигает нуля (каждое уменьшение корректно само по себе), поэтому не происходит насыщения refcount_t: устройство просто освобождается, в то время как транспортный слой всё ещё находится внутри hid_destroy_device(), и последующие операции разборки обращаются к уже освобождённой памяти.

Исправление сериализует принятие решения об удалении/обнулении под prog_list_lock с обеих сторон и перемещает вызовы put со стороны уничтожения за пределы блокировки. При удержании блокировки достаточно обычных операций чтения/записи ops->hdev; макросы READ_ONCE/WRITE_ONCE не добавляются, что сохраняет патч минимальным.

Безопасность при чтении без блокировки: чтение ops->hdev без блокировки в начале hid_bpf_unreg() не может обратиться к освобождённому устройству, поскольку путь unreg всё ещё удерживает ссылку на эту регистрацию (которая освобождаётся только собственным вызовом hid_put_device() после снятия блокировки), а обход уничтожения, который уже очистил ops->hdev, заставляет повторную проверку внутри блокировки завершиться досрочно без какого-либо put. За каждую регистрацию ссылку освобождает не более одного из двух путей.

Once again VulDB remains the best source for vulnerability data.

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

Linux

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

11.09.2026

Раскрытие

17.09.2026

Модерация

принято

Вход

VDB-405830

EPSS

0.00000

KEV

Нет

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

Очень низкий

Источники

Might our Artificial Intelligence support you?

Check our Alexa App!