Skip to content

Commit b33d867

Browse files
committed
Fix a crash parsing a malformed IPv4 packet.
Found via cargo-fuzz.
1 parent 6447d94 commit b33d867

File tree

1 file changed

+13
-0
lines changed

1 file changed

+13
-0
lines changed

src/wire/ipv4.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,8 @@ impl Repr {
402402
if packet.header_len() > 20 { return Err(Error::Unrecognized) }
403403
// We do not support fragmentation.
404404
if packet.more_frags() || packet.frag_offset() != 0 { return Err(Error::Fragmented) }
405+
// Total length may not be less than header length.
406+
if packet.total_len() < packet.header_len() as u16 { return Err(Error::Malformed) }
405407
// Since the packet is not fragmented, it must include the entire payload.
406408
let payload_len = packet.total_len() as usize - packet.header_len() as usize;
407409
if packet.payload().len() < payload_len { return Err(Error::Truncated) }
@@ -630,6 +632,17 @@ mod test {
630632
assert_eq!(repr, packet_repr());
631633
}
632634

635+
#[test]
636+
fn test_parse_total_len_underflow() {
637+
let mut bytes = vec![0; 24];
638+
bytes.copy_from_slice(&REPR_PACKET_BYTES[..]);
639+
let mut packet = Packet::new(&mut bytes);
640+
packet.set_total_len(10);
641+
packet.fill_checksum();
642+
let packet = Packet::new(&*packet.into_inner());
643+
assert_eq!(Repr::parse(&packet), Err(Error::Malformed));
644+
}
645+
633646
#[test]
634647
fn test_emit() {
635648
let repr = packet_repr();

0 commit comments

Comments
 (0)