Description
Summary
Description
On the Avail Light Client network, we've identified a potential panic in the mDNS implementation when processing response packets with extremely large TTL values. The issue occurs due to an arithmetic overflow when adding a TTL duration to an Instant
.
Root Cause
The issue was identified in the extract_discovered
method in the query.rs
file:
let new_expiration = now + peer.ttl();
Expected behavior
The quoted vulnerable line above should be able to cap the TTL to a reasonable maximum value [say 24 hours].
Actual behavior
This unchecked arithmetic panics when an mDNS packet contains an unusually large TTL value, possibly due to receiving malformed or malicious mDNS packets.
Relevant log output
Error: The application panicked (crashed).
Message: overflow when adding duration to instant
Location: library/std/src/time.rs:417
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ BACKTRACE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⋮ 6 frames hidden ⋮
7: core::option::expect_failed::h8c40d2d654ba3611
at <unknown source file>:<unknown line>
8: tokio::time::interval::Interval::poll_tick::hc1814dc20e3605e4
at <unknown source file>:<unknown line>
9: <libp2p_mdns::behaviour::Behaviour<P> as libp2p_swarm::behaviour::NetworkBehaviour>::poll::ha2bef1b1e29f0bbc
Possible Solution
Replace the vulnerable line with a safer implementation that caps the TTL to a reasonable maximum value:
// Cap TTL to a reasonable maximum (e.g., 24 hours)
let capped_ttl = std::cmp::min(peer.ttl(), Duration::from_secs(86400)); // 86400 seconds = 24 hours
let new_expiration = now + capped_ttl;
Another approach could be to use checked_add with a fallback:
let new_expiration = now.checked_add(peer.ttl())
.unwrap_or_else(|| now + Duration::from_secs(3600)); // Fallback to 1 hour if overflow
Version
0.55.0
Would you like to work on fixing this bug?
Yes