Skip to content

Releases: acceptha/bin-cve-patch-guide

v0.2.0 — measurement and distro awareness

Choose a tag to compare

@acceptha acceptha released this 26 Oct 10:14

Measurement and distro awareness: a held-out benchmark set, a benchmark of the gate itself,
per-model gate acceptance, and backport status from the distributions carried into the guide
and enforced by two new gate rules.

Added

  • Backport status (bcpg.match.distro, bcpg scan --distro R --pkg-version V): each
    upstream CVE is open / fixed only in Ubuntu Pro / fixed by a backport / has no distro record,
    from the Debian and Ubuntu records in OSV for the installed package version. Shown in
    report.md (section and column), report.json and the trace. Rules gain distro_package.
  • Holdout benchmark set: 33 libraries from Debian 12, Ubuntu 22.04 and 24.04, extracted
    after the rules were frozen (extract.py --set holdout). Frozen rules: 27/33 exact versions;
    after two rule fixes 29/33; the other four files carry no version string.
  • bcpg gate-bench: false rejections of correct advice (0/540, 18 phrasings) and detection
    of 22 injected fault kinds (572/572), plus two out-of-scope semantic faults (0/54, reported).
  • bcpg model-bench: per-model gate acceptance per batch, rejections by rule letter,
    tokens and time; results merge by model in bench/model_results.md.
  • make fuzz: libFuzzer + ASan/UBSan harness for the C ELF parser in Docker
    (10 minutes, 2.38M inputs, no crash).
  • README.ko.md and docs/design.ko.md (public design-decision record).
  • docs/demo.gif (recorded with vhs docs/demo.tape, offline, no LLM).
  • Distro-aware guide: with --distro, each CVE's backport status goes into the facts (with
    a per-CVE must_say line), the prompt and the template; validator rule (k) rejects an
    action for a CVE the installed package already fixes unless it says so, and a Pro-only fix
    unless it says Pro. Package and release versions (~18.04.23, Ubuntu 20.04) are no longer
    read as invented component versions. Sample: docs/sample/zlib-1.2.11-debian10/.
  • Model benchmark row for qwen2.5 7B (4/9 batches accepted vs 6/9 for exaone3.5 2.4B).
  • make lint; CI also runs ruff format --check.
  • Validator rule (l): input field names (facts.…, allowed_refs, …) in the report text;
    rule (k) also rejects a "not fixed yet" phrase next to a CVE the distribution fixes or has no
    record of. Both from a qwen2.5 7B guide that passed the earlier rules.

Changed

  • Offline OSV misses are logged as one line per run instead of one per CVE (47 lines for a
    holdout libcurl scan before).

Fixed

  • report.md, report.json and trace.json are written with LF on Windows too.
  • Validator rule (i) rejected correct advice that listed protocol versions ("TLS 1.2/1.3");
    found by gate-bench.
  • Rules: libxml2's integer version glued to preceding bytes (::20914, Debian 12); zlib builds
    without copyright banners (bare ZLIB_VERSION, trusted inside libz.so only).

Key numbers: holdout set 29/33 exact versions (27/33 with the frozen rules) · gate 0/540 false rejections, 572/572 targeted faults detected · local LLMs on CPU: exaone3.5 2.4B 6/9 batches accepted, qwen2.5 7B 4/9.

Full changelog: CHANGELOG.md

v0.1.0 — first feature-complete release

Choose a tag to compare

@acceptha acceptha released this 26 Oct 06:17

First feature-complete release.

Pipeline

  • extract — ELF parser written in C (elfdump.c, loaded with ctypes) with a pyelftools
    fallback that must produce identical results; PE via pefile (imports, VS_VERSION_INFO).
    Version-string candidates keep their file offsets. Corrupted inputs are bounds-checked and
    fuzzed in tests.
  • identify — 10 CPE-grounded YAML signature rules (OpenSSL, zlib, curl, SQLite, Expat,
    libpng, BusyBox, PCRE2, libxml2, nginx); components are marked bundled (code inside the
    file, matched) or linked (a dependency to scan separately).
  • identify --llm-hint (opt-in) — version strings no rule claimed go to the LLM; a
    suggestion is kept only if the version occurs verbatim at the cited offset and its CPE
    vendor:product is on an allowlist (every extra entry checked against the NVD CPE API on
    2026-10-23). Accepted/rejected counts are traced.
  • match — NVD CPE query with a local range re-check, fixed_in from the range ends, OSV
    references as enrichment; disk cache and recorded fixtures for offline runs.
  • retrieve — allowlisted advisory fetcher (redirects re-checked, size cap, per-host
    spacing), SQLite FTS5/BM25 index with a pure-Python BM25 fallback. Debian/Ubuntu tracker
    pages and recorded fixture pages are looked up for every CVE, not only NVD references;
    one passage per page is taken before a second from the same page.
  • advise — Anthropic (structured output) or Ollama (JSON schema) writes the Korean guide
    from a facts JSON plus <document>-wrapped passages; injection-looking passages are flagged.
    Batch size is provider-aware (Ollama 4 CVEs per call, Anthropic 12; --batch-size
    overrides) after CPU Ollama timed out on 12-CVE batches; the Ollama request timeout is
    BCPG_OLLAMA_TIMEOUT (default 600 s). Null-like fixed_in strings from the model
    ("null", "None", "N/A", "없음", "", …) are coerced to null and whitespace is
    stripped before the gate; the count is traced as normalized_fields.
  • validate — deterministic gate, rules (a)–(g) on the structured fields and (h)–(j) on the
    free text: inline citations must belong to the CVE (and to the finding's evidence), every
    version in the text must be installed / a fixed_in / a range bound, no upgrade target for a
    CVE without a fixed version, and priority words next to a CVE id must match its CVSS
    priority. Rejections are sent back verbatim (≤ 2 retries), then the template is used.
  • report — Korean report.md, report.json, and trace.json with every stage, attempt,
    rejection reason, token count and page-fetch outcome.

Tools

  • bcpg scan, bcpg identify, bcpg bench [--sets] [--online].
  • bcpg-mcp MCP server: scan_binary, lookup_cve, identify_strings.
  • Benchmark: synthetic (10 binaries) and distro (44 real libraries from Debian 10/11 and
    Ubuntu 18.04/20.04) — bundled-component precision/recall and version accuracy 100%.

Quality

  • Test suite runs with zero network and zero LLM calls (recorded NVD/OSV/page fixtures,
    scripted fake provider); tests/conftest.py blocks non-loopback sockets and the Ollama
    port, stubs the Ollama probe and clears provider/API-key/offline variables, so local
    services and shell settings cannot change results. The Anthropic SDK is imported only when
    a real client is built or an SDK error is mapped, which took a cold-venv run from 46 s to
    13 s on Windows (about 10 s warm). CI on Ubuntu with the optional extras installed.
  • Sample reports in docs/sample/: zlib 1.2.11 regenerated live with 0.1.0 (CPU Ollama; the
    gate rejected all three replies, so the template report shipped) and a template OpenSSL
    1.1.1n report.