Skip to content

cvehound-spatch 1.3.2.post2

Choose a tag to compare

@evdenis evdenis released this 28 Aug 21:39
· 9 commits to main since this release

Rebuilds the bundle from the cvehound branch, which has gained six commits
since 1.3.2.post1. Four of them change how spatch can be driven, and this
release is what makes them reachable — including a way for a caller to find out
that they are there.

spatch can now be run as a server

spatch --zygote reads length-prefixed requests on stdin and forks a fresh
process for each one, after warming standard.iso and standard.h once. A
scan that runs hundreds of rules pays process startup once instead of once per
rule. Every request still runs in its own process, so no engine state carries
from one rule to the next and results are unchanged; measured at roughly 5% of
a CVEhound scan today, and more as the rule set grows.

A fired --timeout is now distinguishable from a crash

It used to escape as an uncaught Common.Timeout, i.e. exit 2, which is also
what any other uncaught exception gives. It now exits 124, the way
timeout(1) does. The exception name stays in the message, so a caller that
already scrapes stderr keeps working.

The AST cache is safe to share

--cache-prefix entries are written through a temporary name and renamed,
value before dependencies, so parallel scans sharing one cache directory cannot
read a half-written entry. standard.h is now part of the cache key. The cache
path also no longer forks /bin/sh to run mkdir -p once per file — which a
cache hit was paying too.

FEATURES, so callers can ask

>>> import cvehound_spatch
>>> cvehound_spatch.FEATURES
frozenset({'exit124', 'shared-cache', 'zygote'})

None of the above can be detected from outside: --zygote is dispatched before
spatch parses its arguments, so it is in no --help output, and the version
banner is identical with and without it. make_wheel.py probes the built
binary at pack time rather than asserting, so a build from a ref that predates
a feature advertises nothing instead of lying. Read it with
getattr(cvehound_spatch, 'FEATURES', frozenset()) and every older wheel
correctly reports that it has none of this.

CVEhound uses exactly that to decide whether to run spatch as a server, so
cvehound[spatch] installs get the faster transport automatically from
this release on, and installs on an older wheel keep the previous behaviour
rather than failing.

Built with flambda

The compiler study was re-run against the real rule corpus rather than a
handful of heavy rules, and flambda -O3 measures 4.5% of CPU (5.3% under
the zygote transport), against the 2-3% that had it rejected the first time.
It costs +11.4 MB of binary, which buys 428 extra minor page faults per exec —
about 0.05 ms. llvm-BOLT was measured again too and is still not shipped; the
reasoning is in the README.