BanMan::Ban computes the ban end as GetTime() + bantime (banman.cpp:140). setban and -bantime both accept any int64, so a relative bantime close to INT64_MAX:
setban 1.2.3.5 add 9223372036854775807
returns success, but the sum overflows. UBSan reports:
src/banman.cpp:140:73: runtime error: signed integer overflow: 1790412558 + 9223372036854775807 cannot be represented in type 'int64_t'
Without UBSan the result wraps negative, the ban is treated as already expired, and it is silently dropped. With -bantime=9223372036854775807 the same happens to every setban add that uses the default duration.
This limits relative ban times to uint32 (about 136 years):
setbanrejects a relative bantime aboveUINT32_MAXwith "Error: bantime is too large"-bantimeis parsed asuint32_t, so larger values saturate atUINT32_MAX
Absolute timestamps are unchanged.
The added cases in rpc_setban.py check that UINT32_MAX + 1 and INT64_MAX are rejected, that UINT32_MAX is accepted, and that with -bantime=INT64_MAX a default-duration ban is listed with a duration of UINT32_MAX. Both parts fail on master and pass with the change. p2p_disconnect_ban.py still passes.
AI tools were used to help find this issue and to prepare the patch and test.