-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Bug: Arithmetic overflow in mDNS implementation when adding TTL to Instant #5943
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hey! Nice catch on the possible overflow. While I am not against having it fixed to a specific value if it does overflow, I am curious on if we should also have this apart of libp2p spec as well so it would possibly be more consistent in such cases where there is a overflow. |
If that overflow is due to a malformed or malicious packet do we even want to handle the content? IMO it's also reasonable to just filter out a peer in a response if the ttl is invalid. |
Hey guys, thanks for the prompt responses, really appreciate it. Without defining fallback TTL values to compare to, would something like this be a suitable change for the response handling? pub(crate) fn extract_discovered(
&self,
now: Instant,
local_peer_id: PeerId,
) -> impl Iterator<Item = (PeerId, Multiaddr, Instant)> + '_ {
self.discovered_peers()
.filter(move |peer| peer.id() != &local_peer_id)
// Filter out peers whose TTL would cause overflow
.filter(move |peer| now.checked_add(peer.ttl()).is_some())
.flat_map(move |peer| {
let observed = self.observed_address();
// Safe to use direct addition since we've filtered out overflow cases
let new_expiration = now + peer.ttl();
peer.addresses().iter().filter_map(move |address| {
let new_addr = _address_translation(address, &observed)?;
let new_addr = new_addr.with_p2p(*peer.id()).ok()?;
Some((*peer.id(), new_addr, new_expiration))
})
})
} |
Yes, that's what I was thinking too. I think we can simply do: self.discovered_peers()
.filter_map(|peer| {
if peer.id() != &local_peer_id {
return None;
}
let new_expiration = now.checked_add(peer.ttl())?;
Some((peer, new_expiration))
}
.flat_map(|(peer, new_expiration)| {
let observed = self.observed_address();
...
} |
Hey hey, the initial changes were meant to keep things minimal, but I’m totally on board with simplifying the code.
maan, I hate negations ! 🗡 Looking at the possible filter_map combinations now, the one with just the added filter feels like the cleanest and easiest to follow. |
Ah yes, that was a typo, I meant Anyway, let's discuss this on the PR :) |
Awesome, really appreciate all your help guys. |
Reopening the issue just to track properly how/ when it is resolved. |
Uh oh!
There was an error while loading. Please reload this page.
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 thequery.rs
file: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
Possible Solution
Replace the vulnerable line with a safer implementation that caps the TTL to a reasonable maximum value:
Another approach could be to use checked_add with a fallback:
Version
0.55.0
Would you like to work on fixing this bug?
Yes
The text was updated successfully, but these errors were encountered: