Summary
When the selected range begins at MessageNonce::MAX, the expression
begin + count - 1 performs the overflowing MAX + 1 intermediate calculation in
debug builds instead of returning the valid range MAX..=MAX.
This finding was found by Runtime Whitebox Fuzzer.
Severity / Sensitivity
Low severity, non-sensitive. This is a public boundary arithmetic defect in message-range construction.
Source Evidence
bridges/relays/messages/src/message_race_limits.rs:78-81: best_target_nonce = MAX - 1 produces a valid begin nonce of MAX.
bridges/relays/messages/src/message_race_limits.rs:165-168: range-end arithmetic then overflows.
PoC Unit Test
Place this in bridges/relays/messages/src/generated_tests.rs. The helper is
repeated so this PoC can be pasted independently of finding 4.
use super::*;
use bp_messages::{MessageNonce, Weight};
use crate::message_lane_loop::{MessageDetails, MessageDetailsMap};
use crate::message_lane_loop::tests::{header_id, TestMessageLane};
use crate::message_race_limits::{MessageRaceLimits, RelayMessagesBatchReference};
fn single_max_nonce_reference() -> RelayMessagesBatchReference<TestMessageLane> {
let mut details = MessageDetailsMap::new();
details.insert(
MessageNonce::MAX,
MessageDetails { dispatch_weight: Weight::from_parts(1, 0), size: 1, reward: 0 },
);
RelayMessagesBatchReference::<TestMessageLane> {
max_messages_in_this_batch: 10,
max_messages_weight_in_single_batch: Weight::from_parts(100, 0),
max_messages_size_in_single_batch: 1_000,
best_target_nonce: MessageNonce::MAX - 1,
nonces_queue: vec![(header_id(1), details)].into_iter().collect(),
nonces_queue_range: 0..=0,
}
}
// RWF-INVARIANTS: inv_wu594hra
// RWF-RISKS: risk_yq5p6bas
#[ignore]
#[tokio::test]
async fn test_inv_wu594hra_decide_single_message_near_max_boundary() {
let range = MessageRaceLimits::decide(single_max_nonce_reference())
.await
.expect("the single MAX nonce message must be deliverable");
assert_eq!(*range.start(), MessageNonce::MAX);
assert_eq!(*range.end(), MessageNonce::MAX);
}
Reproduction Command
cargo test -p messages-relay \
generated_tests::test_inv_wu594hra_decide_single_message_near_max_boundary \
-- --ignored --exact --nocapture
Observed Result
panicked at bridges/relays/messages/src/message_race_limits.rs:167:17:
attempt to add with overflow
Expected Behavior
Return the single-message range MessageNonce::MAX..=MessageNonce::MAX without an
overflowing intermediate calculation.
Likely Fix Direction
Compute the inclusive range end without an overflowing intermediate, using checked arithmetic and preserving the valid MAX..=MAX case.
RWF Metadata
Summary
When the selected range begins at
MessageNonce::MAX, the expressionbegin + count - 1performs the overflowingMAX + 1intermediate calculation indebug builds instead of returning the valid range
MAX..=MAX.This finding was found by Runtime Whitebox Fuzzer.
Severity / Sensitivity
Low severity, non-sensitive. This is a public boundary arithmetic defect in message-range construction.
Source Evidence
bridges/relays/messages/src/message_race_limits.rs:78-81:best_target_nonce = MAX - 1produces a valid begin nonce ofMAX.bridges/relays/messages/src/message_race_limits.rs:165-168: range-end arithmetic then overflows.PoC Unit Test
Place this in
bridges/relays/messages/src/generated_tests.rs. The helper isrepeated so this PoC can be pasted independently of finding 4.
Reproduction Command
cargo test -p messages-relay \ generated_tests::test_inv_wu594hra_decide_single_message_near_max_boundary \ -- --ignored --exact --nocaptureObserved Result
Expected Behavior
Return the single-message range
MessageNonce::MAX..=MessageNonce::MAXwithout anoverflowing intermediate calculation.
Likely Fix Direction
Compute the inclusive range end without an overflowing intermediate, using checked arithmetic and preserving the valid
MAX..=MAXcase.RWF Metadata
Found by Runtime Whitebox Fuzzer
Finding:
find_5wqne5x69xTarget:
messages-relaySeverity:
lowCategory:
arithmetic overflow