Skip to content

Commit

Permalink
Fix insufficient length validation in UDP packets.
Browse files Browse the repository at this point in the history
Found via cargo-fuzz.
  • Loading branch information
whitequark committed Jun 24, 2017
1 parent b33d867 commit 2989fa3
Showing 1 changed file with 18 additions and 5 deletions.
23 changes: 18 additions & 5 deletions src/wire/udp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,22 @@ impl<T: AsRef<[u8]>> Packet<T> {

/// Ensure that no accessor method will panic if called.
/// Returns `Err(Error::Truncated)` if the buffer is too short.
/// Returns `Err(Error::Malformed)` if the length field has a value smaller
/// than the header length.
///
/// The result of this check is invalidated by calling [set_header_len].
/// The result of this check is invalidated by calling [set_len].
///
/// [set_header_len]: #method.set_header_len
/// [set_len]: #method.set_len
pub fn check_len(&self) -> Result<(), Error> {
let len = self.buffer.as_ref().len();
if len < field::CHECKSUM.end {
let buffer_len = self.buffer.as_ref().len();
if buffer_len < field::CHECKSUM.end {
Err(Error::Truncated)
} else {
if len < self.len() as usize {
let field_len = self.len() as usize;
if buffer_len < field_len {
Err(Error::Truncated)
} else if field_len < field::CHECKSUM.end {
Err(Error::Malformed)
} else {
Ok(())
}
Expand Down Expand Up @@ -299,6 +304,14 @@ mod test {
assert_eq!(&packet.into_inner()[..], &PACKET_BYTES[..]);
}

#[test]
fn test_impossible_len() {
let mut bytes = vec![0; 12];
let mut packet = Packet::new(&mut bytes);
packet.set_len(4);
assert_eq!(packet.check_len(), Err(Error::Malformed));
}

fn packet_repr() -> Repr<'static> {
Repr {
src_port: 48896,
Expand Down

0 comments on commit 2989fa3

Please sign in to comment.