From d53bdab0298674eec0772e3332684020385f2cd0 Mon Sep 17 00:00:00 2001 From: whitequark Date: Wed, 30 Aug 2017 13:34:50 +0000 Subject: [PATCH] Fix Ipv4Packet::payload{,_mut}() returning overly long buffers. These functions only skipped the header, but what they should have done is cut the packet at its total length and skip the header. Otherwise, if the buffer the IP packet is constructed from contains padding, such as Ethernet packets, the payload would be too long. --- src/wire/ipv4.rs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/wire/ipv4.rs b/src/wire/ipv4.rs index f1370a9..7f77bb0 100644 --- a/src/wire/ipv4.rs +++ b/src/wire/ipv4.rs @@ -248,9 +248,9 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Packet<&'a T> { /// Return a pointer to the payload. #[inline] pub fn payload(&self) -> &'a [u8] { - let range = self.header_len() as usize; + let range = self.header_len() as usize..self.total_len() as usize; let data = self.buffer.as_ref(); - &data[range..] + &data[range] } } @@ -381,7 +381,7 @@ impl<'a, T: AsRef<[u8]> + AsMut<[u8]> + ?Sized> Packet<&'a mut T> { /// Return a mutable pointer to the payload. #[inline] pub fn payload_mut(&mut self) -> &mut [u8] { - let range = self.header_len() as usize..; + let range = self.header_len() as usize..self.total_len() as usize; let data = self.buffer.as_mut(); &mut data[range] } @@ -611,6 +611,18 @@ mod test { assert_eq!(&packet.into_inner()[..], &PACKET_BYTES[..]); } + #[test] + fn test_overlong() { + let mut bytes = vec![]; + bytes.extend(&PACKET_BYTES[..]); + bytes.push(0); + + assert_eq!(Packet::new(&bytes).payload().len(), + PAYLOAD_BYTES.len()); + assert_eq!(Packet::new(&mut bytes).payload_mut().len(), + PAYLOAD_BYTES.len()); + } + static REPR_PACKET_BYTES: [u8; 24] = [0x45, 0x00, 0x00, 0x18, 0x00, 0x00, 0x40, 0x00,