mirror of
https://github.com/XRPLF/rippled.git
synced 2026-07-28 01:20:32 +00:00
ci: Key rippled UBSan suppressions by source file
The function-name suppressions for rippled's own code never matched: this UBSan build runs without symbol information, so the runtime only reports the file:line of each diagnostic, not the enclosing function. The CI log still showed ~486 unsuppressed `runtime error:` lines, all from own-code files whose entries were written as function-name globs. Re-key every rippled own-code entry by source file (the only granularity the runtime can match here), covering all files flagged by the ubsan job: amount/number arithmetic, hashing and PRNG, counter/sentinel wraparound guarded by explicit checks, codec index math, and intentional test arithmetic. Each entry keeps a comment naming the construct. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -130,46 +130,32 @@ unsigned-integer-overflow:include/c++/*/bit
|
||||
# Rippled code suppressions
|
||||
# =============================================================================
|
||||
|
||||
# Signed integer negation (-value) in amount types.
|
||||
# INT64_MIN cannot occur in practice due to domain invariants (mantissa ranges
|
||||
# are well within int64_t bounds), but UBSan flags the pattern as potential
|
||||
# signed overflow. Narrowed to operator- to avoid suppressing unrelated
|
||||
# overflows anywhere in a stack trace containing these type names.
|
||||
signed-integer-overflow:operator-*IOUAmount*
|
||||
signed-integer-overflow:operator-*XRPAmount*
|
||||
signed-integer-overflow:operator-*MPTAmount*
|
||||
signed-integer-overflow:operator-*STAmount*
|
||||
# These suppressions are keyed by SOURCE FILE, not function name. This UBSan
|
||||
# build runs without symbol information, so the runtime only knows the
|
||||
# file:line of each report, never the enclosing function — function-name
|
||||
# patterns silently never match. Each entry below is therefore scoped to the
|
||||
# file whose arithmetic is intentional; the comment names the specific
|
||||
# construct.
|
||||
|
||||
# STAmount::operator+ signed addition — operands are bounded by total supply
|
||||
# (~10^17 for XRP, ~10^18 for MPT) so overflow cannot occur in practice.
|
||||
signed-integer-overflow:operator+*STAmount*
|
||||
# STAmount amount-type arithmetic. Unary negation of the mantissa in xrp()/
|
||||
# iou()/mpt()/canonicalize() and getInt64Value, plus bounded +/- on amounts:
|
||||
# INT64_MIN cannot occur because canonicalize() keeps the mantissa well within
|
||||
# int64_t, and operands are bounded by total supply (~10^17 XRP, ~10^18 MPT).
|
||||
signed-integer-overflow:protocol/STAmount.cpp
|
||||
|
||||
# STAmount::getRate uses unsigned shift and addition
|
||||
unsigned-integer-overflow:*STAmount*getRate*
|
||||
# STAmount::serialize uses unsigned bitwise operations
|
||||
unsigned-integer-overflow:*STAmount*serialize*
|
||||
# nft::cipheredTaxon uses intentional uint32 wraparound (LCG permutation);
|
||||
# the helper lives in the generated protocol header nft.h.
|
||||
unsigned-integer-overflow:protocol/nft.h
|
||||
|
||||
# nft::cipheredTaxon uses intentional uint32 wraparound (LCG permutation)
|
||||
unsigned-integer-overflow:cipheredTaxon
|
||||
# STPathElement::getHash multiplies/adds accumulators (non-secure, speed-first).
|
||||
unsigned-integer-overflow:protocol/STPathSet.cpp
|
||||
|
||||
# Signed negation of INT64_MIN in STAmount accessors. xrp()/iou()/mpt() and
|
||||
# getInt64Value negate the mantissa when isNegative_; the mantissa is bounded
|
||||
# well within int64_t by canonicalize(), so INT64_MIN cannot occur in practice.
|
||||
# (The operator-*STAmount* entry above only covers binary/unary operator-.)
|
||||
signed-integer-overflow:*STAmount*xrp*
|
||||
signed-integer-overflow:*STAmount*iou*
|
||||
signed-integer-overflow:*STAmount*mpt*
|
||||
signed-integer-overflow:*STAmount*canonicalize*
|
||||
signed-integer-overflow:getInt64Value*
|
||||
|
||||
# Hash helpers using intentional unsigned wraparound (non-secure, speed-first).
|
||||
# STPathElement::getHash multiplies/adds accumulators; XorShiftEngine is a PRNG.
|
||||
unsigned-integer-overflow:*STPathElement*getHash*
|
||||
unsigned-integer-overflow:*XorShiftEngine*
|
||||
# beast XorShiftEngine PRNG and murmurhash3 mixing wrap by design.
|
||||
unsigned-integer-overflow:beast/xor_shift_engine.h
|
||||
|
||||
# Number::normalizeToRange multiplies the mantissa by powers of ten; the result
|
||||
# is intentionally allowed to wrap while searching for the in-range value.
|
||||
unsigned-integer-overflow:*Number*normalizeToRange*
|
||||
unsigned-integer-overflow:basics/Number.h
|
||||
|
||||
# Counter / sequence arithmetic with intentional unsigned wraparound, each
|
||||
# guarded by an explicit overflow or domain check at the call site:
|
||||
@@ -177,32 +163,34 @@ unsigned-integer-overflow:*Number*normalizeToRange*
|
||||
# ApplyView::insertPage ++page is asserted to wrap to 0 (page exhaustion);
|
||||
# confineOwnerCount documents "overflow is well defined on unsigned";
|
||||
# NFTokenMint checks tokenSeq + 1u == 0u; AmendmentTable does (seq - 1) / 256.
|
||||
unsigned-integer-overflow:*base_uint*operator++*
|
||||
unsigned-integer-overflow:*base_uint*operator--*
|
||||
unsigned-integer-overflow:*insertPage*
|
||||
unsigned-integer-overflow:confineOwnerCount*
|
||||
unsigned-integer-overflow:*NFTokenMint*doApply*
|
||||
unsigned-integer-overflow:*AmendmentTableImpl*needValidatedLedger*
|
||||
unsigned-integer-overflow:basics/base_uint.h
|
||||
unsigned-integer-overflow:ledger/ApplyView.cpp
|
||||
unsigned-integer-overflow:ledger/helpers/AccountRootHelpers.cpp
|
||||
unsigned-integer-overflow:tx/transactors/nft/NFTokenMint.cpp
|
||||
unsigned-integer-overflow:app/misc/detail/AmendmentTable.cpp
|
||||
|
||||
# Sentinel / bounded subtractions that wrap by design (loop counters, reverse
|
||||
# iteration, "not found" sentinels, balance math bounded by issuance invariants).
|
||||
unsigned-integer-overflow:*SHAMap*lowerBound*
|
||||
unsigned-integer-overflow:*permissionToTxType*
|
||||
unsigned-integer-overflow:b256ToB58Be*
|
||||
unsigned-integer-overflow:*base64*decode*
|
||||
unsigned-integer-overflow:*NetworkOPsImp*apply*
|
||||
unsigned-integer-overflow:*NetworkOPsImp*getBookPage*
|
||||
unsigned-integer-overflow:*OracleSet*preclaim*
|
||||
unsigned-integer-overflow:*availableMPTAmount*
|
||||
unsigned-integer-overflow:RFC1751*getWordFromBlob*
|
||||
unsigned-integer-overflow:*StrandFlow*
|
||||
unsigned-integer-overflow:*ValueProxy*operator+*
|
||||
# iteration, "not found" sentinels, balance math bounded by issuance invariants,
|
||||
# base58/base64 codec index math, hash-router and role bit math).
|
||||
unsigned-integer-overflow:shamap/SHAMap.cpp
|
||||
unsigned-integer-overflow:protocol/Permissions.cpp
|
||||
unsigned-integer-overflow:protocol/tokens.cpp
|
||||
unsigned-integer-overflow:basics/base64.cpp
|
||||
unsigned-integer-overflow:json/json_value.cpp
|
||||
unsigned-integer-overflow:app/misc/NetworkOPs.cpp
|
||||
unsigned-integer-overflow:rpc/detail/Role.cpp
|
||||
unsigned-integer-overflow:tx/transactors/oracle/OracleSet.cpp
|
||||
unsigned-integer-overflow:ledger/helpers/MPTokenHelpers.cpp
|
||||
unsigned-integer-overflow:crypto/RFC1751.cpp
|
||||
unsigned-integer-overflow:tx/paths/detail/StrandFlow.h
|
||||
unsigned-integer-overflow:protocol/STObject.h
|
||||
|
||||
# GetAggregatePrice negates an unsigned trim count to step a reverse iterator;
|
||||
# trimCount is bounded by the price set size.
|
||||
unsigned-integer-overflow:*doGetAggregatePrice*
|
||||
unsigned-integer-overflow:rpc/handlers/orderbook/GetAggregatePrice.cpp
|
||||
|
||||
# Test-only intentional overflow/underflow in fixture and unit-test arithmetic.
|
||||
unsigned-integer-overflow:tests/libxrpl/basics/RangeSet.cpp
|
||||
unsigned-integer-overflow:test/app/Batch_test.cpp
|
||||
unsigned-integer-overflow:test/app/Invariants_test.cpp
|
||||
unsigned-integer-overflow:test/app/Loan_test.cpp
|
||||
|
||||
Reference in New Issue
Block a user