{"id":13711,"url":"\/distributions\/13711\/click?bit=1&hash=993ce7f10a29e09ef6007450140ef5fcebecd55805799940a93c3efe78cce5e3","title":"\u0411\u043e\u0438\u0442\u0435\u0441\u044c \u043d\u0435\u0434\u043e\u043e\u0446\u0435\u043d\u0451\u043d\u043d\u044b\u0445 \u0431\u0443\u043c\u0430\u0433? \u0412\u043e\u0442 \u043f\u0430\u0440\u0430 \u0441\u043e\u0432\u0435\u0442\u043e\u0432 \u043e\u0442 \u0438\u043d\u0432\u0435\u0441\u0442\u043e\u0440\u043e\u0432","buttonText":"\u0427\u0438\u0442\u0430\u0442\u044c","imageUuid":"9ff620a4-3fae-5002-9694-5d10fe8c5bbf","isPaidAndBannersEnabled":false}

Simics: Забиваем гвозди сваебоем

Любите ли вы отзывчивые программы так, как люблю их я? Любовь эта привела меня к Колибри ОС - невероятно шустрой операционной системе, которая запускает программу до того, как вы осознаете, что кликнули по ней. И недавно у неё нашли уязвимость: ping of death.Так получилось, что моя первая работа была связана с симуляцией компьютерных систем – от серверов до мобильных устройств. И там мы использовали симулятор Simics. Этой системой пользуются крупные производители железа для опережающей разработки драйверов.

Если бы только можно было использовать Simics для отладки любительской ОС...

Часть 0: Проблема

Баг описал пользователь turbocat на форуме: достаточно большой ICMP echo-запрос может убить один из процессов операционной системы или полностью вывести её из строя. Для воспроизведения проблемы нужно пингануть машину с запущенной системой Колибри. А для этого потребуется два компьютера, подключенных к одной локальной сети.

Если бы только Simics мог симулировать компьютерные сети…

Часть 1: Воспроизведение

Симуляция в Simics настраивается с использованием simics-скриптов, которые создают и настраивают устройства. Для воспроизведения можно создать свой скрипт: «targets/linux-kolibri.simics».

Для начала нужна машина с Linux на борту. Это самая простая часть, такая машина включена в базовый дистрибутив Simics, и её можно создать, используя скрипт из пакета «simics-qsp-x86». Он даже сеть автоматически может настроить! Но здесь это не нужно:

Этот скрипт уже можно запустить командой simics linux-kolibri.simics и введя continue в командной строке Simics (изначально симуляция находится в состоянии паузы). После этого видим графику и консоль Linux:

Ещё нужен ПК с установленной Колибри. Его можно создать тем же скриптом, нужно только указать свой образ жесткого диска. А для упрощения работы можно настроить виртуальный USB-планшет - он позволит с комфортом использовать мышь внутри Колибри:

Теперь скрипт запускает две системы:

Но у Колибри проблема: она не распознаёт сетевую карточку. Не беда! В стандартную поставку Simics входит вагон устройств на любой вкус: от USB флешек до видеокарт. Есть и сетевые карточки. Нужно найти ту, которая поддерживается в Колибри ОС:

Среди устройств Simics есть i82543 – должен заработать. Нужно только загрузить одноименный модуль, создать устройство и подключить его к свободному PCIe слоту на северном мосту машины. Главное – не забыть инициализировать новые устройства командой «instantiate-components»:

Вуаля: новая сетевая карта определилась как «I8254x»:

Теперь нужно как-то соединить эти две машины в одну сеть. Для этого достаточно создать коммутатор и подключить к нему сетевые карты машин:

Чтобы не настраивать IP руками, можно поставить локальный DHCP сервер, который присвоит IP адреса автоматически. Для этого существует объект «Service node». Service node - это вообще универсальная штука: и DNS он тебе предоставит, и DHCP, и даже доступ к интернету. Нужно только его настроить: создать на нём шлюз по умолчанию, подключить его к коммутатору и указать пул выдаваемых адресов:

Ну и, конечно же, снова инициализировать все компоненты:

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

Можно запустить этот скрипт и посмотреть IP адреса в Колибри:

И в Linux:

И пингануть Колибри из Линукса:

Система настроена! Теперь можно воспроизводить проблему. Но для начала лучше сохранить текущее состояние симуляции, чтобы не загружать обе системы заново, если что-то пойдет не так: остановить симуляцию командой stop, и выполнить команду:

