Repository navigation
feat(kernel-doctor): report Linux kernel CVE evidence, never a verdict - #520
Merged
Merged
Conversation
The 7-day release quarantine lets a security fix through per package with an absolute `exclude-newer-package` cutoff. That cutoff never expires by itself, so once the admitted release is older than the window the entry only freezes the package there and later Dependabot bumps become silent no-ops. That is what scripts/check_uv_exclude_newer.py exists to catch, and it now fails: emulator/pyproject.toml: `certifi` cutoff 2026-10-20 is 9 days old emulator/pyproject.toml: `mlflow` cutoff 2026-10-21 is 8 days old ... mlflow-skinny, mlflow-tracing, and telemetry/examples `certifi` certifi 2026.10.19 (the eMudhra CA removal) and mlflow / mlflow-skinny / mlflow-tracing 3.17.2 (GHSA-wqmh-qccw-pqwf) were admitted on 2026-10-26 with a comment saying to remove them on or after 2026-10-28. Dropping them leaves the repo-authoritative `exclude-newer = "7 days"` span in charge, which now admits those releases on its own. `uv lock` in both projects removes only the lock's `[options.exclude-newer-package]` metadata: no resolved version changes (the diff is 7 deletions, 0 version lines). The `ruff = false, ty = false` entries stay; those are a different mechanism (skip the span so an exact pin can move without waiting out the window).
CVE-2026-98432 (ipv4: free inet_opt and ireq_opt after an RCU grace period) is a real Linux kernel use-after-free, but this repository ships, builds and pins no Linux kernel: the kernel belongs to Microsoft (WSL and its self-hosted runner), to the distribution, or to the container host. There is nothing here to patch, so the honest response is detection and advice. tools/kernel-doctor compares the kernel version a host reports against reviewed, source-cited fix floors in one embedded record. It deliberately refuses to compare anything that is not a clean upstream x.y.z on a reviewed branch: Ubuntu 6.8.0-45-generic and Debian 6.1.0-28-amd64 carry the vendor's own ABI revision, not the upstream patch level, so numeric comparison is wrong in both directions. Unverified is never counted as fixed, and patch_status/backport_state stay unverified on every line. scripts/doctor.sh wires it as advisory only. This repository cannot fix a kernel, so no kernel finding may reach doctor's err count: `just doctor` exiting non-zero would break `just self-check` and test_doctor_sandbox over a condition only the operator can fix, and only outside this repository. The block therefore adds findings to warn only, and downgrades any ERR the checker emits to a single WARN. docs/runbook/kernel-doctor.md records the dispute over severity (NVD/Tenable 9.8 with AC:L versus Oracle's preliminary 8.1 with AC:H; Red Hat priority high, not critical; EPSS 0.00388; not in KEV, which is not proof that no public exploit exists) and the remedy per surface. The WSL kernel and .wslconfig stay unmanaged (ADR-0058, ADR-0064); the runbook carries `wsl --update` as an operator step, to run when no runner job is in flight. ADR-0065 records the decision and is Proposed, tracked in the decision queue.
An independent review of 41551b2 found two real defects and one over-claim. This fixes them. Its third finding did not reproduce; that is recorded rather than patched. 1. The JSON output bypassed the source-freshness check. With a stale or absent --source, the findings said only "run just kernel-doctor-build before trusting any finding", while the same report still carried `at-or-above-reviewed-fix-floor` in `assessments`. Both outputs now come from one evaluate() result, so a comparison is withheld for exactly the reason the line findings are withheld. Reverting the change makes the new test fail, so it does pin the behaviour. 2. A test asserted a macOS-only outcome. It required the assessment list to be empty when no version is obtained, which holds here only because there is no /proc; on Linux the collector succeeds and the list is not empty. The test would have failed `just go-test` on the sandbox after passing locally. run() now takes the host OS and the collector, so every host shape is driven from a test: readable -> one assessment, unreadable -> none. That also makes the documented --osrelease contract literally true. The help says the local /proc and /etc/os-release are not read, but Collect ran unconditionally and only its result was discarded. With injection the override performs no local read at all, which a test asserts by counting collector calls. 3. The CISA KEV observation claimed "CISA has no record of exploitation in the wild". Absence from KEV establishes nothing about exploitation, about public exploits, or about CISA's assessment status. The record and the runbook now say only what was observed: not listed at observation time. The review also reported that a large checker output aborts doctor before the WARN downgrade, via a here-string temp file. Not reproduced: with a verified-unwritable TMPDIR, bash 5.3.20 here-strings handle 20 MB without creating a temp file. The same construct already exists in the CA block, so this is an open constraint for doctor.sh as a whole, not something to patch in one place. docs/plan/kernel-cve-evidence.md records the evidence.
The verification record predated the Tidy First commit and still described the quarantine gate as blocking; 973f7d4 resolved it, so the section now states the SHA it was measured against and what actually remains red. Adds the commit-time review record: the re-measurement of the eight plan-review findings, the three new findings with what confirmed each, the one finding I could not reproduce and why, and the falsifications the review attempted and failed to land.
hironow
added a commit
that referenced
this pull request
Oct 30, 2026
- fix(install): find the mise prek through the latest symlink - fix(install): keep going when corepack enable fails - fix(skills): drop the two skills their upstreams no longer ship - fix(doctor): prune pyright installed as a uv tool - chore(rtk): follow rtk 1.1.0 - test(ollama): skip the real-bind serve tests where ::1 cannot bind - fix(emulator): pin a2a-inspector to its last Python/TypeScript commit - chore(deps): drop expired exclude-newer-package overrides (from #520) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0147hurtFmppBfdZ3M8n8e4V
Owner
Author
Windows 側のチェック検証と ready 化の承認(2026-10-30)所有者より「Windows 側で、更新・再起動・既存処理の停止なしでのチェック検証は OK」と報告され、ready 化の指示を受けました。
記録の push 後に ready 化し、CI の検証は別途確認します。マージは行いません。 |
hironow
marked this pull request as ready for review
October 30, 2026 13:31
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
目的
CVE-2026-98432(Linux カーネル IPv4 TCP の use-after-free)への対応。
このリポジトリは Linux カーネルを同梱・ビルド・固定していないため、「修正を適用する」対応は存在しません。できるのは検出と助言だけです。本 PR はそれを、既存の
ca-doctor/brotli-doctorと同じ規律(証拠であって判定ではない)で追加します。チケットの前提の訂正
チケットは「CVSS 9.8 / リモート / 認証不要 / 容易」でしたが、深刻度には争いがあります。
AC:L(容易)AC:H(競合を勝ち抜く必要)Red Hat の優先度は critical ではなく high(修正版は未確定)。EPSS 0.00388、観測時点で KEV 未収載。到達には「SYNACK 組み立て中の競合」か「
net.ipv4.tcp_migrate_req=1/ BPF reuseport」が必要です。runbook と記録 JSON に両論を併記しました。露出面
wsl --update)WSL カーネルと
.wslconfigを管理しない方針は維持します(ADR-0058 / 0064 は変更していません)。変更
tools/kernel-doctor/(Go、stdlib のみ)— 実行中または報告されたカーネル版を、レビュー済みの出典つき修正床と突き合わせるscripts/doctor.sh— advisory ブロック(CA ブロックには終端マーカーを追加)justfile—kernel-doctor-build/kernel-doctor/kernel-doctor-build-alldocs/runbook/kernel-doctor.md— 面ごとの是正手順docs/adr/0065-kernel-cve-is-evidence-only.md— Proposed(decision-queue に決裁待ちで起票).gitattributes(LF 固定)、.gitignore、tools/README.md設計の核
D2 — ベンダー / ディストロのカーネルは比較しない。 Ubuntu
6.8.0-45-genericや Debian6.1.0-28-amd64の第 3 成分は上流の patch level ではなく、数値比較は両方向に間違えます。比較するのは文字列全体がクリーンな上流形x.y.zで、かつmajor.minorがレビュー済み branch のときだけ。それ以外はunverifiedとし、未判定を修正済みとして数えません。D1 — kernel の所見は doctor の
errに入れない。just doctorの exit 1 はjust self-checkとtest_doctor_sandboxを赤くします。カーネルはこのリポジトリが直せないので、operator がリポジトリ外でしか直せない条件で repo の gate を赤くしません。ツールの自己申告に頼らず、doctor.sh側でも ERR を単一の WARN に落とします。証拠の提示を一箇所に。
evaluate()が line findings と structured assessments を一緒に返すので、鮮度検査が通らなければ両出力とも比較を出しません(実装レビューで見つかった、JSON だけが比較を配っていた欠陥の修正)。レビュー
計画段階と実装後の 2 回(Codex 0.164.0)。記録は
docs/plan/kernel-cve-evidence.mdの §独立レビュー記録 / §実装レビュー記録 に、各指摘をどう確認して採用・反論したかつきで残しています。just go-testを落とす(ローカル緑 → sandbox 赤)。collector を注入してホスト非依存に--jsonが鮮度検査を迂回し、stale な binary でも比較を配っていたTMPDIRでも bash 5.3.20 は 20 MB まで一時ファイルを作らないことを実測。加えて同じ形は CA ブロックにも既存なので、doctor.sh 全体の制約として別件化検証
通った: Go テスト /
just go-test/just go-lint(11 module、0 issues) / ruff format・check / ty / shellcheck / markdownlint / semgrep / D2 受入表 13 行 /kernel-doctor-build-all(6 ターゲット、file(1)で ELF・Mach-O・PE32+) /just lint(repo 全体)走っていない(重要):
just test(sandbox) — このホストで Docker が実行できません(docker probe がPermissionErrorで 111 errors)。test_doctor_sandboxは sandbox 内でjust doctorの exit 0 を要求するので、この leg は ready にして CI が回って初めて実行されますjust check-all(repo が定める push gate)—just testを含むため完走できません/proc経路 / Windows・WSL 実機のカーネル版(クロスビルド成功は実機観測の証明ではありません)既存赤(本ブランチの base で pristine な worktree を作り、同一に再現させて無関係と確認済み):
tests/unit/test_wsl_clipboard.py::test_root_installs_and_repeat_is_noop(macOS 固有)なお
just lint/just checkを落としてどの commit も通せなかったcheck_uv_exclude_newerは、本ブランチの973f7d4が解消しました(期限切れ override 5 件を削除、lock の差分は 7 削除・version 変更 0)。Draft → ready の条件
bfd8d469)。observation にはしない(incidents/*.jsonの全 observation は公開 https の出典を要する。ローカルなuname -rの計測をそこに入れると、出典を捏造するか検証に落ちて全比較が拒否されるかのどちらかになる。所有者の判断で、機体固有の検証は検証記録側に置く)test_doctor_sandbox)の初回結果を確認し、取りこぼしを直すマージ方針
このブランチは 4 commit で、squash merge すると PR タイトルの 1 commit に畳まれます。
973f7d4(chore(deps)の quarantine cleanup)もこのfeatに含まれる扱いとしました(所有者の判断)。commit discipline の「1 commit 1 type」からは外れますが、この cleanup が無いとjust lintがどの commit もブロックしていたため、Tidy First として先頭に置いてあります。