Merge #562
562: fuzz: DHCP header parser r=Dirbaio a=alexandrasandulescu Hi. This fuzz target tests the [DHCPRepr](https://docs.rs/smoltcp/0.7.5/smoltcp/wire/struct.DhcpRepr.html) `parse` and `emit` functions ([context](https://github.com/smoltcp-rs/smoltcp/issues/305#issuecomment-530327153)). The fuzz target requires a small change in the `DHCPOption` parser because the option type `OPT_DOMAIN_NAME_SERVER ` requires the payload representing the DNS server list to have a length multiple of 4. Otherwise the `chunks` call places the remainder in the last chunk (length < 4). This panics when the last chunk is parsed into an `IPv4Address`. Do you have a better suggestion for handling this situation? I ran the fuzzer for a couple of days but it didn't find any crash yet. To increase the chances, I used the oss-fuzz seed corpora of `dnsmasq` DHCP fuzzer and `systemd` DHCP server fuzzer. Please share if you have suggestions on how to improve coverage. Co-authored-by: Alexandra Sandulescu <aesa@google.com>master
commit
9d0372454a
|
@ -28,3 +28,9 @@ name = "tcp_headers"
|
|||
path = "fuzz_targets/tcp_headers.rs"
|
||||
test = false
|
||||
doc = false
|
||||
|
||||
[[bin]]
|
||||
name = "dhcp_header"
|
||||
path = "fuzz_targets/dhcp_header.rs"
|
||||
test = false
|
||||
doc = false
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
#![no_main]
|
||||
use libfuzzer_sys::fuzz_target;
|
||||
use smoltcp::wire::{DhcpPacket, DhcpRepr};
|
||||
|
||||
fuzz_target!(|data: &[u8]| {
|
||||
let _ = match DhcpPacket::new_checked(data) {
|
||||
Ok(ref packet) => match DhcpRepr::parse(packet) {
|
||||
Ok(dhcp_repr) => {
|
||||
let mut dhcp_payload = vec![0; dhcp_repr.buffer_len()];
|
||||
match DhcpPacket::new_checked(&mut dhcp_payload[..]) {
|
||||
Ok(mut dhcp_packet) => Some(dhcp_repr.emit(&mut dhcp_packet)),
|
||||
Err(_) => None,
|
||||
}
|
||||
}
|
||||
Err(_) => None,
|
||||
},
|
||||
Err(_) => None,
|
||||
};
|
||||
});
|
|
@ -824,7 +824,11 @@ impl<'a> Repr<'a> {
|
|||
data,
|
||||
} => {
|
||||
let mut servers = [None; MAX_DNS_SERVER_COUNT];
|
||||
for (server, chunk) in servers.iter_mut().zip(data.chunks(4)) {
|
||||
let chunk_size = 4;
|
||||
for (server, chunk) in servers.iter_mut().zip(data.chunks(chunk_size)) {
|
||||
if chunk.len() != chunk_size {
|
||||
return Err(Error::Malformed);
|
||||
}
|
||||
*server = Some(Ipv4Address::from_bytes(chunk));
|
||||
}
|
||||
dns_servers = Some(servers);
|
||||
|
|
Loading…
Reference in New Issue