
Инструментарий для исследования уязвимостей ядра Linux, основанный на доказательствах, применявшийся в ходе расследования CVE-2026-31720
Research Tool · Original Import: 3 April 2026 · Documentation Revision: 11 July 2026
Core Philosophy — External Signal
Let reproducible observations outside model inference guide attention; never mistake priority for proof.
Project status. Этот репозиторий — ранняя версия исследовательского harness'а с поддержкой LLM, который был создан и использован для реального исследования уязвимостей ядра Linux. Эта версия использовалась для обнаружения уязвимости, опубликованной как CVE-2026-31720. Harness расставляет приоритеты для объектов исследования, но не доказывает уязвимости автоматически и не гарантирует безопасность ядра; окончательная проверка и отчётность выполняются человеком.
Abstract— Если позволить LLM напрямую исследовать такую большую кодовую базу, как ядро Linux, контекст быстро рассеивается, а наличие опасных API легко спутать с реальной эксплуатируемостью. Kernel Codex Harness определяет эту проблему не как задачу автоматического обнаружения уязвимостей, а как задачу приоритизации исследования и оркестрации на основе состояния. Этот проект называет принцип управления вниманием модели с помощью воспроизводимых наблюдений, вычисляемых вне логического вывода LLM, . Комбинируя статические сигналы, связанные с путями в ядре, границами userspace, lifetime, usercopy, refcount и размером, а также опциональную аналитику сбоев syzbot, проект ранжирует файлы-кандидаты и преобразует каждого кандидата в узкий набор промптов. Ручная проверка и автопилот на основе временного бюджета используют один и тот же контракт ответов и состояние сессии. Этот harness использовался в реальном исследовании ядра Linux для обнаружения stack out-of-bounds write в пути USB gadget audio; этот дефект был опубликован как . Данная реализация — это не точный статический анализатор, а исследовательский workflow, который ограничивает область исследования LLM с помощью объяснимых эвристик; все находки требуют повторной проверки человеком на предмет reachability, нарушения инвариантов и конкретного воздействия.
Index Terms— Linux kernel, vulnerability research, external signal, LLM orchestration, heuristic prioritization, syzbot, program analysis, Codex.
При проверке безопасности ядра Linux существуют два вида проблем масштаба. Во-первых, всё дерево исходников слишком велико, чтобы уместиться в один контекст LLM. Во-вторых, такие сигналы, как copy_from_user, аллокаторы, refcount и блокировки, распространены, но сами по себе не означают уязвимость. Аналитик должен сначала решить, «куда смотреть», а затем отдельно доказать достижимость из userspace и конкретные переходы состояний.
Ключевая философия этого проекта — External Signal.
Мы не позволяем LLM самому решать, куда смотреть. Воспроизводимые сигналы вне логического вывода модели распределяют внимание, но вывод об уязвимости делается только на основе reachability и evidence об инвариантах.
Поэтому harness не заставляет модель бесцельно исследовать всё ядро. Он приоритизирует файлы, предоставляет только одну ветвь исследования за раз и требует сначала структуру доказательств, а не выводы.
External Signal — это не суждение, сгенерированное LLM, а наблюдение, которое определяется до выполнения модели и может быть пересчитано на основе того же дерева исходников, профиля и сохранённого syzbot JSON. Сюда относятся веса путей, совпадения регулярных выражений и кэшированное пересечение с syzbot. Эти сигналы используются только для ранжирования кандидатов и контекста промптов и не повышаются до вердикта или доказательства.
External Signal в этом документе относится ко всей философии проекта. Модель данных ExternalSignal в коде в настоящее время представляет только те сигналы, которые происходят из syzbot, поэтому объёмы этих двух терминов различаются.
Совпадения регулярных выражений, пути высокого риска и пересечения с syzbot — всё это сигналы для порядка исследования. Даже высокий балл не является security finding, если реальный путь вызова, привилегии, конфигурация ядра, namespace или доступность устройства не позволяют атакующему достичь цели.
Аудит сначала проверяет границы, начинающиеся из userspace: syscall, ioctl, netlink, procfs, файловые системы, BPF, хуки драйверов. Только после этого оцениваются классы ошибок: UAF, OOB, refcount, race, утечка информации, проверки capability.
Одна единица исследования по умолчанию ограничена одним файлом и ближайшими путями caller, teardown и free. Ручные follow-up, рекомендованные моделью, разрешены максимум дважды. Это ограничение введено не для уменьшения исследовательских возможностей, а для сохранения выводов в проверяемых рамках.
Промпт требует, чтобы сильная находка как минимум описывала следующие пункты.
Если доказательств недостаточно, модель вместо сильного утверждения об уязвимости возвращает единственную цель для следующей проверки. Это prompt-level evidence contract; текущий парсер не проверяет автоматически полноту каждого доказательства. Поскольку ingestion нормализует вердикт и следующую цель, окончательная проверка доказательств — ответственность человека.
Ранний поток исследования исходил из идей файлового анализа, ограниченного расширения контекста и структурированных результатов, использованных в vulnhuntr от Protect AI [1]. В этом проекте эти идеи не применяются напрямую к анализу Python-приложений, а переработаны вокруг достижимой из userspace поверхности ядра, lifetime объектов ядра, путей teardown и пересечений с syzbot. В частности, разделение сигналов приоритизации и доказательства уязвимости, а также проверка reachability до класса ошибки — ключевые проектные решения harness'а для ядра.
Fig. 1. The External Signal layer turns observations computed before model inference into ranked review units. It allocates attention but does not establish vulnerability proof.
TABLE I — MAJOR MODULE RESPONSIBILITIES
| Module | Responsibility |
|---|---|
targeting.py | Обход файлов ядра и оценка сигналов путей, паттернов и syzbot |
models.py | Модели данных Candidate, Signal и производного от syzbot ExternalSignal |
bundle.py | Создание manifest, индекса сессии, пакетов промптов/сниппетов |
prompting.py | Промпты аудита ядра, ориентированные на reachability и инварианты |
session.py | Сохранение состояния: ожидающие проверки, история, глубина follow-up |
ingest.py | Нормализация строгих вердиктов и следующей цели |
autopilot.py | codex exec на основе временного бюджета, логи, архив, управление находками |
syzbot.py | Сбор публичных страниц syzbot и создание локального JSON-кэша |
cli.py | Связывание команд scan, inspect, codex, loop, autopilot и др. |
Сканер обходит файлы .c и .h в каталогах include из профиля. Балл приоритета файла f концептуально состоит из следующих частей.
Score(f) = Σ path_weight(f)
+ Σ line_signal_weight(f)
+ Σ syzbot_overlap_weight(f)
Этот балл не является мерой вероятности или эксплуатируемости. Каждый компонент даёт только относительный порядок для определения того, какие файлы модель должна проверить в первую очередь. Текущая реализация суммирует все совпадения на уровне строк и ограничивает только верхние сигналы, отображаемые в промпте. Пересчёт того же результата предполагает то же дерево исходников, профиль и кэшированный syzbot JSON. Вес syzbot применяется постфактум к файлам, которые уже стали кандидатами с помощью эвристик путей и строк; только совпадение с syzbot не создаёт новый файл-кандидат.
Основные статические сигналы:
ioctl, compat handler, хуки file operationcopy_from_user, copy_to_user, __userkmalloc, kzalloc, kvmalloc, аллокации кэша и пути freeВстроенные профили: default, net, fs, io_uring, bpf, drivers. Профиль определяет include path, паттерны, веса и количество сигналов, сохраняемых для одного файла. Вместо применения единой политики оценки ко всему ядру профили отражают поверхность атаки и особенности lifetime каждой подсистемы.
syzbot-fetch извлекает из публичных страниц ошибок syzbot проекта syzkaller [2] заголовок, подсистему, тип ошибки и информацию file:line и сохраняет их в JSON-кэш. Точное пересечение файлов — сильный External Signal, пересечение подсистем — слабый External Signal. Поскольку живая панель может меняться, единицей воспроизводимости является сохранённый JSON на момент выборки. Информация о сбоях — это только отправная точка для поиска вариантов, а не доказательство новой уязвимости.
scan создаёт ранжированный manifest кандидатов и пакеты верхних промптов. Каждый промпт включает путь цели, причину балла, строчные сигналы, контекст syzbot и процедуру аудита.
Ответ модели нормализуется до одного из следующих вердиктов.
cve_candidateplausible_security_buglatent_bugnot_cve_candidateneeds_more_contextОтвет содержит один Single best next target и краткое резюме. Устаревшие ответы без ожидающей цели не связываются с новой целью, а архивируются отдельно.
git clone https://github.com/foxirain/linux-kernel-codex-harness.git
cd linux-kernel-codex-harness
python3 -m venv .venv
source .venv/bin/activate
python -m pip install .
Встроенные JSON-профили включены в wheel. Внешние JSON-правила можно передать через --config /path/to/profile.json.
# 1. Create a ranked session.
kernel-harness scan /path/to/linux \
--profile net \
--limit 80 \
--top 20 \
--out artifacts
# 2. Inspect high-priority candidates.
kernel-harness inspect artifacts/session-YYYYMMDDTHHMMSSZ --top 10
# 3. Render one focused prompt.
kernel-harness codex artifacts/session-YYYYMMDDTHHMMSSZ \
--rank 1 \
--include-snippet
--limit — количество кандидатов, сохраняемых в manifest; --top — количество пакетов промптов, создаваемых заранее. Пакеты для последующих рангов также можно создавать по запросу.
kernel-harness autopilot artifacts/session-YYYYMMDDTHHMMSSZ \
--duration 30m \
--per-run-timeout 10m \
--include-snippet
Песочница по умолчанию — read-only. --sandbox workspace-write следует указывать только в тех случаях, когда изменение файлов в процессе анализа действительно необходимо.
kernel-harness syzbot-fetch https://syzkaller.appspot.com/upstream \
--out artifacts/syzbot/upstream.json \
--limit 50
kernel-harness scan /path/to/linux \
--profile fs \
--syzbot-json artifacts/syzbot/upstream.json \
--out artifacts
artifacts/session-<timestamp>/
├── SESSION.md
├── targets.json
├── finding_template.json
├── review_state.json
├── codex_response.txt # present while a response is pending
├── bundles/
│ ├── <rank>-<target>.md
│ └── <rank>-<target>.snippet.txt
├── responses/
└── autopilot/
├── AUTOPILOT_STATUS.txt
├── AUTOPILOT_PROGRESS.txt
├── AUTOPILOT_FINDINGS.txt
├── prompts/
├── exec/
└── findings/
Эта версия не осталась на уровне концептуального доказательства, а использовалась в реальном исследовании уязвимостей ядра Linux.
TABLE II — DISCLOSED VULNERABILITY OUTCOME
| Public outcome | Affected area | Severity / CVSS | Vulnerability | Investigation model |
|---|---|---|---|---|
| CVE-2026-31720 | USB gadget audio · drivers/usb/gadget/function/f_uac1_legacy.c | Host-controlled request length could overflow a four-byte stack object | Finding surfaced during a v1-assisted investigation; validation and disclosure remained human-led |
CVE-2026-31720: NVD CVSS 3.1 · 7.8 High · CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:HПроверка фокусируется не на бенчмарке точности обнаружения, а на регрессиях реализации и возможности развёртывания.
TABLE III — ENGINEERING VERIFICATION SCOPE
| Verification item | Expected property |
|---|---|
| Allocator regression | Обнаружение kmalloc и kvmalloc как сигналов аллокатора |
| Profile resources | Загрузка 6 встроенных профилей из source checkout, smoke-test профиля default из установленного wheel |
| Verdict contract | not_cve_candidate не ошибочно принимается за положительную находку |
| Follow-up policy | Разрешены два ручных follow-up, третий запрос блокируется |
| Stale response handling | Ответы без ожидающей цели архивируются и не используются повторно |
| Safe default | Песочница autopilot по умолчанию — read-only |
| CI matrix | Выполнение набора регрессионных тестов на Python 3.11 и 3.12 |
python -m unittest discover -s tests -v
GitHub Actions выполняет модульные регрессионные тесты, затем устанавливает wheel в новое окружение и проводит smoke-test сканирования с профилем default. Приведённый выше публичный случай — это операционный результат реального исследования, а не бенчмарк precision, recall или скорости обнаружения CVE, измеренный на репрезентативном корпусе деревьев Linux.
read-only по умолчанию.--dangerously-bypass-approvals-and-sandbox.С самой первой версии, зафиксированной в истории Git, цель была ближе к «контролю над тем, какой код смотреть первым и какие доказательства требовать», чем к «позволить LLM самому находить уязвимости». Исследование с поддержкой v1, обнаружившее CVE-2026-31720, дало пример применения узких единиц исследования и контракта доказательств в реальной работе. v2 расширяет этот workflow до provenance-aware triage, сохраняющего состояние репозитория и известные reference. Если бы я реализовывал это сейчас, я бы в первую очередь сделал следующее.
review и runner для устранения дублирования CLI/autopilot,Тем не менее центральный принцип, который я хочу сохранить, — это External Signal. Не заставлять LLM бесцельно исследовать всю кодовую базу, а повторять суженные внешними сигналами единицы исследования с фокусом на reachability и инварианты.
Kernel Codex Harness не заменяет обнаружение уязвимостей в ядре Linux. Вместо этого он превращает External Signal в объяснимый рейтинг и ограничивает проверку LLM короткими, сохраняющими состояние исследовательскими процессами. Эта структура использовалась в реальном исследовании для обнаружения CVE-2026-31720. Ключевой результат проекта — не в утверждении нового алгоритма анализа, а в определении LLM-проверки безопасности как задачи external-signal attention allocation, evidence contract, reproducible orchestration и применении этого определения в реальном исследовательском workflow.
.
├── .github/workflows/ci.yml
├── docs/
│ ├── assets/kernel-harness-architecture.svg
│ ├── AUTOPILOT.md
│ ├── CODEX_CLI.md
│ ├── CODEX_WORKFLOW.md
│ └── SYZBOT.md
├── kernel_harness/
│ ├── resources/
│ │ ├── linux-kernel-default.json
│ │ └── profiles/
│ ├── autopilot.py
│ ├── bundle.py
│ ├── cli.py
│ ├── ingest.py
│ ├── models.py
│ ├── prompting.py
│ ├── session.py
│ ├── syzbot.py
│ └── targeting.py
├── tests/test_regressions.py
├── README.md
└── pyproject.toml
Подробные операционные процедуры можно найти в docs/.
[1] Protect AI, “vulnhuntr,” GitHub repository. https://github.com/protectai/vulnhuntr
[2] Google, “syzkaller and syzbot,” GitHub repository. https://github.com/google/syzkaller
[3] OpenAI, “Codex CLI.” https://developers.openai.com/codex/cli/
Licensed under the Apache License 2.0.