db/seg, db/seg/patricia: fix fuzz harness defects - #23173
Merged
Conversation
Map iteration order decided which keys got concatenated into the match data, so the same fuzz input produced a different test string on every run. LibAFL reports edges_stability 59% for this target as a result, and a crash saved to the corpus would not replay.
pos[i]*10 is uint8 arithmetic and wraps for pos[i] >= 26, so the conversion to int happened after the value had already been truncated. The harness only ever produced wrapped chunk sizes.
AskAlexSharov
enabled auto-merge
August 11, 2026 10:44
Same defect as FuzzCompress: pos[i]*10 is uint8 arithmetic and wraps for pos[i] >= 26, so the conversion to int happened after truncation.
sudeepdino008
approved these changes
Aug 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three fuzz harnesses fixed, two defect classes, found by running gosentry (Trail of Bits' LibAFL-backed fork of the Go toolchain) against our fuzz targets.
db/segFuzzCompress and FuzzDecompressMatch — uint8 overflow in the chunk size.pos[i]is abyte, sopos[i]*10is uint8 arithmetic and wraps forpos[i] >= 26; theint()conversion was applied to the already-truncated value. Both harnesses only ever produced wrapped chunk sizes.db/seg/patriciaFuzzLongestMatch — nondeterministic input. The key list was filled from a Go map and then indexed to build the match data, so the same input built a different test string on every run. gosentry measurededges_stabilityat 59%: coverage feedback was partly noise, and a crash saved to the corpus would not have replayed. Sorting the list takes it to 100%.FuzzLongestMatchstabilityFuzzCompresswith overflow detectionFuzzDecompressMatchwith overflow detectionTest-only changes; no production code touched.
Other findings from the same run, not included here
execution/rlp.(*Stream).Listreports a uint8-addition overflow under deep list nesting. The reported operation does not match the source line (limit - sizeon[]uint64), so the attribution is likely displaced by inlining — unresolved, needs a look.ecrecover.RunandrecoverPlainboth wrap onv - 27, but a wrapped value can only land in 229–255 andTransactionSignatureIsValidaccepts only 0 or 1 — benign.swarEdge,bitutil.Select64andmurmur3wrap by design (SWAR / hash mixing) — benign.Fuzz_ProcessUpdates_ArbitraryUpdateCount2callshph.Processonce per key over a growing trie (quadratic) and typeskeysCountasuint16, so the average input asks for ~32k keys; it manages ~82 executions in 38s.execution/vm.codeBitmap(analysis.go:50) andcommon/bitutil.Select(select.go:96) wrap by design — SWAR has-zero-byte tests, same family asswarEdge.-truncationdetect=true) is unusable as-is: it fires within the first 1–4 executions of nearly every target —sais.freq_,math.ReadBits,rlp/decode.go:1164,hex_patricia_hashed.go:704. Go narrows integers constantly by design, so it needs a large suppression pass before it yields signal.eliasfano32targets pad every input to 32KB, holding them at ~60 exec/s. Making the padding fuzzer-controlled gives 2.7–3.7x, but it changes the fuzz signature and invalidates the 8 committed corpus entries, so it needs a corpus migration and is left out of this PR.parallel_compress, parallel commitment and txpool parsing.