Skip to content

Stop the two documents a reporter reads saying this tree has nothing to attack - #446

Merged
iderex merged 1 commit into
mainfrom
security-policy-says-what-the-crate-holds
Sep 18, 2026
Merged

iderex merged 1 commit into
mainfrom
security-policy-says-what-the-crate-holds

Conversation

@iderex

@iderex iderex commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

The issues this belongs to

Closes #444
Closes #445

Two issues on one branch because both land documents and nothing else, and
because they are one topic: the two registers a person outside this account reads
to decide what is worth examining here both describe a tree with no parser in it.
Landing them separately would move the mainline under the other for a change that
touches no shared line.

What changed

SECURITY.md. The paragraph under the inventory enumerated what the crate's types
hold - a name, a statement about which thread a caller may use them from, and the
measurement facility - and said there was no request, no cache, no decode and no
sign-in. The enumeration is deleted rather than replaced with a longer one, and
what stands in its place is the reading tests/replay_the_seed_corpus.rs already
derives its own target list from, so the parse targets a reporter should look at
are one command away and no list here goes stale on the next landing. Three of the
four absences hold and are kept word for word; the cache clause is corrected.
The claim that README.md says the same thing is gone, and the paragraph says
what was wrong, when each of the three files that made this claim corrected it,
and how this one was found.

security/statements.json. The scorecard/FuzzingID entry dismissed the check on
the ground that there is no untrusted input surface here that a fuzzer would reach.
That half of the ground is deleted and recorded as refuted; the half that holds -
onboarding needs somebody who can be paged - is what the dismissal now rests on.
impact separates the seed-corpus replay, which runs in the gating build, from the
coverage-guided search, which happens nowhere, and states the second as what is not
looked for. retires_when says its own condition has been met and that lifting the
dismissal is an act on the code-scanning surface rather than a change to this tree.
updated carries today.

No source file is touched and no rule is added.

What failure it prevents

A reporter or a downstream consumer reading either file, concluding there is
nothing here worth examining, and not opening the code. This has already happened
once on this board in the same file: #200 was the issue for SECURITY.md saying
the core was not written, and the sentence that replaced it was an enumeration
that went stale in the same direction. #445's half was never true at all - three
seed corpora landed on 2026-08-31 and two more on 2026-09-02, the last of them
eleven hours before the document saying there was nothing to fuzz was published.

Evidence

Read at the commit pushed, 4984877.

The paragraph that was replaced, and the entry that was corrected:

git show b5266ba:SECURITY.md | sed -n '141,146p'
WHAT IS ABSENT IS BEHAVIOUR RATHER THAN CODE, and that distinction is the one a
reporter needs. The crate compiles, a suite runs against it, and what the types
in it hold today is a name, a statement about which thread a caller may use it
from, and the measurement facility. There is no request, no cache, no decode and
no sign-in. `README.md` says the same thing in its own words, and the section
below on what is not a vulnerability here says what follows from it.

git show b5266ba:security/statements.json | sed -n '44p'
      "justification": "There is no untrusted input surface in this tree today that a fuzzer would reach, and onboarding to OSS-Fuzz needs somebody who can be paged.",

What both describe as absent:

git ls-tree --name-only 4984877 tests/fixtures/corpus/
tests/fixtures/corpus/artwork-format
tests/fixtures/corpus/artwork-identifier
tests/fixtures/corpus/artwork-shape
tests/fixtures/corpus/cache-envelope
tests/fixtures/corpus/server-address
git ls-tree -r --name-only 4984877 tests/fixtures/corpus/ | wc -l
52

SECURITY.md's paragraph landed before the first of those existed, and
security/statements.json's entry landed after all five of them:

