Ebpf verifier repair
Making eBPF verifier errors as friendly as Rust compiler errors, and let LLM fix it.
npx -y skills add eunomia-bpf/bpfix --skill ebpf-verifier-repairAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 18 stars18 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
End-to-end workflow for diagnosing and repairing eBPF verifier rejections in C, Rust/Aya, libbpf, libbpf-rs, BCC, bpftool, and CI logs from raw verbose verifier logs, BPFix diagnostics, or source/test failures. Use when Codex is asked to fix, explain, or patch verifier errors, verifier logs, BPFIX diagnostics, packet bounds, nullable pointer, stack initialization, reference lifetime, scalar range, pointer provenance, compiler lowering artifact, helper/kfunc/dynptr/iterator, RCU/IRQ/lock, environment capability, or verifier budget failures.
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
8.3 KB, as published. Nobody here has run it
eBPF Verifier Repair
Overview
Repair verifier failures as missing proof obligations, not as string-matched
terminal errors. A full verbose verifier log plus source is sufficient evidence
to start; use bpfix only when it is available and helpful. Make the smallest
verifier-visible source change that preserves program semantics and proves the
required safety fact to the kernel verifier.
Do not split work into one skill per verifier error family. BPFIX-E*,
failure_class, and next_action values are routing signals inside this
workflow; the reusable user job is "repair this verifier rejection."
Resource Routing
- Read
references/log-collection.mdwhen the user did not provide a full verbose verifier log, the log is incomplete, or the framework/loader command is unclear. - Read
references/raw-log-triage.mdwhenever repairing from a raw verifier log. Use its rejected-instruction and proof-lifecycle procedure before selecting a source rewrite. - Read
references/diagnostic-routing.mdonly when a BPFix diagnostic is provided or generated. Do not block raw-log repair on this file. - Read
references/repair-patterns.mdbefore editing source, selecting a verifier-visible rewrite, or reviewing a proposed patch. - Read
references/semantic-preservation.mdbefore editing a nontrivial program, especially when it updates maps, emits events, has fallback policy, or uses multiple acquired resources. - Read
references/failure-directed-retry.mdafter any candidate fails to compile, load, or pass the semantic oracle. Route the next edit by the failure stage instead of starting a new speculative repair. - Run
scripts/run-bpfix-diagnostic.shonly when BPFix is available and a repeatable plain-text diagnostic artifact would make the repair loop clearer. - Run
scripts/extract_verifier_failure.py verifier.logwhen a raw log is too large for the working context. Keep the original log and inspect omitted PCs when the initial slice does not reveal proof origin or loss.
Repair Workflow
-
Establish the failing load path. Identify the loader command, framework, BPF source file, compiled object if available, kernel/program type, and the exact command that produced the rejection. Preserve the full verbose verifier/build/load log; the final
Permission deniedorinvalid argumentline is not enough. -
Choose the evidence path. If only source and a raw verbose verifier log are available, work directly from them. Find the rejected instruction, terminal verifier message, register state, helper call, source annotation, and the earlier branch or check that should have established the missing proof. Do not wait for BPFix.
If BPFix is available and the user did not ask for a raw-log-only repair, it can add proof-aware plain-text evidence:
bpfix verifier.log bpfix --fail-on-unsupported verifier.log > bpfix-diagnostic.txt bpfix --object prog.o verifier.logIf this skill is checked out with the BPFix repo, the helper script can produce a repeatable plain-text artifact:
skills/ebpf-verifier-repair/scripts/run-bpfix-diagnostic.sh --out .bpfix-agent verifier.log skills/ebpf-verifier-repair/scripts/run-bpfix-diagnostic.sh --object prog.o verifier.log -
Route by proof evidence, not by prose alone. Inspect the diagnostic class, safety/confidence labels, next action, required proof, source spans, and verifier evidence when a diagnostic exists. With raw logs, infer the same facts manually from the rejected PC, register classes/ranges, helper arguments, and source lines. If the log is incomplete, fix log collection first. If the evidence points to environment/configuration failure, confirm kernel/program-type/helper/BTF availability before editing source.
-
Freeze the semantic contract. List the observable behavior that the repair must preserve: program section and return actions, packet or context fields consumed, map keys and values, state mutations, event contents, helper calls, resource lifecycle, fallback behavior, and meaningful branch outcomes. Read the project's tests and loader when available. Distinguish a safety guard from a policy decision; do not turn a missing proof into a new policy.
-
Form a proof-obligation hypothesis. State the fact the verifier could not prove at the rejected instruction: packet bounds, non-nullness, initialized stack bytes, live reference release, scalar range, pointer provenance/type, alignment, helper/kfunc contract, dynptr protocol, execution context, or complexity bound. Name where the proof is established, lost, or missing.
-
Edit the source minimally and verifier-visibly. Prefer rewrites that keep the checked value and the used value in the same verifier-visible path. Revalidate after helpers that invalidate pointers. Re-derive pointers from checked bases near use when compiler lowering or branch merging hides provenance. Do not add unrelated checks or broad casts that change semantics without proving the required fact.
-
Validate the repair. Rebuild the BPF object, rerun the original load/replay command, and rerun
bpfixon any new verifier log only if BPFix was part of the evidence path. A successful repair means the original rejection no longer appears, no new verifier rejection replaces it, and the project's semantic oracle still passes. If a stage fails, followreferences/failure-directed-retry.mdand make the next edit answer that evidence. When privileged loading is not available, run compile/tests and explain the remaining verification gap. -
Report the result in proof terms. Summarize the changed proof, the files touched, the validation command and result, and any kernel/environment assumption that remains.
Source Editing Rules
- For full-source repairs, return a complete compilable source file. Preserve
includes, map definitions, helper prototypes,
SEC()sections, license, constants, function names, and loader-visible symbols unless the evidence specifically requires changing them. - Preserve BPF program semantics first; verifier acceptance is not sufficient if the runtime behavior changes.
- Keep fixes local to the rejected proof path unless evidence shows a shared helper, macro, or abstraction owns the missing proof.
- Do not delete functionality, weaken filters, change return values, remove map operations, or replace helper calls merely to make the verifier accept the program.
- When a candidate fails to compile or is malformed, fix syntax, braces, includes, macros, and complete-source formatting before changing verifier logic.
- When a candidate loads but fails the project's oracle, treat that as a real semantic regression. Reopen the proof hypothesis and preserve the original dataflow, side effects, and observable outputs.
- Treat
lowering_artifactas a bytecode-shape problem: duplicate small branches, keep pointer values typed, or rederive from a tracked base instead of only adding a source-level check that may lower away. - Treat
verifier_false_positiveandhelp_safety: triage_onlyas cautious triage: simplify the relation or test another kernel before claiming a source bug. - Prefer framework-native idioms: libbpf C helpers/macros for C programs, Aya APIs for Rust loaders/programs, and BCC conventions for Python/C snippets.
- Do not hide verifier-sensitive code behind opaque helper calls unless the verifier can inline or otherwise see the proof.
Completion Criteria
Finish only after one of these is true: the verifier load/replay passes; the project's available test path passes and the missing privileged verifier step is explicitly documented; or the evidence shows the issue is environment-only and the correct non-source change is identified.