#36366 net: limit relative ban times to uint32

ReviewabilityReviewsAgreementSize
#36366 Bruce039 net: limit relative ban times to uint32Ready0 (+1)Strong6 + 25 tests
  • Prevent signed integer overflow and silent ban drops when users set very large relative ban durations
  • Reject excessive durations in setban and clamp the bantime startup setting to safe maximum limits
  • Review is worthwhile now with no blocking issues
  • Substantive support for clamping or rejecting values larger than realistic use cases (maflcko)
  • Author pushed a fix after startup failure was flagged for large bantime in settings.json (willcl-ark)
  • 6 lines added or modified outside tests
  • 25 lines added or modified in tests
  • 1 lines removed in total
  • 3 files, 1 commits
RPC / REST / ZMQ#28 of 55
P3 · bug fix
  • P3 because it fixes an overflow bug where extreme ban durations silently expire immediately
  • Avoids misleading success returns from setban while addressing a UBSan runtime failure
  • Ranking pass: Moved up 15: setban silently dropping bans while reporting success is a false-success bug like the others grouped here.
Reviewability: ReadyStalePaused
Agreement: StrongPositivePositive w/ caveatsNeutralMildDisputedBlockedCrickets
Reviews: current code-review ACKs, then (+stale ACKs) and -NACKs; greener = more ACKs.
Size: lines added or modified outside tests, then in tests; greener = smaller.

Goal

Caps relative ban durations to UINT32_MAX in both the setban RPC and the -bantime configuration argument. The setban RPC rejects relative ban durations exceeding UINT32_MAX with an invalid parameter error, while -bantime clamps values greater than UINT32_MAX using std::min. Absolute timestamps remain unaffected.

Problem: BanMan calculates ban expiration as GetTime() + bantime using signed 64-bit integers. If a relative ban duration near INT64_MAX is provided, the addition overflows, causing a signed integer overflow runtime error under UBSan; without UBSan, it wraps negative, causing the node to treat the ban as already expired and silently drop it while setban still returns success.

Evidence of importance:

  • PR description quotes a UBSan runtime error: src/banman.cpp:140:73: runtime error: signed integer overflow: 1790412558 + 9223372036854775807 cannot be represented in type 'int64_t'

Risk of a mistake: medium (rpc_api). A flaw in duration validation could reject valid bans or cause bans to expire at unintended times for node operators.

Changed since the previous assessment: Switched from parsing -bantime as uint32_t to keeping GetIntArg and clamping with std::min so oversized values in settings.json do not abort node startup, and added a test for settings.json.

Reviewability

Ready

Nothing known that would invalidate a review now.

Waiting on (from the thread read):

  • reviewer: willcl-ark to review fix for settings.json bantime parsing 2026-10-02

Agreement

Strong

substantive support, no open objection (maflcko)

Thread notes: willcl-ark pointed out an issue where values > uint32 in settings.json throw on startup; the author pushed a fix parsing as int64 and capping at UINT32_MAX.

Objections, suggestions, and questions:

ReviewerTypeHarm, request, or questionStatusMust beAuthor repliedQuote
maflcko (member)objection, approachSupporting durations unsupported by C++ chrono using SaturatingAdd does not work for chrono types; excessively large bantime arguments should be rejected insteadaccepted · fix pushed · author switched to rejecting large bantimes and reviewer accepted with an ACKchangedyes2026-09-28: 'I am not sure about starting/trying to support durations that C++ itself doesn't even support... Also, `SaturatingAdd` doesn't work for chrono types ...'
Status from: 2026-09-29: maflcko: 'Seems fine to reject or clamp values larger than any meaningful use-case.'
maflcko (member)suggestion, approachReject relative ban times above UINT32_MAX to avoid a time dependencyaccepted · fix pushed · author implemented uint32 limit in setban and reviewer ACKedansweredyes2026-09-29: 'This should be more than enough and also avoid the weird time dependency.'
Status from: 2026-09-29: maflcko: 'lgtm ACK d49c1c9ab3e139158d76141b71943ff79903e87a'
maflcko (member)suggestion, approachParse bantime as u32accepted · fix pushed · author parsed -bantime as uint32_t and reviewer ACKedansweredyes2026-09-29: 'What about parsing it as u32?'
Status from: 2026-09-29: maflcko: 'lgtm ACK d49c1c9ab3e139158d76141b71943ff79903e87a'
willcl-ark (member)objection, correctnessA bantime value greater than uint32 in settings.json throws during conversion on startupfixed · fix pushed · author reverted -bantime parsing to int64, capped at UINT32_MAX, and added a test casechangedyes2026-10-02: 'settings.json can also have a value > uint32 which will throw during conversion'
Status from: 2026-10-02: Bruce039: '`-bantime` is now read as int64 again and capped at UINT32_MAX, so it no longer matters where the value comes from.'

Support:

  • maflcko (member) (ACK, 2026-09-29) [read]: Seems fine to reject or clamp values larger than any meaningful use-case.

Participants:

  • maflcko (member, support, 3 statements 2026-09-28 to 2026-09-29): ACKed after author addressed objection to SaturatingAdd and adopted suggestions to limit bantime to uint32
  • willcl-ark (member, objection, 1 statements 2026-10-02 to 2026-10-02): pointed out bantime > uint32 in settings.json throws on startup

Files

25 lines under test/bench/ci.

  • test/functional/rpc_setban.py +25/-0
  • src/rpc/net.cpp +5/-0
  • src/init.cpp +1/-1

Card

The short text the ranking pass compares across PRs.

Caps relative ban durations to UINT32_MAX across the setban RPC and the -bantime startup option. Relative ban durations near INT64_MAX currently cause signed 64-bit integer overflow in BanMan, triggering UBSan errors and wrapping to negative timestamps that silently discard bans while reporting success. With this change, setban rejects relative durations exceeding UINT32_MAX, and -bantime clamps larger values without failing startup.

Data

dossier JSON · extract JSON · model ledger, generated 2026-10-04T01:17, confidence high, input hash 13aca77bf9eee554
thread read through 2026-10-02 (7 statements), head 514ff32e2f
labels: RPC/REST/ZMQ

Categories

RPC / REST / ZMQ

P3 · bug fix (ranking pass: Moved up 15: setban silently dropping bans while reporting success is a false-success bug like the others grouped here.)

Prevents signed integer overflow and silent ban drops when callers provide relative ban times near INT64_MAX. As noted in the description, 'GetTime() + bantime... wraps negative, causing the node to treat the ban as already expired and silently drop it while setban still returns success.'

Membership: Matches RPC/REST/ZMQ label and modifies `src/rpc/net.cpp` parameter validation for the `setban` RPC method.

Factors: security/stability 1, bug 1, performance 0, user value 0, leverage 0