git log -1 --format='%cI %s' c6d3694
2026-08-26T16:39:05+02:00 Make the security policy read the tree it describes (#200) (#203)
git log -1 --format='%cI %s' 1f6ec6c
2026-08-26T21:02:07+02:00 Turn what a person typed into a base address, and join every path to it once
git log -1 --format='%cI %s' c6802a0
2026-09-02T05:32:20+02:00 Replay a corpus over the identifier and the tag a server sent (#86)
git log -1 --format='%cI %s' 2939128
2026-09-02T16:39:54+02:00 Say publicly why a finding that is not fixed does not apply (#89)

The cache clause, refuted by a public pair:

git grep -n 'pub fn read\|pub fn write' 4984877 -- src/cache/envelope.rs
4984877:src/cache/envelope.rs:365:    pub fn write(&self, kind: EntryKind, key: &EntryKey, payload: &[u8]) -> Cached {
4984877:src/cache/envelope.rs:378:    pub fn read(&self, kind: EntryKind, key: &EntryKey) -> Option<Vec<u8>> {

The three absences kept as they were still hold:

git grep -n 'std::net\|TcpStream\|TcpListener' 4984877 -- 'src/**/*.rs' ; echo "exit=$?"
exit=1

Checks run on this machine over the tree at 4984877, with nothing uncommitted
in it but an untracked directory no rule here reads:

bash .github/doc-paths/doc-paths.sh check | tail -1
Every path these documents name resolves against the tracked set.

bash .github/statements/statements.sh check | tail -1
Every directive this repository excludes has a published statement saying why, and what is consequently not looked for.

bash .github/invariants/invariants.sh check | tail -1
Every rule above was applied to its subject and refused nothing.

What a guard here refuses, and the proof it bites

Nothing here adds or edits a guard. The section is kept rather than deleted so
that its absence is stated: no rule in this tree compares a sentence in a document
against the tree it describes, which is why both of these landed and why neither
was found by a run. .github/statements/statements.sh prints that bound on every
run - "NOT MADE HERE: whether a statement is TRUE" - and this change does not move
it.

What this does not cover

  • The Scorecard dismissal itself. Whether the fuzzing finding is left dismissed
    or raised again is a state on the repository, not a byte in this tree, and no
    branch can change it. It stays dismissed, on the narrower ground.
  • The coverage-guided fuzzing run. Fuzz the parsers, and replay the seed corpus inside the gating build #86 is open for it and carries its own
    waiting label. Nothing here asks for a fuzzer or an OSS-Fuzz onboarding.
  • Every other reading in SECURITY.md. The security policy's evidence that the core is written reads a moving reference and pastes a reading taken at a fixed one #427 and The security policy's near-miss reading asks the working tree and HEAD, and the equality its sentence rests on is a fact about one commit #429 pinned the inventory and
    near-miss blocks; neither is reopened, and the readings under "What somebody
    could actually report" are outside this.
  • The threat model below the repaired paragraph. Whether the sections under it
    are sized to the tree as it stands is a separate question and was not asked.
  • The other seven entries in the statements register. They were read while this
    was found and none of them is repaired here.
  • README.md and src/lib.rs. Both already carry their own corrections of the
    claim SECURITY.md was still making, and neither is edited here.
  • cargo build --locked --all-targets and cargo test --locked ON THIS
    MACHINE.
    Neither answered here. The build was started over the tree carrying
    the SECURITY.md edit and had not finished when this body was written, and the
    suite was not run locally at all. What is green is the gate's own build and
    test on this pull request, read off the runner rather than measured here, and
    that is what this line claims and nothing more.

Who has read it

Nobody other than the author. There is one account here, which is what
security/statements.json says under scorecard/CodeReviewID, so the evidence
above stands in place of a review rather than beside one.

…to attack

Both files tell somebody outside this account what is worth looking at here, and
both of them describe a tree with no parser in it.

`SECURITY.md` enumerated what the crate's types hold as a name, a statement about
which thread a caller may use them from, and the measurement facility, and said
there was no request, no cache, no decode and no sign-in. That was a fair reading
of the ten module roots `src/` held on 2026-08-26, the day it landed in the change
that closed #200 for saying the core was not written; the first parser landed four
hours after it. The tree now carries five parse targets with a committed seed
corpus that `cargo test --locked` replays, and a cache that reads and writes
through the store a client supplies. The enumeration is gone rather than corrected,
because a list there is wrong on the next landing and nothing in this tree reads
one: what replaces it is the reading `tests/replay_the_seed_corpus.rs` already
derives its own target list from. Three of the four absences hold and are kept as
they were; the cache clause is the one that stopped holding, and `src/cache/mod.rs`
carried the correction of that same shape from #442 one day earlier. The paragraph
also called `README.md` a file saying the same thing, and that file corrected its
own version on 2026-08-29, as `src/lib.rs` corrected a third on 2026-09-18.

`security/statements.json` dismissed the Scorecard fuzzing check on the ground that
"There is no untrusted input surface in this tree today that a fuzzer would reach".
Three seed corpora landed on 2026-08-31 and the fourth and fifth on 2026-09-02,
the last of them eleven hours before that document was published, so the tree
refuted the sentence before it was written rather than afterwards. The entry keeps
the half of its ground that holds - nobody here can be paged - and now says that
the condition its own `retires_when` names has been met. What it does not do is
lift the dismissal: that is a state on the code-scanning surface rather than a byte
in this tree, no branch here can change it, and the check prints on every run that
it cannot read one. Its `impact` field described the seed-corpus replay as work #86
is open for; the replay runs inside the gating build, and what is not looked for is
a NEW hostile input, which is the coverage-guided half #86 is still open for.

What both prevented is the same failure in two registers: a reporter or a
downstream consumer concluding from a document that there is nothing here worth
examining, and not opening the code. That is what #200 closed the first of these
sections for, and it had come back one enumeration later.

Both were found by reading the sentences against the corpus the suite replays. No
number is written into either file to replace what was deleted.

Closes #444
Closes #445

Signed-off-by: Nils Lehnen <30603423+iderex@users.noreply.github.com>
@iderex iderex closed this Sep 18, 2026
@iderex iderex reopened this Sep 18, 2026
@iderex
iderex merged commit 9fe6420 into main Sep 18, 2026
53 of 56 checks passed
@iderex
iderex deleted the security-policy-says-what-the-crate-holds branch September 18, 2026 04:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant