浏览代码

Reject certain malformed IPv4 packets.

Reported independently, but testcase found via cargo-fuzz.
whitequark 7 年之前
父节点
当前提交
181083f18c
共有 1 个文件被更改,包括 11 次插入0 次删除
  1. 11 0
      src/wire/ipv4.rs

+ 11 - 0
src/wire/ipv4.rs

@@ -184,6 +184,8 @@ impl<T: AsRef<[u8]>> Packet<T> {
 
 
     /// Ensure that no accessor method will panic if called.
     /// Ensure that no accessor method will panic if called.
     /// Returns `Err(Error::Truncated)` if the buffer is too short.
     /// Returns `Err(Error::Truncated)` if the buffer is too short.
+    /// Returns `Err(Error::Malformed)` if the header length is greater
+    /// than total length.
     ///
     ///
     /// The result of this check is invalidated by calling [set_header_len]
     /// The result of this check is invalidated by calling [set_header_len]
     /// and [set_total_len].
     /// and [set_total_len].
@@ -196,6 +198,8 @@ impl<T: AsRef<[u8]>> Packet<T> {
             Err(Error::Truncated)
             Err(Error::Truncated)
         } else if len < self.header_len() as usize {
         } else if len < self.header_len() as usize {
             Err(Error::Truncated)
             Err(Error::Truncated)
+        } else if self.header_len() as u16 > self.total_len() {
+            Err(Error::Malformed)
         } else if len < self.total_len() as usize {
         } else if len < self.total_len() as usize {
             Err(Error::Truncated)
             Err(Error::Truncated)
         } else {
         } else {
@@ -739,6 +743,13 @@ mod test {
         assert_eq!(Repr::parse(&packet, &ChecksumCapabilities::default()), Err(Error::Malformed));
         assert_eq!(Repr::parse(&packet, &ChecksumCapabilities::default()), Err(Error::Malformed));
     }
     }
 
 
+    #[test]
+    fn test_parse_total_len_less_than_header_len() {
+        let mut bytes = vec![0; 40];
+        bytes[0] = 0x09;
+        assert_eq!(Packet::new_checked(&mut bytes), Err(Error::Malformed));
+    }
+
     #[test]
     #[test]
     fn test_emit() {
     fn test_emit() {
         let repr = packet_repr();
         let repr = packet_repr();