Skip to content

[do not merge] gosentry overflow-detection suppressions and run script - #23202

Draft
AskAlexSharov wants to merge 4 commits into
mainfrom
alex/gosentry_overflow_37
Draft

[do not merge] gosentry overflow-detection suppressions and run script#23202
AskAlexSharov wants to merge 4 commits into
mainfrom
alex/gosentry_overflow_37

Conversation

@AskAlexSharov

Copy link
Copy Markdown
Collaborator

Preserves the triage from running gosentry — a fork of the Go toolchain that panics on integer overflow/underflow at runtime — over the unit suite, the fuzz targets, and a syncing mainnet node. Not for merge: gosentry is not in CI, and these markers only earn their place if it becomes a recurring audit. Opened so the work is not lost.

The expensive part is not the code, it is knowing which sites are deliberate. Without this, the next instrumented run repeats the whole triage.

Two mechanisms, chosen by scope.

Packages that are modular arithmetic end to end are exempted wholesale in misc/gosentry-run.sh. Marking them in place does not scale — Sum128WithSeed alone has 16 arithmetic operations, 40 across the file:

-gcflags=github.com/erigontech/erigon/common/murmur3=-overflowdetect=false

Single benign sites inside packages worth instrumenting are marked in the source, so the rest of the package keeps its checks — the EVM is exactly where a real overflow would matter:

// overflow_false_positive
vByte := byte(vb.Uint64() - 27)

What was checked, and why each is benign.

site why it wraps
murmur3, blake2b, recsplit.remix, ethash FNV hash mixing; the reference C++ uses uint64_t, Rust ports spell it wrapping_mul
bitutil.Select, patricia.swarEdge, vm.codeBitmap SWAR — the borrow out of a zero byte is the result
transaction_signing.go:421, contracts.go:335 v - 27; a wrapped value lands in 229–255 and TransactionSignatureIsValid accepts only 0 or 1
txn_executor.go:307 stNonce+1 < stNonce is itself the overflow check
vm/evm.go:233 documented in place: mod-2^64 subtraction is the correct computation
cache.go:245, cache_accessors.go:51 epoch 0 produces a garbage slot, rejected by the error path
prefix_trie.go, kvcache.go:241, nodedb.go:598, stage_senders.go:335 wrapped value is discarded, used as a map miss, or only reaches a debug log

Two real bugs came out of the same runs and are in their own PRs, not here: #23192 (AA gas limits summed unchecked; parseBitlist msb underflow) and #23173 (fuzz harness defects).

Notes
  • misc/gosentry-run.sh has build, test and fuzz subcommands. The fuzz path sets RUSTFLAGS=-C link-arg=-lstdc++, without which the LibAFL harness fails to link against evmone's C++ modexp.
  • Truncation detection (-truncationdetect=true) is deliberately not enabled: it fires within the first 1–4 executions of nearly every package and needs its own triage pass.
  • common/murmur3 here also carries a wmul/wadd helper pair, kept as a worked example: two // overflow_false_positive markers silence all 40 sites because suppression survives inlining. The package exemption makes it redundant, and it diverges from the reference transcription, so it should probably be dropped before any merge. I did not measure whether the helpers are free — the benchmark run timed out.
  • The exemption list is what lets a node start at all. Without it the node dies in seconds: first murmur3.go:41 via every index lookup, then recsplit.go:86.

Records the triage from running the gosentry toolchain over the unit
suite, the fuzz targets and a syncing node. Every site marked here was
checked and found to be deliberate modular arithmetic.

Packages that are modular arithmetic end to end are exempted wholesale by
misc/gosentry-run.sh rather than marked: murmur3 alone would need 40
markers. Single benign sites inside packages worth instrumenting are
marked in place, so the rest of those packages keeps its checks.

Not for merge: gosentry is not part of CI, and these markers only earn
their place if it becomes a recurring audit.
…kages

Round 2's site list was measured on a tree that already carried round 1's
markers, so five landed below the arithmetic instead of above it and had
no effect. Verified now: every marker sits directly above an arithmetic
statement.

Packages the script exempts wholesale no longer carry markers, murmur3
included: the exemption already covers them, and the wmul/wadd helpers
diverged from the reference transcription for no gain.
zz_release_bench_test.go and hex_patricia_hashed_gosentry_test.go were
untracked working-tree files picked up by an over-broad git add.
…ng ops

Package-level -overflowdetect exemption does not survive inlining: a
small exempted function inlined into an instrumented caller gets checks
inserted at the call site. bitutil.Select64 fired from eliasfano32.get
despite being exempted.

Source markers do survive, so route the wrapping operations of the three
small hot functions through marked helpers.
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