Update sixlowpan fuzzer

This commit is contained in:
Thibaut Vandervelden 2022-07-01 18:57:56 +02:00
parent 43273265a7
commit 4767aadcb4
4 changed files with 242 additions and 91 deletions

View File

@ -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

View File

@ -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);
}
};
});

View File

@ -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(_) => (),
}
});

View File

@ -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),
);
}
};
});