瀏覽代碼

Update sixlowpan fuzzer

Thibaut Vandervelden 2 年之前
父節點
當前提交
4767aadcb4

+ 2 - 8
fuzz/Cargo.toml

@@ -43,13 +43,7 @@ test = false
 doc = false
 
 [[bin]]
-name = "sixlowpan_udp_header"
-path = "fuzz_targets/sixlowpan_udp_header.rs"
-test = false
-doc = false
-
-[[bin]]
-name = "sixlowpan_iphc_header"
-path = "fuzz_targets/sixlowpan_iphc_header.rs"
+name = "sixlowpan_packet"
+path = "fuzz_targets/sixlowpan_packet.rs"
 test = false
 doc = false

+ 0 - 42
fuzz/fuzz_targets/sixlowpan_iphc_header.rs

@@ -1,42 +0,0 @@
-#![no_main]
-use libfuzzer_sys::fuzz_target;
-use smoltcp::wire::{Ieee802154Address, SixlowpanIphcPacket, SixlowpanIphcRepr};
-
-#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, arbitrary::Arbitrary)]
-pub enum AddressFuzzer {
-    Absent,
-    Short([u8; 2]),
-    Extended([u8; 8]),
-}
-
-impl From<AddressFuzzer> for Ieee802154Address {
-    fn from(val: AddressFuzzer) -> Self {
-        match val {
-            AddressFuzzer::Absent => Ieee802154Address::Absent,
-            AddressFuzzer::Short(b) => Ieee802154Address::Short(b),
-            AddressFuzzer::Extended(b) => Ieee802154Address::Extended(b),
-        }
-    }
-}
-
-#[derive(Debug, arbitrary::Arbitrary)]
-struct SixlowpanIphcPacketFuzzer<'a> {
-    data: &'a [u8],
-    ll_src_addr: Option<AddressFuzzer>,
-    ll_dst_addr: Option<AddressFuzzer>,
-}
-
-fuzz_target!(|fuzz: SixlowpanIphcPacketFuzzer| {
-    if let Ok(ref frame) = SixlowpanIphcPacket::new_checked(fuzz.data) {
-        if let Ok(repr) = SixlowpanIphcRepr::parse(
-            frame,
-            fuzz.ll_src_addr.map(Into::into),
-            fuzz.ll_dst_addr.map(Into::into),
-        ) {
-            let mut buffer = vec![0; repr.buffer_len()];
-
-            let mut frame = SixlowpanIphcPacket::new_unchecked(&mut buffer[..]);
-            repr.emit(&mut frame);
-        }
-    };
-});

+ 240 - 0
fuzz/fuzz_targets/sixlowpan_packet.rs

