Найти в Дзене
Айтуби / IT to Business

В ЯДРЕ LINUX X86 ГОДАМИ СКРЫВАЛАСЬ ОПАСНАЯ ОШИБКА

В ядре операционной системы Linux специалисты обнаружили серьёзную уязвимость, которая оставалась незамеченной с 2020 года. Она затрагивала один из фундаментальных механизмов — обработку ошибок страниц памяти (page fault) на платформе x86. Этот код активируется каждый раз, когда процессор обнаруживает попытку некорректного доступа к памяти, что делает его критически важным для стабильности всей системы. Проблема заключалась в том, что в определённых сценариях аппаратные прерывания могли оказаться включёнными в моменты, когда ядро гарантированно ожидало их отключенными. Это создавало угрозу нестабильности в редких, но экстремально важных ситуациях, где от абсолютной предсказуемости работы ядра зависит целостность и безопасность системы. На аномалию обратил внимание инженер Intel Седрик Син (Cedric Xing), который проводил детальный аудит кода обработки исключений. Анализ показал, что логика в ключевой функции do_page_fault() основывалась на устаревшем и, по сути, ошибочном предположении.

В ядре операционной системы Linux специалисты обнаружили серьёзную уязвимость, которая оставалась незамеченной с 2020 года. Она затрагивала один из фундаментальных механизмов — обработку ошибок страниц памяти (page fault) на платформе x86. Этот код активируется каждый раз, когда процессор обнаруживает попытку некорректного доступа к памяти, что делает его критически важным для стабильности всей системы.

Проблема заключалась в том, что в определённых сценариях аппаратные прерывания могли оказаться включёнными в моменты, когда ядро гарантированно ожидало их отключенными. Это создавало угрозу нестабильности в редких, но экстремально важных ситуациях, где от абсолютной предсказуемости работы ядра зависит целостность и безопасность системы.

На аномалию обратил внимание инженер Intel Седрик Син (Cedric Xing), который проводил детальный аудит кода обработки исключений. Анализ показал, что логика в ключевой функции do_page_fault() основывалась на устаревшем и, по сути, ошибочном предположении. Даже в комментариях к коду разработчики отмечали, что отслеживание состояния прерываний по всем возможным путям выполнения — это «комбинаторный кошмар», что на годы застопорило решение между точечными правками и страхом что-то сломать.

Оказалось, что корень проблемы глубже поверхностных ошибок. Код некорректно смешивал два разных понятия: тип адреса (пользовательский или ядерный) и контекст выполнения. Хотя обычно они совпадают, существуют исключительные ситуации, когда ядро обращается к своей памяти, но в пользовательском контексте. На некоторых ветках обработки, особенно в функции __bad_area_nosemaphore(), это приводило к тому, что прерывания могли быть ошибочно активированы и система возвращалась в состояние, противоречащее ожиданиям ядра, создавая опасную асимметрию.

В результате команда разработчиков пришла к кардинальному, но элегантному решению. Вместо бесконечного исправления отдельных веток кода, которое напоминало игру в «испорченный телефон», было решено применить жёсткую гарантию. Теперь прерывания безусловно отключаются в одном строго определённом месте — непосредственно перед возвратом управления в низкоуровневый обработчик page fault. Без сложных проверок и догадок о контексте.

Исправления уже включены в основную ветку разработки Linux 6.19. Также запланирован их бэкпорт в предыдущие стабильные версии ядра, что устранит дефект, берущий начало ещё со времён Linux 5.8. Это решение закрывает многолетний потенциальный источник нестабильности, укрепляя один из самых важных механизмов в сердце операционной системы.