docs(contributor-scan): what c/memory covers, and what SMT covers instead

libpng's library code never calls strcpy, strcat, sprintf or gets -- all
twelve files that do are under contrib/. It overflows through array and
pointer arithmetic and memcpy sizing, which is a different question from
the one this family asks: "can this expression exceed this allocation"
rather than "does tainted data reach this call".

That is a constraint problem. It is what SMT is for, and what this project
deliberately did not adopt -- the architecture decision was abstract
interpretation as arbiter, taken because a model layer can be built from
code where execution cannot be assumed. That decision was right for the
flow families and it does not reach this one. The maintainer has attacked
libpng exactly this way, using SMT to lay out memory and then guiding a
fuzzer to the inputs that reach it, which is evidence about the shape of
the problem rather than a plan to reimplement it: the honest routes to C
memory safety are constraint solving or execution, and the ladder already
has a rung for the second.

So 2.15 now separates the cheap route (pin a C project whose CVE runs
through a string function, giving the family its first true positive) from
the expensive one (model the arithmetic, a different engine), instead of
implying a sink-table fix would cover both.

And 2.16 asks the question this spec's predecessor would have asked:
c/memory has scored zero true positives and three separate classes of
false one -- a substring match, a bound it could not see, an allocation
sized to fit. Every one was a real engine defect and every one is fixed,
but the family has never been right. Keep it scoped and labelled, or
retire it; either way with a number behind it, and never leaving a silent
C scan to read as a clean bill of health.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01T7XD7x5KonMdmGRkp63EQG
This commit is contained in:
Marius Ciepluch
2026-09-09 13:11:30 +02:00
co-authored by Claude Opus 5
parent c1191b3a6b
commit 2589c3d47a
+32 -6
View File
@@ -272,15 +272,41 @@
and five buffer-overflow fixes checked (`png_set_quantize`, `png_image_finish_read`,
`png_init_read_transformations`, `png_do_quantize`, `png_write_image_8bit`) touch no modelled sink at
all.
- So there are two ways forward and they are different sizes. Pin a C project whose CVE genuinely runs
through a string function -- cheap, and it gives the memory family its first true positive. Or model how
C actually overflows: a `memcpy` whose size is computed, an index that is not bounded. That is size
arithmetic rather than sink matching, a different abstraction, and it should not be started by accident.
- Observable: a pinned checkout with an in-scope CVE found at a rung, or a recorded decision that the
memory family needs the second abstraction before any C detection claim is made.
- So there are two ways forward and they are different sizes.
- **Cheap: pin a C project whose CVE genuinely runs through a string function.** That gives the memory
family its first true positive and tells us whether the family works at all. It does not make libpng
decidable.
- **Expensive, and a different engine: model how C actually overflows.** A `memcpy` whose size is
computed, an index that is not bounded. That is *size arithmetic*, not sink matching -- "can this
expression exceed this allocation" rather than "does tainted data reach this call". It is a constraint
problem, which is what SMT is for and what this project deliberately did not adopt: the architecture
decision was abstract interpretation as arbiter, taken because a model layer can be built from code
where execution cannot be assumed. That decision was right for the flow families and it does not reach
this one.
- The maintainer has attacked libpng this way directly -- SMT to lay out memory, then guiding a fuzzer to
produce the PNGs that reach it -- which is evidence about the shape of the problem, not a suggestion to
reimplement it. It says the honest routes to C memory safety are constraint solving or execution, and
the ladder already has a rung for the second (`execution_confirmed`, built and unreachable per the
module audit).
- Observable: a pinned checkout with an in-scope CVE found at a rung, OR a recorded decision that
`c/memory` is scoped to string-function misuse and makes no claim about arithmetic overflows. Do not
leave it implying it covers a class it cannot see.
- _Requirements: 4.1, 4.4_
- _Depends: 2.12_
- [ ] 2.16 Say what `c/memory` actually covers, or retire it
- Its score so far is zero true positives and every finding a false one: 26 from a substring match, 3 from
a bound it could not see, 1 from an allocation sized to fit. Each was a real defect in the engine and
each is now fixed, but the family has never once been right, and 2.15 explains why -- it models string
functions in a codebase class that overflows through arithmetic.
- This spec's predecessor threw away parts that did not carry their weight, and the same question applies
here. The answer may well be "keep it, scoped and labelled" -- `strcpy` misuse is real in plenty of C --
but it should be a recorded decision with a number behind it, not an assumption.
- Observable: either a measured true positive on the 2.15 checkout, or the family's declared scope
narrowed in the facts and the docs so no reader takes a silent C scan for a clean bill of health.
- _Requirements: 3.1, 8.2_
- _Depends: 2.15_
## Group 3 — Ship it
- [ ] 3.1 Contributor output