Уязвимость эксплуатируется без состояния гонки, потому что ошибка возникает не из-за одновременного доступа, а из-за статического дефекта: ядерная функция копирования (copy_from_user / copy_to_user) возвращает частичный результат, а код драйвера или подсистемы игнорирует возвращаемое значение. Это позволяет атакующему передать специально сформированный пользовательский буфер, который вызовет неполное копирование (например, страница с ошибкой доступа, нулевая длина, невыровненный адрес). После этого ядро использует мусорные или неполные данные, приводя к переполнению буфера, утечке памяти или выполнению произвольного кода — без необходимости гонки, так как весь процесс однопоточный.
Причины
- Программист не проверяет возвращаемое значение `copy_from_user()` или `copy_to_user()`.
- Для эксплуатации не требуются race conditions – атакующий просто подаёт буфер, при котором копирование срывается (например, последняя страница пользовательского буфера не отображена).
- Пример: CVE-2022-29582 – io_uring не проверяет `copy_from_user()` при обработке IORING_OP_SENDMSG, что позволяет записать произвольные данные в стек ядра.
Решение
1. В коде обязательно проверять статус копирования и прерывать обработку при неполном/неуспешном копировании:
c
if (copy_from_user(kbuf, uptr, size)) {
/ очистка и возврат -EFAULT /
return -EFAULT;
}2. Использовать `copy_struct_from_user()` (Linux 5.5+), которая гарантирует полное копирование и проверяет возврат.
3. Включать статический анализ (Coverity, smatch) для поиска необработанных возвратов копирования.
4. При форензике искать в логах ядра сообщения о частичных копированиях (если есть дополнительное логгирование) или анализировать аномалии в дампах памяти (структуры с неожиданными значениями, указывающие на непроверенное копирование).