
Harness de recherche de vulnérabilités du noyau Linux sensible à la provenance, utilisé dans l'investigation de la CVE-2026-53075
Outil de recherche · Import d'origine : 3 avril 2026 · Révision de la documentation v2 : 11 juillet 2026
Signal externe : de l'allocation de l'attention au triage sensible à la provenance
Utilisez des observations reproductibles pour guider l'attention du modèle, puis utilisez la provenance du dépôt pour organiser les files de revue — jamais pour prétendre à une preuve.
Lignée du projet — Kernel Codex Harness v1 · Allocation de l'attention → Kernel Codex Harness v2 · Triage sensible à la provenance
Statut du projet. Ce dépôt est un harnais de recherche assisté par LLM qui fait évoluer le workflow d'allocation de l'attention de v1 vers un triage sensible à la provenance pour la recherche réelle de vulnérabilités dans le noyau Linux. Cette version a été utilisée pour découvrir la vulnérabilité publiée sous le nom CVE-2026-53075. Il ne s'agit pas d'un détecteur automatique de vulnérabilités, d'un juge de nouveauté, d'un validateur d'exploit ni d'un outil d'assurance de sécurité du noyau ; la validation finale et le rapport sont effectués par des humains.
Abstract— Faire explorer directement une base de code aussi vaste que le noyau Linux à un LLM disperse le contexte et confond facilement la présence d'API dangereuses avec une exploitabilité réelle. Kernel Codex Harness v2 définit ce problème en deux étapes de traitement du signal externe. Avant l'appel au modèle, les poids de chemin, les correspondances lexicales et le chevauchement syzbot mis en cache classent les fichiers candidats pour répartir l'attention. Après la réponse du modèle, la branche Git, le HEAD, l'état dirty et les marqueurs CVE, commit et known extraits de la réponse sont combinés pour classer les findings forts dans des buckets de revue sensibles à la provenance. Ce harnais a été utilisé dans une recherche réelle sur le noyau Linux pour découvrir un défaut de vérification des permissions du network namespace cible de PPP, publié sous le nom CVE-2026-53075. Le triage est une heuristique qui organise la file d'investigation ; en particulier, new_candidate signifie seulement qu'aucun indice connu ni problème de provenance n'a été trouvé, et non une preuve de nouveauté. Tous les findings exigent une revalidation humaine de l'atteignabilité depuis l'espace utilisateur, de la rupture d'invariant et de l'impact concret.
Index Terms— noyau Linux, recherche de vulnérabilités, signal externe, provenance, triage heuristique, orchestration LLM, syzbot, Codex.
La revue de sécurité du noyau comporte deux types d'incertitude distincts.
Le problème central de v1 était le premier, à savoir l'allocation de l'attention. v2 conserve ce principe tout en étendant le second problème au triage sensible à la provenance. Les deux versions ont chacune été utilisées dans des recherches réelles : l'investigation assistée par v1 a conduit à CVE-2026-31720, et l'investigation assistée par v2 a conduit à CVE-2026-53075.
Les observations hors modèle réduisent le périmètre d'investigation, et après la réponse du modèle, une provenance de dépôt vérifiable est attachée. Aucun signal, à aucune étape, ne prouve une vulnérabilité ou une nouveauté.
Le signal externe pré-inférence n'est pas un jugement du LLM mais une observation calculée avant l'exécution du modèle.
Avec la même arborescence source, le même profil et le même JSON syzbot mis en cache, le classement des candidats peut être recalculé. Ce score n'est ni une probabilité ni une exploitabilité, mais un ordre relatif pour décider où regarder en premier.
L'étape post-inférence combine un verdict fort du modèle avec les informations suivantes.
Dans ce document, le signal externe post-inférence désigne uniquement la provenance collectée indépendamment du modèle, comme le dépôt/statut Git, la branche, le HEAD, l'état dirty et l'ascendance des commits locaux. Les marqueurs CVE, commit et known sont des références dérivées du modèle extraites de la réponse du modèle, et non un signal externe ni un fait faisant autorité. Le triage combine les deux types d'entrées mais enregistre leur source séparément.
Un finding fort est opérationnellement classé dans l'un des buckets de revue suivants.
| Bucket | Signification |
|---|---|
new_candidate | Candidat dont la provenance est confirmée et pour lequel aucun signal bloquant dirty/known n'a été détecté |
known_issue | Candidat avec une référence connue non niée, ou un commit que la réponse désigne comme correctif/relation upstream et qui est inclus dans le HEAD actuel |
dirty_tree_suspect | Candidat dont l'influence d'un dépôt dirty ou d'une cible dirty ne peut être exclue |
provenance_unknown | Candidat dont le dépôt Git, le statut ou le HEAD n'a pas pu être confirmé de manière fiable |
Pour tous les résultats de classification, novelty_proven est false. new_candidate ne signifie pas « nouvelle vulnérabilité » mais une file prioritaire pour qu'un humain poursuive l'investigation de nouveauté.
L'audit vérifie d'abord les frontières initiées depuis l'espace utilisateur, comme syscall, ioctl, netlink, procfs, les systèmes de fichiers, BPF et les hooks de pilotes. Ce n'est qu'ensuite que les classes de bugs telles que UAF, OOB, refcount, race, fuite d'informations et vérification de capacités sont évaluées.
Une unité d'investigation est limitée à un fichier et à ses chemins proches d'appelants, de teardown et de libération. Les suivis manuels proposés par le modèle sont limités à deux au maximum afin de maintenir des chemins courts et vérifiables plutôt qu'une exploration large.
Un finding fort doit au minimum expliquer ce qui suit.
Le parseur normalise le verdict et la cible suivante, mais ne prouve pas automatiquement la complétude de ces preuves.
Le flux initial s'inspire de l'analyse par fichier, de l'extension limitée du contexte et des résultats structurés utilisés par vulnhuntr de Protect AI [1]. Dans ce projet, cela a été redessiné pour la surface du noyau atteignable depuis l'espace utilisateur, la durée de vie des objets du noyau, les chemins de teardown et le chevauchement syzbot. La contribution supplémentaire de v2 est l'ajout d'une étape de triage des findings utilisant la provenance du dépôt après l'allocation de l'attention.
Fig. 1. Le signal externe pré-inférence classe des unités de revue reproductibles. Le triage post-inférence combine la provenance Git indépendante du modèle avec les références de réponse dérivées du modèle, sans traiter ces dernières comme un signal externe ni un fait faisant autorité. La validation humaine reste en dehors des deux étapes automatisées.
TABLEAU I — RESPONSABILITÉS DES MODULES PRINCIPAUX
| Module | Responsabilité |
|---|---|
targeting.py | Exploration des fichiers du noyau et score des signaux path, lexical et syzbot |
models.py | Candidate, Signal, ExternalSignal dérivé de syzbot |
bundle.py | Génération du manifeste, de l'index de session et des bundles prompt/extrait |
prompting.py | Prompts d'audit du noyau centrés sur l'atteignabilité et les invariants |
session.py | Stockage de l'état : revue en attente, historique, profondeur de suivi |
ingest.py | Normalisation du verdict strict et de la cible suivante unique |
repo_state.py | Collecte de la branche Git, du HEAD, du statut, des chemins dirty et de l'ascendance |
finding_triage.py | Classification heuristique en buckets basée sur la provenance et les références connues |
autopilot.py | Exécution Codex basée sur un budget de temps, ingest, archivage, enregistrement des findings |
syzbot.py | Collecte du HTML public syzbot et génération du cache JSON local |
cli.py | Connexion des commandes scan/review/doctor/autopilot |
Le scanner parcourt les fichiers .c et .h sous le répertoire include du profil.
Score(f) = Σ path_weight(f)
+ Σ line_signal_weight(f)
+ Σ syzbot_overlap_weight(f)
L'implémentation actuelle additionne les correspondances au niveau des lignes et limite uniquement le nombre de signaux principaux affichés dans le prompt. Le score détermine l'ordre d'investigation du modèle mais n'est pas une valeur statistique calibrée pour la probabilité de vulnérabilité.
Les principaux signaux statiques sont les suivants.
__user| Profil | Focus |
|---|---|
default | Points de départ kernel/mm/net/fs/security/io_uring/lib/drivers |
net | netlink, socket, skb, XDP |
fs | ioctl, procfs, seq_file, debugfs |
io_uring | Durée de vie des requêtes asynchrones et teardown |
bpf | Verifier, durée de vie map/programme, BTF |
drivers | ioctl, DMA, MMIO et teardown des pilotes |
syzbot-fetch extrait le titre, le sous-système, le type de bug et le fichier:ligne des pages de bugs publiques syzbot et les enregistre en JSON. Un chevauchement exact de fichier est un signal de classement fort ; un chevauchement de sous-système est un signal faible. Le tableau de bord en direct pouvant changer, l'unité de reproduction est le JSON enregistré au moment de la collecte. Le chevauchement de crash est un indice pour la chasse aux variantes, pas une preuve de vulnérabilité.
scan génère le manifeste complet des candidats classés et les bundles de prompts principaux. --limit est le nombre de candidats conservés dans le manifeste et --top est le nombre de bundles pré-générés. Les rangs suivants peuvent également être générés à la demande.
La réponse du modèle est normalisée en l'un des verdicts suivants.
cve_candidateplausible_security_buglatent_bugnot_cve_candidateneeds_more_contextLa revue manuelle et l'autopilot utilisent le même review_state.json, le même chemin de réponse fixe et le même parseur de verdict.
doctor et l'autopilot vérifient la présence d'un dépôt Git, le succès de la collecte du statut, la branche, le HEAD et les chemins dirty. Un état dont la provenance ne peut pas être établie n'est pas considéré comme clean mais conservé comme provenance_unknown.
Le triage d'un verdict fort suit approximativement la priorité suivante.
provenance_unknown,dirty_tree_suspect,known_issue,new_candidate.Les expressions de négation ou de non-relation comme « not a known issue », « unrelated to CVE-… » ne sont pas utilisées comme base de known. La décision finale conserve le verdict d'origine ainsi que la branche, le HEAD, le statut, l'état dirty, la référence correspondante et la raison.
Actuellement, la classification en buckets sensible à la provenance et l'écrivain JSONL s'appliquent au chemin d'ingest de l'autopilot. Les loop et ingest manuels utilisent le même état de session de base et le même parseur de verdict, mais ne produisent pas d'artefact de bucket.
La dépendance d'exécution Python ne comprend que la bibliothèque standard.
git clone https://github.com/foxirain/linux-kernel-codex-harness-v2.git
cd linux-kernel-codex-harness-v2
python3 -m venv .venv
source .venv/bin/activate
python -m pip install .
kernel-harness --help
Les profils JSON intégrés sont inclus dans la wheel. Des règles supplémentaires peuvent être transmises via --config /path/to/profile.json.
# 1. Vérifier la provenance du dépôt.
kernel-harness doctor /path/to/linux
# 2. Créer une session classée.
kernel-harness scan /path/to/linux \
--profile net \
--limit 80 \
--top 20 \
--out artifacts
# 3. Inspecter et rendre une revue ciblée.
kernel-harness inspect artifacts/session-YYYYMMDDTHHMMSSZ --top 10
kernel-harness codex artifacts/session-YYYYMMDDTHHMMSSZ \
--rank 1 \
--include-snippet
Les réponses Codex manuelles sont enregistrées dans codex_response.txt comme spécifié par le runbook, puis peuvent être ingérées avec la commande suivante.
kernel-harness loop artifacts/session-YYYYMMDDTHHMMSSZ --include-snippet
kernel-harness status artifacts/session-YYYYMMDDTHHMMSSZ
kernel-harness autopilot artifacts/session-YYYYMMDDTHHMMSSZ \
--duration 30m \
--per-run-timeout 10m \
--include-snippet \
--require-clean-tree \
--stop-on-finding
La valeur par défaut du sandbox Codex est read-only. --require-clean-tree n'autorise l'exécution que si le dépôt Git, le statut et le HEAD sont confirmés et que l'arbre de travail est clean. --stop-on-finding s'arrête uniquement lorsque le résultat du triage heuristique est new_candidate.
kernel-harness syzbot-fetch https://syzkaller.appspot.com/upstream \
--out artifacts/syzbot/upstream.json \
--limit 50
kernel-harness syzbot-stats artifacts/syzbot/upstream.json --top 15
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 # présent lorsque la réponse est en attente
├── bundles/
├── responses/
└── autopilot/
├── AUTOPILOT_STATUS.txt
├── AUTOPILOT_PROGRESS.txt
├── AUTOPILOT_BASELINE.json
├── AUTOPILOT_FINDINGS.txt
├── AUTOPILOT_FINDINGS_NEW.txt
├── AUTOPILOT_KNOWN_ISSUES.txt
├── AUTOPILOT_SUSPECTS.txt
├── AUTOPILOT_PROVENANCE_UNKNOWN.txt
├── AUTOPILOT_FINDINGS.jsonl
├── prompts/
├── exec/
├── parse_errors/
└── findings/
├── new/
├── known/
├── suspects/
└── unknown/
AUTOPILOT_FINDINGS.jsonl conserve le verdict, le bucket, la raison, la branche, le HEAD, l'état de provenance, la référence correspondante et les chemins finding/archive dans un format post-traitable.
v2 a appliqué l'architecture étendue à une recherche réelle de vulnérabilités dans le noyau Linux.
TABLEAU II — RÉSULTAT DE VULNÉRABILITÉ PUBLIÉE
| Résultat public | Zone affectée | Sévérité / CVSS | Vulnérabilité | Modèle d'investigation |
|---|---|---|---|---|
| CVE-2026-53075 | PPP · drivers/net/ppp/ppp_generic.c | Les ioctls administratifs non attachés ne disposaient pas d'une vérification CAP_NET_ADMIN contre le namespace utilisateur propriétaire du network namespace cible | Finding révélé lors d'une investigation assistée par v2 ; la validation et la divulgation sont restées menées par des humains |
CVE-2026-53075 : Enregistrement CVE du CNA Linux · CVSS 3.1 · 8.8 High · CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:HLes 16 tests de régression se concentrent sur le contrat logiciel et la déployabilité, et non sur un benchmark de précision de détection de sécurité.
python -m unittest discover -s tests -v
python -m pip wheel . --no-deps --wheel-dir dist
python -m pip install --force-reinstall dist/*.whl
GitHub Actions exécute les tests de régression sur Python 3.11 et 3.12, installe la wheel, puis effectue un test de fumée sur les 6 profils packagés et un scan par défaut. Le cas public ci-dessus est un résultat opérationnel issu d'une recherche réelle, mais ne constitue pas un benchmark de précision, de rappel, d'exploitabilité ou de taux de découverte de CVE mesuré sur un corpus d'arbres Linux représentatifs.
read-only et il est recommandé de la conserver.doctor puis --require-clean-tree.--dangerously-bypass-approvals-and-sandbox ne doit pas être utilisé en dehors d'un environnement expérimental isolé.new_candidate ni known_issue ne constituent un jugement final de nouveauté.v1 (dépôt) s'est concentré sur le problème de l'allocation de l'attention du LLM par signal externe et a été utilisé dans une investigation réelle assistée par v1 pour découvrir CVE-2026-31720. v2 poursuit la même philosophie de recherche en étendant l'enregistrement de l'état du dépôt et des références dérivées de la réponse même après qu'un modèle a émis un finding fort. Une investigation ultérieure utilisant cette structure a conduit à la découverte de CVE-2026-53075.
v1 : observations source → classement → revue ciblée
v2 : observations source → classement → revue ciblée → triage sensible à la provenance
Deux principes doivent être maintenus dans cette évolution.
Si une nouvelle extension était entreprise, la priorité irait au graphe d'appels Clang/tree-sitter, à la normalisation des scores, au manifeste versionné avec verrouillage d'état inter-processus, à un adaptateur de base de données CVE/correctif faisant autorité, et à la séparation du runner, du triage et de l'écrivain d'artefacts. L'écriture d'état actuelle utilise un fichier temporaire et un remplacement atomique.
Kernel Codex Harness v2 ne remplace pas la détection de vulnérabilités. Avant l'appel au modèle, le signal externe répartit le budget d'investigation sur des candidats explicables ; après l'appel au modèle, le signal de provenance organise les findings forts en files revoyables. Cette structure a été utilisée dans une recherche réelle pour découvrir CVE-2026-53075, et le résultat clé du projet n'est pas un algorithme de jugement automatique de nouveauté, mais un workflow de revue de sécurité LLM en conditions réelles qui sépare explicitement l'allocation de l'attention et le triage sensible à la provenance.
.
├── .github/workflows/ci.yml
├── docs/
│ ├── assets/kernel-harness-v2-architecture.svg
│ ├── AUTOPILOT.md
│ ├── CODEX_CLI.md
│ ├── CODEX_WORKFLOW.md
│ └── SYZBOT.md
├── kernel_harness/
│ ├── resources/
│ │ ├── linux-kernel-default.json
│ │ └── profiles/
│ │ ├── bpf.json
│ │ ├── drivers.json
│ │ ├── fs.json
│ │ ├── io_uring.json
│ │ └── net.json
│ ├── __init__.py
│ ├── __main__.py
│ ├── autopilot.py
│ ├── bundle.py
│ ├── cli.py
│ ├── finding_triage.py
│ ├── ingest.py
│ ├── models.py
│ ├── prompting.py
│ ├── repo_state.py
│ ├── session.py
│ ├── syzbot.py
│ └── targeting.py
├── tests/test_regressions.py
├── .gitignore
├── README.md
└── pyproject.toml
Les opérations manuelles détaillées sont décrites dans le guide CLI Codex, l'exécution automatique et le triage dans le guide Autopilot, et l'intelligence sur les crashes dans le guide syzbot.
[1] Protect AI, « vulnhuntr », dépôt GitHub. https://github.com/protectai/vulnhuntr
[2] Google, « syzkaller and syzbot », dépôt GitHub. https://github.com/google/syzkaller
[3] OpenAI, « Codex CLI ». https://developers.openai.com/codex/cli/
Sous licence Apache 2.0.