Skip to content

generate-vulns-advisories: derive initial fixed via FormulaVersions#23115

Merged
andrew merged 1 commit into
mainfrom
vulns-osv-export-archaeology
Jul 14, 2026
Merged

generate-vulns-advisories: derive initial fixed via FormulaVersions#23115
andrew merged 1 commit into
mainfrom
vulns-osv-export-archaeology

Conversation

@andrew

@andrew andrew commented Jul 14, 2026

Copy link
Copy Markdown
Member

Follow-up to #23112. When brew generate-vulns-advisories writes a record with no existing file on disk, derive the fixed boundary from homebrew-core git history via FormulaVersions instead of using the current pkg_version: walk newest-to-oldest and use the pkg_version at the oldest revision where the CVE still appears in resolved_ids. Existing records preserve their on-disk ranges (per #23112), so this only fires once per newly-annotated (formula, CVE) pair; a hand-corrected boundary is never recomputed.

Because resolved_ids includes CVEs inferred from patch URLs and apply file paths, this finds the true fix version when the CVE is named there. When a resolves line was added to a patch that had already shipped without a CVE reference, it finds when resolves was added instead (too recent); those cases are hand-corrected in the advisory repo. Historical revisions are loaded under the same SimulateSystem as discovery so output is runner-OS-independent; a resolves inside on_linux/on_intel falls through to the current pkg_version (no such annotation exists in core today).

FormulaVersions#rev_list (path-filtered git rev-list over ~500k homebrew-core commits) is the dominant cost at ~90s per formula; the instance and its rev list are cached per formula so subsequent CVEs for the same formula are near-instant.

Spot-checked against real homebrew/core:

formula CVE current derived
unzip CVE-2014-8139 6.0_8 6.0_6
unzip CVE-2019-13232 6.0_8 6.0_6
unzip CVE-2022-0529 6.0_8 6.0_8
libquicktime CVE-2016-2399 1.2.4_5 1.2.4_5 (resolves-added-later case; hand-correct to _4)
lrzsz CVE-2018-10195 0.12.20_1 0.12.20_1

Context: Homebrew/discussions#6869, Homebrew/homebrew-brew-vulns#111.


  • Have you followed our Contributing guidelines?
  • Have you checked for other open Pull Requests for the same change?
  • Have you explained what your changes do? Performance claims (e.g. "this is faster") must include Hyperfine benchmarks.
  • Have you explained why you'd like these changes included, not just what they do?
  • For bug fixes, have you given step-by-step brew commands to reproduce the bug?
  • Have you written new tests (excluding integration tests)? Here's an example.
  • Have you successfully run brew lgtm (style, typechecking and tests) locally?

  • AI was used to generate or assist with generating this PR.

Written with Claude Code following @Bo98's suggestion on Homebrew/discussions#6869 to use FormulaVersions, with a codex review pass that caught the runner-OS dependence and tightened the walk-termination specs. I read the diff, ran brew lgtm, and spot-checked the derived boundaries against real homebrew/core history.


For records with no existing file, walk homebrew-core git history
(newest-first) via FormulaVersions and use the pkg_version at the oldest
revision where the CVE still appears in resolved_ids as the `fixed`
boundary, instead of the current pkg_version. Existing records preserve
their on-disk ranges (per the merge behaviour in the previous commit),
so this only fires once per newly-annotated (formula, CVE) pair.

The FormulaVersions instance and its rev_list output are cached per
formula so subsequent CVEs for the same formula reuse the ~90s
path-filtered git rev-list and per-revision formula loads. OsvExport.run
now runs inside the SimulateSystem block so historical loads are
runner-OS-independent. Historical revisions are evaluated under the base
simulation only; a resolves inside on_linux/on_intel falls through to
the current pkg_version (documented; no such annotation exists in core
today).

Spot-checked against real homebrew-core: unzip CVE-2014-8139 -> 6.0_6
(current is 6.0_8), CVE-2022-0529 -> 6.0_8; libquicktime CVE-2016-2399
-> 1.2.4_5 (the resolves-added-later case; hand-correct to _4).
Copilot AI review requested due to automatic review settings July 14, 2026 21:11

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves the accuracy of generated OSV advisory “fixed” boundaries when creating new advisory records (i.e., when no <id>.json already exists on disk). Instead of defaulting to the current pkg_version, it allows callers to derive the first fixed version from homebrew-core history (via FormulaVersions), while continuing to preserve existing on-disk ranges as the long-term source of truth.

Changes:

  • Extend Homebrew::Vulns::OsvExport.run to accept an optional first_fixed callback used only when generating records that don’t already exist on disk.
  • Thread an explicit fixed: value through record_for/affected_entry so OSV range events can reflect a derived fixed boundary.
  • Implement and test GenerateVulnsAdvisories#first_fixed_version, walking formula history via FormulaVersions to find the oldest revision where the CVE remains resolved.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
Library/Homebrew/vulns/osv_export.rb Adds optional first_fixed callback plumbing and supports explicit fixed boundaries when building new records.
Library/Homebrew/dev-cmd/generate-vulns-advisories.rb Uses FormulaVersions history to derive an initial fixed boundary for newly written advisories.
Library/Homebrew/test/vulns/osv_export_spec.rb Adds coverage for explicit fixed: handling and first_fixed invocation behavior.
Library/Homebrew/test/dev-cmd/generate-vulns-advisories_spec.rb Adds unit tests for the first_fixed_version history-walk behavior and stubs FormulaVersions for other specs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@andrew andrew requested a review from p-linnane July 14, 2026 21:22
@andrew andrew added this pull request to the merge queue Jul 14, 2026
Merged via the queue into main with commit 6bd951d Jul 14, 2026
45 checks passed
@andrew andrew deleted the vulns-osv-export-archaeology branch July 14, 2026 23:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants