From 017c50d3674e47489392523ef3655ca5b35c1622 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sun, 11 Feb 2024 20:43:30 +0000 Subject: [PATCH] Add fuzzing of DNS server response parsing --- fuzz/Cargo.toml | 46 ++++++++++++ fuzz/src/parse_response.rs | 68 ++++++++++++++++++ ...CODE.-6.ADDR.0.INSTR.mov____%eax,%ebp.fuzz | Bin 0 -> 292 bytes ...CODE.-6.ADDR.0.INSTR.mov____%eax,%ebp.fuzz | Bin 0 -> 32 bytes ...CODE.-6.ADDR.0.INSTR.mov____%eax,%ebp.fuzz | Bin 0 -> 132 bytes ...1.ADDR.7fffff7feff8.INSTR.push___%rbx.fuzz | Bin 0 -> 292 bytes src/query.rs | 7 ++ 7 files changed, 121 insertions(+) create mode 100644 fuzz/Cargo.toml create mode 100644 fuzz/src/parse_response.rs create mode 100644 fuzz/test_cases/parse_response/SIGABRT.PC.7ffff7e42d3c.STACK.1b2d5a02ed.CODE.-6.ADDR.0.INSTR.mov____%eax,%ebp.fuzz create mode 100644 fuzz/test_cases/parse_response/SIGABRT.PC.7ffff7e42d3c.STACK.c7bb77f34.CODE.-6.ADDR.0.INSTR.mov____%eax,%ebp.fuzz create mode 100644 fuzz/test_cases/parse_response/SIGABRT.PC.7ffff7e42d3c.STACK.cbd61ac64.CODE.-6.ADDR.0.INSTR.mov____%eax,%ebp.fuzz create mode 100644 fuzz/test_cases/parse_response/SIGSEGV.PC.5555555998f9.STACK.1a75cee75b.CODE.1.ADDR.7fffff7feff8.INSTR.push___%rbx.fuzz diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml new file mode 100644 index 0000000..c613c87 --- /dev/null +++ b/fuzz/Cargo.toml @@ -0,0 +1,46 @@ +[package] +name = "fuzz" +version = "0.0.1" +authors = ["Automatically generated"] +publish = false +edition = "2021" +# Because the function is unused it gets dropped before we link lightning, so +# we have to duplicate build.rs here. Note that this is only required for +# fuzzing mode. + +[package.metadata] +cargo-fuzz = true + +[features] +afl_fuzz = ["afl"] +honggfuzz_fuzz = ["honggfuzz"] +libfuzzer_fuzz = ["libfuzzer-sys"] +stdin_fuzz = [] + +[dependencies] +dnssec-prover = { path = "../", features = ["validation", "std", "build_server"] } + +afl = { version = "0.12", optional = true } +honggfuzz = { version = "0.5", optional = true, default-features = false } +libfuzzer-sys = { version = "0.4", optional = true } + +[build-dependencies] +cc = "1.0" + +# Prevent this from interfering with workspaces +[workspace] +members = ["."] + +[profile.release] +lto = true +codegen-units = 1 +debug-assertions = true +overflow-checks = true + +# When testing a large fuzz corpus, -O1 offers a nice speedup +[profile.dev] +opt-level = 1 + +[[bin]] +name = "parse_response" +path = "src/parse_response.rs" diff --git a/fuzz/src/parse_response.rs b/fuzz/src/parse_response.rs new file mode 100644 index 0000000..b958776 --- /dev/null +++ b/fuzz/src/parse_response.rs @@ -0,0 +1,68 @@ +// This file is Copyright its original authors, visible in version control +// history. +// +// This file is licensed under the Apache License, Version 2.0 or the MIT license +// , at your option. +// You may not use this file except in accordance with one or both of these +// licenses. + +#![cfg_attr(feature = "libfuzzer_fuzz", no_main)] + +#[cfg(not(fuzzing))] +compile_error!("Fuzz targets need cfg=fuzzing"); + +extern crate dnssec_prover; +use dnssec_prover::query::fuzz_response; + +#[cfg(feature = "afl")] +#[macro_use] extern crate afl; +#[cfg(feature = "afl")] +fn main() { + fuzz!(|data| { + fuzz_response(data); + }); +} + +#[cfg(feature = "honggfuzz")] +#[macro_use] extern crate honggfuzz; +#[cfg(feature = "honggfuzz")] +fn main() { + loop { + fuzz!(|data| { + fuzz_response(data); + }); + } +} + +#[cfg(feature = "libfuzzer_fuzz")] +#[macro_use] extern crate libfuzzer_sys; +#[cfg(feature = "libfuzzer_fuzz")] +fuzz_target!(|data: &[u8]| { + fuzz_response(data); +}); + +#[cfg(feature = "stdin_fuzz")] +fn main() { + use std::io::Read; + + let mut data = Vec::with_capacity(8192); + std::io::stdin().read_to_end(&mut data).unwrap(); + fuzz_response(&data); +} + +#[test] +fn run_test_cases() { + use std::fs; + use std::io::Read; + + if let Ok(tests) = fs::read_dir("test_cases/parse_response") { + for test in tests { + let mut data: Vec = Vec::new(); + let path = test.unwrap().path(); + fs::File::open(&path).unwrap().read_to_end(&mut data).unwrap(); + + fuzz_response(&data); + } + } +} diff --git a/fuzz/test_cases/parse_response/SIGABRT.PC.7ffff7e42d3c.STACK.1b2d5a02ed.CODE.-6.ADDR.0.INSTR.mov____%eax,%ebp.fuzz b/fuzz/test_cases/parse_response/SIGABRT.PC.7ffff7e42d3c.STACK.1b2d5a02ed.CODE.-6.ADDR.0.INSTR.mov____%eax,%ebp.fuzz new file mode 100644 index 0000000000000000000000000000000000000000..ba42741da3af5214926e3a8dd6998f9cf122e85b GIT binary patch literal 292 zcmZ>AYIwlFc;Ns41H%b0FdWb|c^<0l&5H~eAbAYIwlF$WY7?#{dHYKt2Nl2ZRd%PFVuj literal 0 HcmV?d00001 diff --git a/fuzz/test_cases/parse_response/SIGABRT.PC.7ffff7e42d3c.STACK.cbd61ac64.CODE.-6.ADDR.0.INSTR.mov____%eax,%ebp.fuzz b/fuzz/test_cases/parse_response/SIGABRT.PC.7ffff7e42d3c.STACK.cbd61ac64.CODE.-6.ADDR.0.INSTR.mov____%eax,%ebp.fuzz new file mode 100644 index 0000000000000000000000000000000000000000..6ab92b63320ec54cb3a15a5d3da8a794c44a9bb2 GIT binary patch literal 132 zcmZ>AYIwlF$WY7?#{dHYKt2Nl2ZZ|{CW@e$K+FTWCeK5ay?HUfCYXq$8CW3$1C(N5 Y;Ix}N&wFKx_y)JvZ2zI4?~@q=0KYC5sQ>@~ literal 0 HcmV?d00001 diff --git a/fuzz/test_cases/parse_response/SIGSEGV.PC.5555555998f9.STACK.1a75cee75b.CODE.1.ADDR.7fffff7feff8.INSTR.push___%rbx.fuzz b/fuzz/test_cases/parse_response/SIGSEGV.PC.5555555998f9.STACK.1a75cee75b.CODE.1.ADDR.7fffff7feff8.INSTR.push___%rbx.fuzz new file mode 100644 index 0000000000000000000000000000000000000000..ba42741da3af5214926e3a8dd6998f9cf122e85b GIT binary patch literal 292 zcmZ>AYIwlFc;Ns41H%b0FdWb|c^<0l&5H~eAb, rrsig_key_names: &mut Vec) -> Result { let mut read: &[u8] = resp; if emap(read_u16(&mut read))? != TXID { return Err(Error::new(ErrorKind::Other, "bad txid")); } -- 2.30.2