Skip to content

A pin that is behind its upstream is held to a written review, and CI asks for it - #26

Open
DevomB wants to merge 6 commits into
mainfrom
pin-currency-gate
Open

DevomB wants to merge 6 commits into
mainfrom
pin-currency-gate

Conversation

@DevomB

@DevomB DevomB commented Sep 19, 2026

Copy link
Copy Markdown
Owner

Roadmap, Version 1.0: "No known-vulnerable pins", the part that keeps it true.

The problem

check-source-currency.sh reports that a newer version exists and, rightly, judges nothing. Nothing else judged either. On 2026-09-19, 51 of 113 pins were behind their upstream, 16 could not be determined at all, and no file said which gaps held a security fix. Eight did.

What this adds

  • tools/check-pin-reviews.sh, a gate that reads the survey and tools/pin-reviews.tsv and never the network. A pin that is behind passes only with a row naming the version reviewed, the newest upstream release that was read, a verdict, a date and what was read.
  • It is a gate, not a list. A row fails when the pin has moved off the version it reviewed, when upstream has released past what was read, when it is older than 180 days, when it has no note, and when the pin has caught up and the row was left behind.
  • held is loud. A pin held despite a known fix is printed on every run, and --no-held, which is what a release asks, refuses it.
  • The survey can now read the sixteen hosts it could not. Four of those pins were behind.
  • The reviews themselves: 26 fine, 6 held (zlib, gawk, gzip, acl, readline, shadow), each with what is wrong and what moving it needs.
  • CI: the weekly job and every push to main run the survey and the gate. On a pull request the verdict is informational.

Checked

  • 22 offline tests for the gate. They found a real bug before anything else did: a tab-separated row with an empty column lost the column, and all 16 undetermined pins were counted as none.
  • 27 offline tests for the survey tool, nine new, each serving a trap the new rules avoid: release candidates numbered 1.31.901, a release list ordered by date, a beta in a directory listing, dev snapshots, a meta refresh that curl does not follow.
  • The rows, run against the survey as it reads with the open bumps applied: 26 fine, 6 held, nothing unreviewed.

Merging

The rows describe main once #17, #23 and #25 are on it, so this merges after them. It touches tools/, so not while a Distro run is in flight.

…e review stops covering it when upstream releases again

check-source-currency.sh reports that a newer version exists and, rightly,
judges nothing: newer is not a security verdict. Nothing else judged
either, so 51 of 113 pins are behind today and no file says which of those
gaps holds a security fix. This is the place that gets written down.

tools/check-pin-reviews.sh reads the survey (--tsv) and
tools/pin-reviews.tsv, and never the network, so its answer can be tested
and reproduced. A behind pin passes only with a row that names the version
reviewed, the newest upstream release that was read, a verdict, a date and
what was read. fine: nothing in the gap is a security fix that reaches
Kryptik. held: something is, and the row says why the pin stays; it is
printed on every run, and --no-held, which is what a release asks, refuses
it. What makes it a gate and not a list: a row fails when the pin has moved
off the version it reviewed, when upstream has released past what was read,
when it is older than 180 days (a vulnerability is often published long
after its fix), when it has no note, and when the pin has caught up and the
row was left behind, so the file shrinks when the work is done.

The tests (22, offline) found a bug before anything else did. The survey is
tab separated and a pin the survey could not determine has an empty
"newest" column; read merges a run of tabs, every later field moved left,
and all 16 undetermined pins were counted as none. The survey is now read
with a separator that is not whitespace.

make check-pins runs the survey and then the gate; make test-pin-reviews
and tools/run-tests.sh run the suite. The reviews file ships with its
contract and no rows: the rows are the review itself, and come with it.
… pins turn out to be behind

Sixteen pins were UNKNOWN in every survey: the hosts serve an API, a feed or
a front page, not a directory listing. They were also a third of what the
image exposes to untrusted input: less, lynx, openssh, libinput, wlroots,
wayland. Not checked is not the same as fine, and four were not fine: less
661 against 710, procps-ng 4.0.4 against 4.0.7, lvm2 2.03.39 against
2.03.42, libinput 1.30.4 against 1.32.0.

Each rule was run against the real host before it was written, and each
encodes a way to be confidently wrong, with a test that serves the trap:
wayland and libinput number a release candidate 1.31.901, with no "rc" in
it; a GitLab release list is ordered by date, so the first entry is not the
newest; psmisc's release list is missing a release its tags have, and
kernel-hardening-checker publishes tags and no releases; less's directory
offers a beta, and the front page says which version is for general use;
lynx's directory is full of dev snapshots; openssh's p1 is part of the
version; curl.se/ca/ answers 200 with a meta refresh curl does not follow.
wlroots is read within its pinned series, as python is: dwl is written
against one series and the next is an API change. The glibc FHS patch is
deferred to the glibc row, which is what decides it.

The header said --only NAME; the parser has always taken --only=NAME.
…held with what is wrong with each, and a release refused until the six are dealt with

tools/pin-reviews.tsv now has a row for every pin that stays behind its
upstream once the open bumps are on main. Each row names the version
reviewed, the newest upstream release that was read, the date, and what was
read and what it said; they come from four reports made on 2026-09-19 out of
upstream NEWS files and changelogs, project security pages, the Debian
tracker and NVD records, not from a search for "CVE".

Held, because a fix exists and the pin cannot simply move: zlib (1.3.2 fixes
one CVE and introduces a worse one that 1.3.1 does not have; the fix is
unreleased), gawk (four overflows fixed only in 5.4.1, which changes the
regex engine under every build script), gzip (the fix is in no release, so
1.14 fixes nothing), acl (2.4.0 does not build with the pinned tar), readline
(8.2 without its official patches; 8.3 moves with bash 5.3), shadow (a
use-after-free fixed in 4.17, and 4.19 and 4.20 each break the recipe). Run
against the survey as it reads with the open bumps applied: 26 fine, 6 held,
nothing unreviewed, and --no-held, which is what a release asks, fails on
exactly those six.

CI's weekly job and every push to main now run the survey and then the gate.
On a pull request the verdict is printed and does not fail the check: an
upstream that released this morning is not the fault of whoever opened a
pull request this afternoon, and the scheduled run is what makes sure
somebody reads it. The roadmap entry says what is written and what ticking
it still needs.

The rows describe main as it will be once the glibc, gcc and pin-batch
changes are on it, so this merges after them.
…me things

The owner asked whether what is being added is real or padded, and measured
honestly this tool was padded: a join of two files with five ways to fail
had grown an expiry policy, a date override for its own tests, a strict mode
CI never used, six report sections and a test file longer than itself.

It now does what makes it a gate and nothing else: a behind pin needs a row;
the row stops covering it when the pin moves, when upstream releases past
what was read, or when the pin catches up; a row needs a verdict and a note;
held is printed and --no-held refuses it; an undetermined pin is reported.
Review expiry, --strict, --max-age and --today are gone. The suite keeps the
sixteen cases that each guard one of those behaviours, including the
tab-merging bug it originally found. Run against the 32 real rows and the
projected survey it gives the verdicts it gave before: six held, the rest
covered, a release refused for the six.

The reviews file's header, the CI step's comment and the Makefile's are cut
to what a reader needs.
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.

1 participant