Skip to content

Commit 813b905

Browse files
authored
[ice] Avoid unchecked incrementation of port number to avoid potential panic due to overflow in debug, or silent overflow in release (#719)
When `port_start` is assigned the value `u16::MAX`, and the socket cannot be bound to port `u16::MAX`, an unhandled overflow will occur. When building webrtc-rs using the debug profile, this overflow will lead to a panic, and worse yet in the release profile, a silent overflow and wrap around will occur, allowing `listen_udp_in_port_range` to bind to a port outside of the specified port range.
1 parent 310f7a0 commit 813b905

File tree

1 file changed

+34
-1
lines changed

1 file changed

+34
-1
lines changed

ice/src/util/mod.rs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,8 @@ pub async fn listen_udp_in_port_range(
163163
Err(err) => log::debug!("failed to listen {laddr}: {err}"),
164164
};
165165

166-
port_current += 1;
166+
port_current = port_current.checked_add(1).unwrap_or(i);
167+
167168
if port_current > j {
168169
port_current = i;
169170
}
@@ -174,3 +175,35 @@ pub async fn listen_udp_in_port_range(
174175

175176
Err(Error::ErrPort)
176177
}
178+
179+
#[cfg(test)]
180+
mod tests {
181+
use util::vnet::net::{Net, NetConfig};
182+
183+
use crate::util::listen_udp_in_port_range;
184+
use std::sync::Arc;
185+
186+
#[tokio::test]
187+
async fn test_listen_udp_in_port_range_overflow() {
188+
let vnet = Arc::new(Net::new(Some(NetConfig {
189+
static_ips: vec![],
190+
static_ip: "127.0.0.1".parse().unwrap(),
191+
})));
192+
193+
// Preemptively bind to port 65535 (u16::MAX) to ensure that listen_udp_in_port_range
194+
// triggers overflow logic by being unable to bind to port 65535 itself.
195+
let _conn = vnet
196+
.bind("127.0.0.1:65535".parse().unwrap())
197+
.await
198+
.expect("Expected binding to vnet to succeed");
199+
200+
let port_max = u16::MAX;
201+
let port_min = u16::MAX;
202+
203+
assert!(matches!(
204+
listen_udp_in_port_range(&vnet, port_max, port_min, "127.0.0.1:0".parse().unwrap())
205+
.await,
206+
Err(crate::Error::ErrPort)
207+
))
208+
}
209+
}

0 commit comments

Comments
 (0)