Верификация модулей ядра ОС Linux
Ядро ОС Linux состоит из базовых компонентов, реализующих основную функциональность операционной системы (распределение процессорного времени, управление памятью, межпроцессным взаимодействием и т.д.), и подгружаемых модулей, в которые вынесена дополнительная функциональность (файловые системы, сетевые протоколы, драйверы устройств и т.д.). На подгружаемые модули приходится более 70% исходного кода ядра, а внимания их разработке уделяется нередко меньше, чем базовым компонентам. Поэтому неудивительно, что большинство ошибок, приводящих к зависаниям, падениям и некорректной работе всей ОС, содержится именно в исходном коде модулей.
В Центре верификации ведётся работа над двумя проектами, нацеленными на повышение качества подгружаемых модулей ядра ОС Linux. В первом проекте реализуется метод статического анализа исходного кода с целью выявления типовых ошибок в работе модулей ядра, и в первую очередь, драйверов устройств, а во втором разрабатывается система динамического анализа модулей ядра (проект "KEDR").
Технологии статического анализа исходного кода и динамического анализа поведения программ имеют свои достоинства и недостатки и успешно дополняют друг друга. Их основные отличия приведены в следующей таблице:
- "Легковесные" инструменты статического анализа (такие как Sparse и Coccinelle на Linux или PREfast на MS Windows) могут быть использованы разработчиками с самых ранних стадий работы над модулями ядра. Инструменты могут использоваться на компьютерах разработчиков и часто могут быть включены большую часть времени.
- "Тяжеловесные" инструменты (такие как LDV на Linux или Static Driver Verifier на MS Windows), выполняющие более сложный статический анализ, вероятно, стоит использовать, когда большая часть функциональности модуля уже присутствует. Подобные инструменты иногда могут использоваться на машинах разработчиков, но более вероятно их использование на специализированных серверах. Время от времени разработчики загружают туда свой код и затем получают результаты.
Инструменты динамического анализа для разработчиков модуле ядра (модель использования).Инструменты динамического анализа могут быть использованы разработчиками модулей ядра на своих компьютерах, как только разрабатываемые модули можно будет запустить и выполнить с ними какие-то операции. Если модули работают с каким-либо специальным программным обеспечением или оборудованием, может быть сложно развернуть инструменты динамического анализа на внешних серверах, для которых такое оборудование недоступно.
Такие инструменты, как Driver Verifier на MS Windows или KEDR на Linux могут быть использованы на пользовательских компьютерах, чтобы помочь собрать данные о возможных ошибках в модулях ядра. Существует множество конфигураций пользовательских систем и не всегда возможно воспроизвести все эти конфигурации при разработке. Может быть полезно собрать требуемые данные на пользовательских компьютерах напрямую, используя инструменты динамического анализа и посылать собранные данные разработчикам для дальнейшего анализа.
Другой областью, где могут применяться инструменты динамического анализа, является разработка свободных аналогов существующих проприетарных модулей (так Mmiotrace используется для разработки драйверов графики Nouveau для видеокарт NVidia).
Инструменты статического анализа могут использоваться в системах сертификации, но до сих пор не были обязательными (так Static Driver Verifier используется на MS Windows). Вероятно, это связано с возможностью ложных срабатываний (false positives).
Модель использования может быть следующая. Система анализа устанавливается на сервере. Используя службы, предоставляемые этим сервером, можно загрузить исходный код модуля для анализа и затем получить результаты.
Инструменты динамического анализа для систем сертификации модулей ядра (модель использования).Инструменты динамического анализа могут быть использованы в системах сертификации. Подобные инструменты обычно дают меньше ложных срабатываний, чем системы статического анализа, так что если они зафиксируют ошибки в анализируемых модулях, можно считать это основанием для отказа сертификации. Так Driver Verifier используется на MS Windows (Windows Logo Program) и механизмы Novell "API Swapping" на Linux (Novell YES Certified Program).
Модель использования может быть следующей. Система сертификации загружает инструменты динамического анализа и анализируемый модуль и затем запускает ряд тестов для этого модуля. Инструменты следят за работой модуля (a также могут на неё влиять) и выявляют ошибки в этом модуле.
Что касается поиска проблем при обработке ошибок (use-after-free, и т.д.), здесь нельзя сказать, что какой-то из подходов строго лучше, чем другой. Всё сильно зависит от того, насколько длинный путь в коде должен быть проанализирован, чтобы обнаружить проблему.
- Чтобы провести статический анализ модуля ядра, необходима модель среды, в которой исполняется анализируемый модуль. Модель обычно не является абсолютно точной, в конце концов, это же модель.
- Если анализируется конкретный модуль, то необходимы модели модулей, с которыми он взаимодействует, а также модели ядра - и они обычно также не точны.
Как правило, инструменты динамического анализа дают меньше ложных срабатываний, чем инструменты статического анализа (нередко ложных срабатываний нет совсем).Тем не менее, инструменты динамического анализа могут давать ложные срабатыванияю Например, средства для поиска ошибок, связанных с многопоточностью (race conditions, ...) нередко дают ложные срабатывания, когда анализируемая система использует нестандартные механизмы синхронизации.