@@ -0,0 +1,240 @@
+#![no_main]
+use libfuzzer_sys::fuzz_target;
+use smoltcp::{phy::ChecksumCapabilities, wire::*};
+
+#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, arbitrary::Arbitrary)]
+pub enum AddressFuzzer {
+    Absent,
+    Short([u8; 2]),
+    Extended([u8; 8]),
+}
+
+impl From<AddressFuzzer> for Ieee802154Address {
+    fn from(val: AddressFuzzer) -> Self {
+        match val {
+            AddressFuzzer::Absent => Ieee802154Address::Absent,
+            AddressFuzzer::Short(b) => Ieee802154Address::Short(b),
+            AddressFuzzer::Extended(b) => Ieee802154Address::Extended(b),
+        }
+    }
+}
+
+#[derive(Debug, arbitrary::Arbitrary)]
+struct SixlowpanPacketFuzzer<'a> {
+    data: &'a [u8],
+    ll_src_addr: Option<AddressFuzzer>,
+    ll_dst_addr: Option<AddressFuzzer>,
+}
+
+fuzz_target!(|fuzz: SixlowpanPacketFuzzer| {
+    match SixlowpanPacket::dispatch(fuzz.data) {
+        Ok(SixlowpanPacket::FragmentHeader) => {
+            if let Ok(frame) = SixlowpanFragPacket::new_checked(fuzz.data) {
+                if let Ok(repr) = SixlowpanFragRepr::parse(&frame) {
+                    let mut buffer = vec![0; repr.buffer_len()];
+                    let mut frame = SixlowpanFragPacket::new_unchecked(&mut buffer[..]);
+                    repr.emit(&mut frame);
+                }
+            }
+        }
+        Ok(SixlowpanPacket::IphcHeader) => {
+            if let Ok(frame) = SixlowpanIphcPacket::new_checked(fuzz.data) {
+                if let Ok(iphc_repr) = SixlowpanIphcRepr::parse(
+                    &frame,
+                    fuzz.ll_src_addr.map(Into::into),
+                    fuzz.ll_dst_addr.map(Into::into),
+                ) {
+                    let mut buffer = vec![0; iphc_repr.buffer_len()];
+                    let mut iphc_frame = SixlowpanIphcPacket::new_unchecked(&mut buffer[..]);
+                    iphc_repr.emit(&mut iphc_frame);
+
+                    let payload = frame.payload();
+                    match iphc_repr.next_header {
+                        SixlowpanNextHeader::Compressed => {
+                            if let Ok(p) = SixlowpanNhcPacket::dispatch(payload) {
+                                match p {
+                                    SixlowpanNhcPacket::ExtHeader => {
+                                        if let Ok(frame) =
+                                            SixlowpanExtHeaderPacket::new_checked(payload)
+                                        {
+                                            if let Ok(repr) = SixlowpanExtHeaderRepr::parse(&frame)
+                                            {
+                                                let mut buffer = vec![0; repr.buffer_len()];
+                                                let mut ext_header_frame =
+                                                    SixlowpanExtHeaderPacket::new_unchecked(
+                                                        &mut buffer[..],
+                                                    );
+                                                repr.emit(&mut ext_header_frame);
+                                            }
+                                        }
+                                    }
+                                    SixlowpanNhcPacket::UdpHeader => {
+                                        if let Ok(frame) =
+                                            SixlowpanUdpNhcPacket::new_checked(payload)
+                                        {
+                                            if let Ok(repr) = SixlowpanUdpNhcRepr::parse(
+                                                &frame,
+                                                &iphc_repr.src_addr,
+                                                &iphc_repr.dst_addr,
+                                            ) {
+                                                let mut buffer = vec![
+                                                    0;
+                                                    repr.header_len()
+                                                        + frame.payload().len()
+                                                ];
+                                                let mut udp_packet =
+                                                    SixlowpanUdpNhcPacket::new_unchecked(
+                                                        &mut buffer[..],
+                                                    );
+                                                repr.emit(
+                                                    &mut udp_packet,
+                                                    &iphc_repr.src_addr,
+                                                    &iphc_repr.dst_addr,
+                                                    frame.payload().len(),
+                                                    |b| b.copy_from_slice(frame.payload()),
+                                                );
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                        SixlowpanNextHeader::Uncompressed(proto) => match proto {
+                            IpProtocol::HopByHop => {
+                                if let Ok(frame) = Ipv6HopByHopHeader::new_checked(payload) {
+                                    if let Ok(repr) = Ipv6HopByHopRepr::parse(&frame) {
+                                        let mut buffer = vec![0; repr.buffer_len()];
+                                        let mut hop_by_hop_frame =
+                                            Ipv6HopByHopHeader::new_unchecked(&mut buffer[..]);
+                                        repr.emit(&mut hop_by_hop_frame);
+                                    }
+                                }
+                            }
+                            IpProtocol::Icmp => {
+                                if let Ok(frame) = Icmpv4Packet::new_checked(payload) {
+                                    if let Ok(repr) =
+                                        Icmpv4Repr::parse(&frame, &ChecksumCapabilities::default())
+                                    {
+                                        let mut buffer = vec![0; repr.buffer_len()];
+                                        let mut icmpv4_packet =
+                                            Icmpv4Packet::new_unchecked(&mut buffer[..]);
+                                        repr.emit(
+                                            &mut icmpv4_packet,
+                                            &ChecksumCapabilities::default(),
+                                        );
+                                    }
+                                }
+                            }
+                            IpProtocol::Igmp => {
+                                if let Ok(frame) = IgmpPacket::new_checked(payload) {
+                                    if let Ok(repr) = IgmpRepr::parse(&frame) {
+                                        let mut buffer = vec![0; repr.buffer_len()];
+                                        let mut frame = IgmpPacket::new_unchecked(&mut buffer[..]);
+                                        repr.emit(&mut frame);
+                                    }
+                                }
+                            }
+                            IpProtocol::Tcp => {
+                                if let Ok(frame) = TcpPacket::new_checked(payload) {
+                                    if let Ok(repr) = TcpRepr::parse(
+                                        &frame,
+                                        &iphc_repr.src_addr.into_address(),
+                                        &iphc_repr.dst_addr.into_address(),
+                                        &ChecksumCapabilities::default(),
+                                    ) {
+                                        let mut buffer = vec![0; repr.buffer_len()];
+                                        let mut frame = TcpPacket::new_unchecked(&mut buffer[..]);
+                                        repr.emit(
+                                            &mut frame,
+                                            &iphc_repr.src_addr.into_address(),
+                                            &iphc_repr.dst_addr.into_address(),
+                                            &ChecksumCapabilities::default(),
+                                        );
+                                    }
+                                }
+                            }
+                            IpProtocol::Udp => {
+                                if let Ok(frame) = UdpPacket::new_checked(payload) {
+                                    if let Ok(repr) = UdpRepr::parse(
+                                        &frame,
+                                        &iphc_repr.src_addr.into_address(),
+                                        &iphc_repr.dst_addr.into_address(),
+                                        &ChecksumCapabilities::default(),
+                                    ) {
+                                        let mut buffer =
+                                            vec![0; repr.header_len() + frame.payload().len()];
+                                        let mut packet = UdpPacket::new_unchecked(&mut buffer[..]);
+                                        repr.emit(
+                                            &mut packet,
+                                            &iphc_repr.src_addr.into_address(),
+                                            &iphc_repr.dst_addr.into_address(),
+                                            frame.payload().len(),
+                                            |b| b.copy_from_slice(frame.payload()),
+                                            &ChecksumCapabilities::default(),
+                                        );
+                                    }
+                                }
+                            }
+                            IpProtocol::Ipv6Route => {
+                                if let Ok(frame) = Ipv6RoutingHeader::new_checked(payload) {
+                                    if let Ok(repr) = Ipv6RoutingRepr::parse(&frame) {
+                                        let mut buffer = vec![0; repr.buffer_len()];
+                                        let mut packet = Ipv6RoutingHeader::new(&mut buffer[..]);
+                                        repr.emit(&mut packet);
+                                    }
+                                }
+                            }
+                            IpProtocol::Ipv6Frag => {
+                                if let Ok(frame) = Ipv6FragmentHeader::new_checked(payload) {
+                                    if let Ok(repr) = Ipv6FragmentRepr::parse(&frame) {
+                                        let mut buffer = vec![0; repr.buffer_len()];
+                                        let mut frame =
+                                            Ipv6FragmentHeader::new_unchecked(&mut buffer[..]);
+                                        repr.emit(&mut frame);
+                                    }
+                                }
+                            }
+                            IpProtocol::Icmpv6 => {
+                                if let Ok(packet) = Icmpv6Packet::new_checked(payload) {
+                                    if let Ok(repr) = Icmpv6Repr::parse(
+                                        &iphc_repr.src_addr.into_address(),
+                                        &iphc_repr.dst_addr.into_address(),
+                                        &packet,
+                                        &ChecksumCapabilities::default(),
+                                    ) {
+                                        let mut buffer = vec![0; repr.buffer_len()];
+                                        let mut packet =
+                                            Icmpv6Packet::new_unchecked(&mut buffer[..]);
+                                        repr.emit(
+                                            &iphc_repr.src_addr.into_address(),
+                                            &iphc_repr.dst_addr.into_address(),
+                                            &mut packet,
+                                            &ChecksumCapabilities::default(),
+                                        );
+                                    }
+                                }
+                            }
+                            IpProtocol::Ipv6NoNxt => (),
+                            IpProtocol::Ipv6Opts => {
+                                if let Ok(packet) = Ipv6Option::new_checked(payload) {
+                                    if let Ok(repr) = Ipv6OptionRepr::parse(&packet) {
+                                        let mut buffer = vec![0; repr.buffer_len()];
+                                        let mut packet = Ipv6Option::new_unchecked(&mut buffer[..]);
+                                        repr.emit(&mut packet);
+                                    }
+                                }
+                            }
+                            IpProtocol::Unknown(_) => (),
+                        },
+                    };
+
+                    let mut buffer = vec![0; iphc_repr.buffer_len()];
+
+                    let mut frame = SixlowpanIphcPacket::new_unchecked(&mut buffer[..]);
+                    iphc_repr.emit(&mut frame);
+                }
+            };
+        }
+        Err(_) => (),
+    }
+});

+ 0 - 41
fuzz/fuzz_targets/sixlowpan_udp_header.rs

@@ -1,41 +0,0 @@
-#![no_main]
-use libfuzzer_sys::fuzz_target;
-use smoltcp::wire::{Ipv6Address, SixlowpanUdpNhcPacket, SixlowpanUdpNhcRepr};
-
-#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, arbitrary::Arbitrary)]
-pub struct AddressFuzzer(pub [u8; 16]);
-
-impl From<AddressFuzzer> for Ipv6Address {
-    fn from(val: AddressFuzzer) -> Self {
-        Ipv6Address(val.0)
-    }
-}
-
-#[derive(Debug, arbitrary::Arbitrary)]
-struct SixlowpanUdpPacketFuzzer<'a> {
-    data: &'a [u8],
-    src_addr: AddressFuzzer,
-    dst_addr: AddressFuzzer,
-}
-
-fuzz_target!(|fuzz: SixlowpanUdpPacketFuzzer| {
-    if let Ok(ref frame) = SixlowpanUdpNhcPacket::new_checked(fuzz.data) {
-        if let Ok(repr) = SixlowpanUdpNhcRepr::parse(
-            frame,
-            &fuzz.src_addr.into(),
-            &fuzz.dst_addr.into(),
-        ) {
-            let payload = frame.payload();
-            let mut buffer = vec![0; repr.header_len() + payload.len()];
-
-            let mut frame = SixlowpanUdpNhcPacket::new_unchecked(&mut buffer[..]);
-            repr.emit(
-                &mut frame,
-                &fuzz.src_addr.into(),
-                &fuzz.dst_addr.into(),
-                payload.len(),
-                |b| b.copy_from_slice(payload),
-            );
-        }
-    };
-});