Получить практические навыки динамического тестирования ядра Linux с использованием инструмента Syzkaller. Собрать учебное ядро с санитайзерами и инструментацией покрытия, развернуть QEMU-гостя с образом Debian, настроить и запустить syz-manager, проанализировать отчёт о найденной ошибке.
Ядро Linux — самый массово используемый программный продукт в истории. Оно работает на серверах, Android-смартфонах, маршрутизаторах и встроенных системах. Ошибка в ядре — не просто сбой приложения. Она может привести к полной компрометации системы (повышение привилегий, отказ в обслуживании, утечка информации).
Тестирование ядра является сложной задачей, так как пространство возможных состояний бесконечно, а классические модульные тесты покрывают лишь малую долю сценариев. Фаззинг (fuzzing) решает эту проблему. Вместо написания тестов вручную генерируется большое количество случайных, но синтаксически корректных программ, которые подаются на вход ядра.
Syzkaller — coverage-guided фаззер для ядра Linux, разработанный в Google и ставший стандартом. Он описывает API ядра на специальном языке syzlang, генерирует корректные последовательности системных вызовов, измеряет покрытие через механизм KCOV и отслеживает сбои по выводу терминала машины и санитайзеры (KASAN, UBSAN, LOCKDEP, KMEMLEAK).
В домашнем задании требуется:
Результаты работы необходимо представить в виде отчёта, оформленного по требованиям нормоконтроля, принятого на кафедре ПМиФИ ОмГТУ.
Задание выполняется на Ubuntu (нативной или в WSL 2). Выполняется на локальной машине, не требует финансовых вложений и аренды серверов.
Структура этапов выполнения ДЗ соответствует структуре разделов и подразделов отчёта
1.1. Установите системные пакеты и инструменты разработки:
sudo apt update
sudo apt install -y \
build-essential git curl wget make gcc flex bison \
libssl-dev libelf-dev libelf1 \
qemu-system-x86 qemu-utils \
debootstrap cpio \
openssh-client
1.2. Установите актуальную стабильную версию Go (рекомендуется через официальный tarball; актуальную версию проверяйте на go.dev/dl):
GO_VERSION=1.27.2
wget "https://dl.google.com/go/go${GO_VERSION}.linux-amd64.tar.gz"
sudo tar -C /usr/local -xzf "go${GO_VERSION}.linux-amd64.tar.gz"
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
source ~/.bashrc
go version
1.3. Проверьте доступность KVM (аппаратного ускорения QEMU):
ls -la /dev/kvm
kvm), то QEMU будет использовать KVM, фаззинг будет быстрымРезультат данного раздела: подготовленный хост с Go и QEMU; зафиксировано, есть ли доступ к KVM.
2.1. Клонируйте репозиторий ядра Linux и зафиксируйте ветку (рекомендуется ветка linux-6.12.y):
mkdir -p ~/syzkaller-task
cd ~/syzkaller-task
git clone --branch linux-6.12.y --depth 1 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git linux
cd linux
git log --format='%h %s' -1
2.2. Сгенерируйте базовую конфигурацию ядра и добавьте опции, необходимые для syzkaller:
make defconfig
make kvm_guest.config
2.3. Включите обязательные и рекомендуемые опции. Добавьте в конец файла .config минимальный набор:
CONFIG_KCOV=y
CONFIG_KCOV_INSTRUMENT_ALL=y
CONFIG_KCOV_ENABLE_COMPARISONS=y
CONFIG_DEBUG_FS=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
CONFIG_KASAN=y
CONFIG_KASAN_INLINE=y
CONFIG_UBSAN=y
CONFIG_FAULT_INJECTION=y
CONFIG_FAULT_INJECTION_DEBUG_FS=y
CONFIG_FAILSLAB=y
CONFIG_FAIL_PAGE_ALLOC=y
CONFIG_NAMESPACES=y
CONFIG_USER_NS=y
CONFIG_CONFIGFS_FS=y
CONFIG_SECURITYFS=y
CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE="net.ifnames=0"
Рекомендуемые дополнительные опции:
CONFIG_DEBUG_KMEMLEAK=y
CONFIG_LOCKDEP=y
CONFIG_PROVE_LOCKING=y
CONFIG_DEBUG_ATOMIC_SLEEP=y
CONFIG_PROVE_RCU=y
CONFIG_FORTIFY_SOURCE=y
CONFIG_HARDENED_USERCOPY=y
CONFIG_DETECT_HUNG_TASK=y
2.4. Примените изменения конфигурации и проверьте итоговый .config:
make olddefconfig
grep -E 'CONFIG_(KCOV|KASAN|DEBUG_INFO|DEBUG_FS)=' .config
2.5. Соберите ядро:
make -j$(nproc)
2.6. Убедитесь, что образ ядра создан:
ls -l arch/x86/boot/bzImage
Результат данного раздела: собранное ядро
bzImageс включёнными KCOV и KASAN; зафиксирован точный коммит исходников и итоговый.config.
3.1. Скачайте официальный скрипт syzkaller для создания образа и запустите его (по умолчанию создаёт Debian trixie — актуальный stable-релиз Debian, список релизов):
mkdir -p ~/syzkaller-task/image
cd ~/syzkaller-task/image
wget -O create-image.sh https://raw.githubusercontent.com/google/syzkaller/master/tools/create-image.sh
chmod +x create-image.sh
sudo ./create-image.sh
3.2. Убедитесь, что образ и SSH-ключ созданы:
ls -l trixie.img trixie.id_rsa
chmod 600 trixie.id_rsa
Результат данного раздела: образ гостевой системы
trixie.imgи SSH-ключtrixie.id_rsaс правами 600.
4.1. Клонируйте и соберите Syzkaller (рекомендуется закрепить конкретный коммит для воспроизводимости):
cd ~/syzkaller-task
git clone https://github.com/google/syzkaller.git syzkaller
cd syzkaller
git log --format='%h %s' -1
make
ls -l bin/
makeсобирает syzkaller для архитектуры хоста.
4.2. Создайте конфигурационный файл myconfig.json:
{
"target": "linux/amd64",
"http": "0.0.0.0:56741",
"workdir": "/home/<user>/syzkaller-task/workdir",
"kernel_obj": "/home/<user>/syzkaller-task/linux",
"image": "/home/<user>/syzkaller-task/image/trixie.img",
"sshkey": "/home/<user>/syzkaller-task/image/trixie.id_rsa",
"syzkaller": "/home/<user>/syzkaller-task/syzkaller",
"procs": 4,
"type": "qemu",
"vm": {
"count": 1,
"kernel": "/home/<user>/syzkaller-task/linux/arch/x86/boot/bzImage",
"cpu": 2,
"mem": 2048
}
}
Замените
/home/<user>на реальный путь вашего пользователя.
Если kvm на вашей машине недоступен, добавьте в блок "vm" конфигурации ключ и значение
"qemu_args": "-cpu qemu64", не забудьте про запятую и валидность JSON
Результат данного раздела: собранный syzkaller, валидный конфигурационный файл.
5.1. Запустите syz-manager (из директории, где лежит myconfig.json):
~/syzkaller-task/syzkaller/bin/syz-manager -config myconfig.json
Для остановки используйте
Ctrl+C, syz-manager корректно завершит работу и сохранит состояние корпуса вworkdir.
5.2. Откройте веб-интерфейс в браузере: http://127.0.0.1:56741. Убедитесь, что он открывается.
5.3. Дождитесь признаков работающего фаззинга (подождите минут 15, предварительно зафиксировав время старта syz-manager):
corpus (количество программ в корпусе) растёт;coverage (процент покрытия) растёт или стабилизируется;execs (общее число выполненных программ) растёт непрерывно.5.4. Сделайте скриншоты дашборда с ненулевыми corpus и coverage.
5.5. Проверьте и зафиксируйте наличие (или отсутствие) сбоев в разделе crashes.
Результат данного раздела: скриншот дашборда с растущим corpus; таблица динамики corpus/coverage; отмечено, были ли обнаружены сбои.
Если syzkaller нашёл хотя бы один сбой (раздел crashes на дашборде и соответствующая директория workdir непусты), то:
6.1. Перейдите в ~/syzkaller-task/workdir/crashes/ и откройте любой файл отчёта.
6.2. Прочитайте отчёт и зафиксируйте в анализе:
Если за время фаззинга сбоев не было, то это также нормальная ситуация (актуальные LTS-ядра хорошо протестированы, логично). В этом случае возьмите готовый учебный отчёт и проанализируйте его по шагу 6.2.
Результат данного раздела: анализ отчёта о сбое (или учебного отчёта) с указанием контекста ошибки.
Отчет обязательно должен содержать:
Отчёт оформляется в соответствии с требованиями
Для списка источников отдельные требования к оформлению
Домашнее задание считается выполненным, если оно подписано, загружено через электронный кабинет ОмГТУ и принято преподавателем
Преподаватель оставляет за собой право отклонить работу без объяснения причин, если оформление отчёта и/или списка источников не соответствует требованиям нормоконтроля