Текущая конфигурация сохранится в папку «after_boot.ckpt». Её можно будет запустить просто передав Simics название этой папки вместо скрипта: simics after_boot.ckpt.

У нашего Ping of Death два симптома: либо он убивает процесс сетевого драйвера, либо заставляет виснуть всю систему целиком. Возможно, если разобраться с первым случаем, будет исправлен и второй.

В Колибри есть доска отладки, в которую выводятся логи приложений и ядра. Если открыть её в режиме ядра, можно запечатлеть падение процесса драйвера. Но чтобы понять, на каком размере эхо-запроса начинаются проблемы, придется несколько раз запускать ping из консоли Линукса, и если зависание таки произойдёт - перезапускать симуляцию и пинговать заново.

Если бы только Simics позволял автоматизировать работу с ОС…

Часть 2: Автоматизация

Simics скрипты позволяют полностью автоматизировать взаимодействие с симулируемыми системами. Можно написать скрипт «ping-of-death.simics», который самостоятельно загрузит чекпойнт и пинганёт Колибри из Линукса. Скрипт с одним параметром – размер отправляемого echo-запроса. Это надуманный повод познакомить читателя с очередным понятием Это поможет быстрее найти значение, которое роняет драйвер.

Для загрузки чекпойнта в Simics скриптах есть отдельная команда:

А дальше нужно как-то ввести в консоль линукса команду «ping», причём сделать это нужно при запущенной симуляции. Но если написать в скрипте «continue», то следующие команды скрипта не выполнятся, пока пользователь сам не остановит симуляцию, как же быть?

На помощь приходят Script Branches. Они позволяют выполнять команды параллельно с запущенной симуляцией. Можно создать такой, который введёт команду в консоль линукса:

Осталось сделать так, чтобы можно было настроить размер пинга. У каждого скрипта могут быть собственные параметры, которые задаются при запуске. Обычно такие создаются в начале скрипта:

Их можно использовать как обычные переменные:

А чтобы не приходилось вводить «continue» в консоль Simics можно ввести его уже в скрипте, в самом его конце:

С таким скриптом можно спокойно экспериментировать с размерами пингов:

Экспериментальным путём было выявлено, что размер пинга, при котором он перестаёт возвращаться: 1469, но драйвер падает на другом значении: 1473. И, судя по доске отладки, падение вызвано исключением Page Fault:

Если бы только Simics мог показать, где возникло это исключение…

Часть 3: Взятие с поличным

В Simics предусмотрена тонна инструментов для отладки оборудования и драйверов. Например, точки останова: ставим такую на выполнение какого-то действия – и программа останавливается при её достижении. Можно поставить точку останова на вызов нужного исключения процессора:

Тогда симуляция остановится на первом же возникшем Page Fault. Если сделать это в скрипте, то в консоли Simics это не будет никак отражено, он просто поставит симуляцию на паузу и разрешит ввод (simics>). Чтобы посмотреть, на какой инструкции возникло исключение, можно воспользоваться вторым инструментом: отладкой процессора. Начать отладку можно так:

В simics можно загрузить информацию о символах ОС, но, к сожалению, ассемблер, на котором написана Колибри, не умеет генерировать информацию нужного формата. Но к счастью – это ассемблер! А значит, можно выявить строку кода с ошибкой по инструкциям, окружающим этот код.

Внезапно, ECHO-запрос вызывает блок кода «dump» (очевидно, имелось в виду «drop» – отбросить пакет). И если вывести содержимое регистра edi, становится понятно, что оно совсем не такое, какое ожидается:

В edi должен был бы быть индекс сетевого девайса, а лежит какой-то адрес. Но почему? И что привело систему в этот блок?

Если бы только Simics умел выполнять код в обратном направлении…

Вывод

Simics имеет достаточное количество инструментов для разработки и отладки операционных систем, а система скриптов позволяет автоматизировать тестирование и воспроизведение проблем.

Сильные стороны системы:

  • Возможность обратного выполнения кода.
  • Обширный инструментарий для отладки.
  • Богатый скриптовый язык с интегрированным Python.
  • Большое количество эмулируемых девайсов и возможность написания своих.

Слабые стороны:

  • Медлительность ввиду избыточного функционала.
  • Проприетарность.

Лично я предпочитаю использовать её при отладке багов в ядре и для тестирования драйверов. В прочих тестах использую Qemu.

Полный оригинал статьи можно прочитать здесь:

0
Комментарии
Читать все 0 комментариев
null