Skip to content

Commit

Permalink
Fix Ipv4Packet::payload{,_mut}() returning overly long buffers.
Browse files Browse the repository at this point in the history
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.
whitequark committed Aug 30, 2017
1 parent 1ece71a commit 280ddde
Showing 1 changed file with 15 additions and 3 deletions.
18 changes: 15 additions & 3 deletions src/wire/ipv4.rs
Original file line number Diff line number Diff line change
@@ -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,

0 comments on commit 280ddde

Please sign in to comment.