mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-05-07 10:14:35 +00:00
fix: avoid panic on malformed short tunnel packets (#1904)
This commit is contained in:
@@ -366,7 +366,9 @@ impl crate::tunnel::TunnelConnector for FakeTcpTunnelConnector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use crate::tunnel::packet_def::{ZCPacket, ZCPacketType};
|
use crate::tunnel::packet_def::{
|
||||||
|
ZCPacket, ZCPacketType, PEER_MANAGER_HEADER_SIZE, TCP_TUNNEL_HEADER_SIZE,
|
||||||
|
};
|
||||||
use crate::tunnel::{SinkError, SinkItem, StreamItem};
|
use crate::tunnel::{SinkError, SinkItem, StreamItem};
|
||||||
use futures::{Sink, Stream};
|
use futures::{Sink, Stream};
|
||||||
use std::task::{Context as TaskContext, Poll};
|
use std::task::{Context as TaskContext, Poll};
|
||||||
@@ -407,7 +409,18 @@ impl Stream for FakeTcpStream {
|
|||||||
let packet = ZCPacket::new_from_buf(buf, ZCPacketType::TCP);
|
let packet = ZCPacket::new_from_buf(buf, ZCPacketType::TCP);
|
||||||
if let Some(tcp_hdr) = packet.tcp_tunnel_header() {
|
if let Some(tcp_hdr) = packet.tcp_tunnel_header() {
|
||||||
let expected_payload_len = tcp_hdr.len.get() as usize;
|
let expected_payload_len = tcp_hdr.len.get() as usize;
|
||||||
if expected_payload_len <= buf_len && expected_payload_len != 0 {
|
let min_packet_len = TCP_TUNNEL_HEADER_SIZE + PEER_MANAGER_HEADER_SIZE;
|
||||||
|
if expected_payload_len < min_packet_len {
|
||||||
|
tracing::warn!(
|
||||||
|
"drop fake tcp packet with invalid length: expected_payload_len={}, min_required={}",
|
||||||
|
expected_payload_len,
|
||||||
|
min_packet_len
|
||||||
|
);
|
||||||
|
s.state = FakeTcpStreamState::Closed;
|
||||||
|
return Poll::Ready(None);
|
||||||
|
}
|
||||||
|
|
||||||
|
if expected_payload_len <= buf_len {
|
||||||
let mut buf = packet.inner();
|
let mut buf = packet.inner();
|
||||||
let new_inner = buf.split_to(expected_payload_len);
|
let new_inner = buf.split_to(expected_payload_len);
|
||||||
s.state = FakeTcpStreamState::ConsumingBuf(buf);
|
s.state = FakeTcpStreamState::ConsumingBuf(buf);
|
||||||
|
|||||||
@@ -437,6 +437,14 @@ pub struct ZCPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ZCPacket {
|
impl ZCPacket {
|
||||||
|
fn bytes_from_offset(&self, offset: usize) -> Option<&[u8]> {
|
||||||
|
self.inner.get(offset..)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mut_bytes_from_offset(&mut self, offset: usize) -> Option<&mut [u8]> {
|
||||||
|
self.inner.get_mut(offset..)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new_nic_packet() -> Self {
|
pub fn new_nic_packet() -> Self {
|
||||||
Self {
|
Self {
|
||||||
inner: BytesMut::new(),
|
inner: BytesMut::new(),
|
||||||
@@ -517,39 +525,39 @@ impl ZCPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn mut_peer_manager_header(&mut self) -> Option<&mut PeerManagerHeader> {
|
pub fn mut_peer_manager_header(&mut self) -> Option<&mut PeerManagerHeader> {
|
||||||
PeerManagerHeader::mut_from_prefix(
|
let offset = self
|
||||||
&mut self.inner[self
|
.packet_type
|
||||||
.packet_type
|
.get_packet_offsets()
|
||||||
.get_packet_offsets()
|
.peer_manager_header_offset;
|
||||||
.peer_manager_header_offset..],
|
let bytes = self.mut_bytes_from_offset(offset)?;
|
||||||
)
|
PeerManagerHeader::mut_from_prefix(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mut_tcp_tunnel_header(&mut self) -> Option<&mut TCPTunnelHeader> {
|
pub fn mut_tcp_tunnel_header(&mut self) -> Option<&mut TCPTunnelHeader> {
|
||||||
TCPTunnelHeader::mut_from_prefix(
|
let offset = self
|
||||||
&mut self.inner[self
|
.packet_type
|
||||||
.packet_type
|
.get_packet_offsets()
|
||||||
.get_packet_offsets()
|
.tcp_tunnel_header_offset;
|
||||||
.tcp_tunnel_header_offset..],
|
let bytes = self.mut_bytes_from_offset(offset)?;
|
||||||
)
|
TCPTunnelHeader::mut_from_prefix(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mut_udp_tunnel_header(&mut self) -> Option<&mut UDPTunnelHeader> {
|
pub fn mut_udp_tunnel_header(&mut self) -> Option<&mut UDPTunnelHeader> {
|
||||||
UDPTunnelHeader::mut_from_prefix(
|
let offset = self
|
||||||
&mut self.inner[self
|
.packet_type
|
||||||
.packet_type
|
.get_packet_offsets()
|
||||||
.get_packet_offsets()
|
.udp_tunnel_header_offset;
|
||||||
.udp_tunnel_header_offset..],
|
let bytes = self.mut_bytes_from_offset(offset)?;
|
||||||
)
|
UDPTunnelHeader::mut_from_prefix(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mut_wg_tunnel_header(&mut self) -> Option<&mut WGTunnelHeader> {
|
pub fn mut_wg_tunnel_header(&mut self) -> Option<&mut WGTunnelHeader> {
|
||||||
WGTunnelHeader::mut_from_prefix(
|
let offset = self
|
||||||
&mut self.inner[self
|
.packet_type
|
||||||
.packet_type
|
.get_packet_offsets()
|
||||||
.get_packet_offsets()
|
.wg_tunnel_header_offset;
|
||||||
.wg_tunnel_header_offset..],
|
let bytes = self.mut_bytes_from_offset(offset)?;
|
||||||
)
|
WGTunnelHeader::mut_from_prefix(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ref versions
|
// ref versions
|
||||||
@@ -562,30 +570,30 @@ impl ZCPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn peer_manager_header(&self) -> Option<&PeerManagerHeader> {
|
pub fn peer_manager_header(&self) -> Option<&PeerManagerHeader> {
|
||||||
PeerManagerHeader::ref_from_prefix(
|
let offset = self
|
||||||
&self.inner[self
|
.packet_type
|
||||||
.packet_type
|
.get_packet_offsets()
|
||||||
.get_packet_offsets()
|
.peer_manager_header_offset;
|
||||||
.peer_manager_header_offset..],
|
let bytes = self.bytes_from_offset(offset)?;
|
||||||
)
|
PeerManagerHeader::ref_from_prefix(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tcp_tunnel_header(&self) -> Option<&TCPTunnelHeader> {
|
pub fn tcp_tunnel_header(&self) -> Option<&TCPTunnelHeader> {
|
||||||
TCPTunnelHeader::ref_from_prefix(
|
let offset = self
|
||||||
&self.inner[self
|
.packet_type
|
||||||
.packet_type
|
.get_packet_offsets()
|
||||||
.get_packet_offsets()
|
.tcp_tunnel_header_offset;
|
||||||
.tcp_tunnel_header_offset..],
|
let bytes = self.bytes_from_offset(offset)?;
|
||||||
)
|
TCPTunnelHeader::ref_from_prefix(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn udp_tunnel_header(&self) -> Option<&UDPTunnelHeader> {
|
pub fn udp_tunnel_header(&self) -> Option<&UDPTunnelHeader> {
|
||||||
UDPTunnelHeader::ref_from_prefix(
|
let offset = self
|
||||||
&self.inner[self
|
.packet_type
|
||||||
.packet_type
|
.get_packet_offsets()
|
||||||
.get_packet_offsets()
|
.udp_tunnel_header_offset;
|
||||||
.udp_tunnel_header_offset..],
|
let bytes = self.bytes_from_offset(offset)?;
|
||||||
)
|
UDPTunnelHeader::ref_from_prefix(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn udp_payload(&self) -> &[u8] {
|
pub fn udp_payload(&self) -> &[u8] {
|
||||||
@@ -751,4 +759,24 @@ mod tests {
|
|||||||
assert_eq!(&tcp_packet[..1], b"\x0b");
|
assert_eq!(&tcp_packet[..1], b"\x0b");
|
||||||
println!("{:?}", tcp_packet);
|
println!("{:?}", tcp_packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_short_tcp_packet_header_access_is_safe() {
|
||||||
|
let mut packet = ZCPacket::new_from_buf(BytesMut::from(&b"\x01"[..]), ZCPacketType::TCP);
|
||||||
|
|
||||||
|
assert!(packet.peer_manager_header().is_none());
|
||||||
|
assert!(packet.tcp_tunnel_header().is_none());
|
||||||
|
assert!(packet.udp_tunnel_header().is_none());
|
||||||
|
assert!(packet.mut_peer_manager_header().is_none());
|
||||||
|
assert!(packet.mut_tcp_tunnel_header().is_none());
|
||||||
|
assert!(packet.mut_udp_tunnel_header().is_none());
|
||||||
|
assert!(packet.mut_wg_tunnel_header().is_none());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_invalid_converted_header_offset_is_safe() {
|
||||||
|
let mut packet = ZCPacket::new_from_buf(BytesMut::from(&b"\x01"[..]), ZCPacketType::UDP);
|
||||||
|
|
||||||
|
assert!(packet.mut_wg_tunnel_header().is_none());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user