mirror of
https://github.com/ZeusWPI/ZNS.git
synced 2024-11-21 13:31:11 +01:00
add fuzzer
This commit is contained in:
parent
3779125367
commit
341f79f5ad
12 changed files with 253 additions and 4 deletions
53
Cargo.lock
generated
53
Cargo.lock
generated
|
@ -1,6 +1,6 @@
|
||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 4
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "addr2line"
|
name = "addr2line"
|
||||||
|
@ -66,6 +66,15 @@ dependencies = [
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "arbitrary"
|
||||||
|
version = "1.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110"
|
||||||
|
dependencies = [
|
||||||
|
"derive_arbitrary",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "asn1"
|
name = "asn1"
|
||||||
version = "0.16.2"
|
version = "0.16.2"
|
||||||
|
@ -149,6 +158,8 @@ version = "1.1.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "72db2f7947ecee9b03b510377e8bb9077afa27176fdbff55c51027e976fdcc48"
|
checksum = "72db2f7947ecee9b03b510377e8bb9077afa27176fdbff55c51027e976fdcc48"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"jobserver",
|
||||||
|
"libc",
|
||||||
"shlex",
|
"shlex",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -255,6 +266,17 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "derive_arbitrary"
|
||||||
|
version = "1.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "diesel"
|
name = "diesel"
|
||||||
version = "2.2.2"
|
version = "2.2.2"
|
||||||
|
@ -640,6 +662,15 @@ version = "1.0.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jobserver"
|
||||||
|
version = "0.1.32"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
version = "0.3.70"
|
version = "0.3.70"
|
||||||
|
@ -655,6 +686,17 @@ version = "0.2.158"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
|
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libfuzzer-sys"
|
||||||
|
version = "0.4.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7"
|
||||||
|
dependencies = [
|
||||||
|
"arbitrary",
|
||||||
|
"cc",
|
||||||
|
"once_cell",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linux-raw-sys"
|
name = "linux-raw-sys"
|
||||||
version = "0.4.14"
|
version = "0.4.14"
|
||||||
|
@ -1614,6 +1656,7 @@ checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
|
||||||
name = "zns"
|
name = "zns"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"arbitrary",
|
||||||
"base64",
|
"base64",
|
||||||
"int-enum",
|
"int-enum",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
@ -1645,3 +1688,11 @@ dependencies = [
|
||||||
"tokio",
|
"tokio",
|
||||||
"zns",
|
"zns",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zns-fuzz"
|
||||||
|
version = "0.0.0"
|
||||||
|
dependencies = [
|
||||||
|
"libfuzzer-sys",
|
||||||
|
"zns",
|
||||||
|
]
|
||||||
|
|
|
@ -5,4 +5,5 @@ members = [
|
||||||
"zns",
|
"zns",
|
||||||
"zns-cli",
|
"zns-cli",
|
||||||
"zns-daemon",
|
"zns-daemon",
|
||||||
|
"fuzz"
|
||||||
]
|
]
|
||||||
|
|
4
fuzz/.gitignore
vendored
Normal file
4
fuzz/.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
target
|
||||||
|
corpus
|
||||||
|
artifacts
|
||||||
|
coverage
|
19
fuzz/Cargo.toml
Normal file
19
fuzz/Cargo.toml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
[package]
|
||||||
|
name = "zns-fuzz"
|
||||||
|
version = "0.0.0"
|
||||||
|
publish = false
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[package.metadata]
|
||||||
|
cargo-fuzz = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
libfuzzer-sys = "0.4"
|
||||||
|
zns = {path = "../zns", features = ["arbitrary"]}
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "parser"
|
||||||
|
path = "fuzz_targets/parser.rs"
|
||||||
|
test = false
|
||||||
|
doc = false
|
||||||
|
bench = false
|
42
fuzz/cov.sh
Executable file
42
fuzz/cov.sh
Executable file
|
@ -0,0 +1,42 @@
|
||||||
|
#!/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Check if the correct number of arguments is provided
|
||||||
|
if [ "$#" -ne 2 ]; then
|
||||||
|
echo "Usage: $0 <llvm-cov> <fuzz_target>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Assign the first argument to the fuzz_target variable
|
||||||
|
COMMAND=$1
|
||||||
|
FUZZ_TARGET=$2
|
||||||
|
|
||||||
|
|
||||||
|
if ! command -v $(COMMAND) &> /dev/null; then
|
||||||
|
echo "llvm-cov could not be found, please install LLVM."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! command -v rustfilt &> /dev/null; then
|
||||||
|
echo "rustfilt could not be found, please install rustfilt."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cargo fuzz coverage "$FUZZ_TARGET"
|
||||||
|
|
||||||
|
TARGET_DIR="target/x86_64-unknown-linux-gnu/coverage/x86_64-unknown-linux-gnu/release"
|
||||||
|
PROF_DATA="coverage/$FUZZ_TARGET/coverage.profdata"
|
||||||
|
OUTPUT_FILE="coverage/index.html"
|
||||||
|
|
||||||
|
if [ ! -f "$PROF_DATA" ]; then
|
||||||
|
echo "Coverage data file $PROF_DATA not found."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
$COMMAND show "$TARGET_DIR/$FUZZ_TARGET" --format=html \
|
||||||
|
-Xdemangler=rustfilt \
|
||||||
|
--ignore-filename-regex="\.cargo" \
|
||||||
|
-instr-profile="$PROF_DATA" \
|
||||||
|
> "$OUTPUT_FILE"
|
||||||
|
|
||||||
|
echo "Coverage report generated as $OUTPUT_FILE"
|
82
fuzz/flake.lock
Normal file
82
fuzz/flake.lock
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"flake-utils": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1726560853,
|
||||||
|
"narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1728241625,
|
||||||
|
"narHash": "sha256-yumd4fBc/hi8a9QgA9IT8vlQuLZ2oqhkJXHPKxH/tRw=",
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "c31898adf5a8ed202ce5bea9f347b1c6871f32d1",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nixos",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"nixpkgs": "nixpkgs",
|
||||||
|
"rust-overlay": "rust-overlay"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rust-overlay": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1728354625,
|
||||||
|
"narHash": "sha256-r+Sa1NRRT7LXKzCaVaq75l1GdZcegODtF06uaxVVVbI=",
|
||||||
|
"owner": "oxalica",
|
||||||
|
"repo": "rust-overlay",
|
||||||
|
"rev": "d216ade5a0091ce60076bf1f8bc816433a1fc5da",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "oxalica",
|
||||||
|
"repo": "rust-overlay",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
31
fuzz/flake.nix
Normal file
31
fuzz/flake.nix
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
{
|
||||||
|
description = "flake for fuzzer as it needs nightly";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||||
|
flake-utils.url = "github:numtide/flake-utils";
|
||||||
|
rust-overlay = {
|
||||||
|
url = "github:oxalica/rust-overlay";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
inputs.flake-utils.follows = "flake-utils";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
outputs = {self, nixpkgs, flake-utils, rust-overlay, ... }:
|
||||||
|
flake-utils.lib.eachDefaultSystem (system:
|
||||||
|
let
|
||||||
|
overlays = [ (import rust-overlay) ];
|
||||||
|
pkgs = import nixpkgs {
|
||||||
|
inherit system overlays;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
with pkgs;
|
||||||
|
{
|
||||||
|
devShell = mkShell {
|
||||||
|
buildInputs = [
|
||||||
|
(rust-bin.nightly.latest.default.override { extensions = [ "llvm-tools-preview" ]; })
|
||||||
|
cargo-fuzz
|
||||||
|
rustfilt
|
||||||
|
];
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
9
fuzz/fuzz_targets/parser.rs
Normal file
9
fuzz/fuzz_targets/parser.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
use libfuzzer_sys::fuzz_target;
|
||||||
|
use zns::{parser::FromBytes, reader::Reader, structs::Message};
|
||||||
|
|
||||||
|
fuzz_target!(|data: &[u8]| {
|
||||||
|
let mut reader = Reader::new(data);
|
||||||
|
let _ = Message::from_bytes(&mut reader);
|
||||||
|
});
|
|
@ -11,6 +11,7 @@ test-utils = []
|
||||||
base64 = "0.22.0"
|
base64 = "0.22.0"
|
||||||
int-enum = "1.1"
|
int-enum = "1.1"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
|
arbitrary = { version = "^1.3.2", optional = true, features = ["derive"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
zns = { path = ".", features = ["test-utils"] }
|
zns = { path = ".", features = ["test-utils"] }
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||||
pub struct LabelString(Vec<String>);
|
pub struct LabelString(Vec<String>);
|
||||||
|
|
||||||
pub fn labels_equal(vec1: &LabelString, vec2: &LabelString) -> bool {
|
pub fn labels_equal(vec1: &LabelString, vec2: &LabelString) -> bool {
|
||||||
|
|
|
@ -66,12 +66,12 @@ impl<'a> Reader<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn seek(&self, position: usize) -> Result<Self> {
|
pub fn seek(&self, position: usize) -> Result<Self> {
|
||||||
if position >= self.position - 2 {
|
if self.position < 2 || position >= self.position - 2 {
|
||||||
Err(ZNSError::Reader {
|
Err(ZNSError::Reader {
|
||||||
message: String::from("Seeking into the future is not allowed!!"),
|
message: String::from("Seeking into the future is not allowed!!"),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
let mut reader = Reader::new(&self.buffer[..self.position]);
|
let mut reader = Reader::new(&self.buffer[..self.position - 1]);
|
||||||
reader.position = position;
|
reader.position = position;
|
||||||
Ok(reader)
|
Ok(reader)
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,7 @@ mod tests {
|
||||||
|
|
||||||
let new_reader = reader.seek(1);
|
let new_reader = reader.seek(1);
|
||||||
assert!(new_reader.is_ok());
|
assert!(new_reader.is_ok());
|
||||||
assert_eq!(new_reader.unwrap().unread_bytes(), 10);
|
assert_eq!(new_reader.unwrap().unread_bytes(), 9);
|
||||||
|
|
||||||
let new_reader = reader.seek(100);
|
let new_reader = reader.seek(100);
|
||||||
assert!(new_reader.is_err());
|
assert!(new_reader.is_err());
|
||||||
|
|
|
@ -3,6 +3,7 @@ use int_enum::IntEnum;
|
||||||
use crate::labelstring::LabelString;
|
use crate::labelstring::LabelString;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||||
pub enum Type {
|
pub enum Type {
|
||||||
Type(RRType),
|
Type(RRType),
|
||||||
Other(u16),
|
Other(u16),
|
||||||
|
@ -10,6 +11,7 @@ pub enum Type {
|
||||||
|
|
||||||
#[repr(u16)]
|
#[repr(u16)]
|
||||||
#[derive(Debug, Clone, PartialEq, IntEnum)]
|
#[derive(Debug, Clone, PartialEq, IntEnum)]
|
||||||
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||||
pub enum RRType {
|
pub enum RRType {
|
||||||
A = 1,
|
A = 1,
|
||||||
SOA = 6,
|
SOA = 6,
|
||||||
|
@ -20,6 +22,7 @@ pub enum RRType {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||||
pub enum Class {
|
pub enum Class {
|
||||||
Class(RRClass),
|
Class(RRClass),
|
||||||
Other(u16),
|
Other(u16),
|
||||||
|
@ -27,6 +30,7 @@ pub enum Class {
|
||||||
|
|
||||||
#[repr(u16)]
|
#[repr(u16)]
|
||||||
#[derive(Debug, Clone, PartialEq, IntEnum)]
|
#[derive(Debug, Clone, PartialEq, IntEnum)]
|
||||||
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||||
pub enum RRClass {
|
pub enum RRClass {
|
||||||
IN = 1,
|
IN = 1,
|
||||||
NONE = 254,
|
NONE = 254,
|
||||||
|
@ -56,6 +60,7 @@ pub enum Opcode {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||||
pub struct Question {
|
pub struct Question {
|
||||||
pub qname: LabelString,
|
pub qname: LabelString,
|
||||||
pub qtype: Type, // NOTE: should be QTYPE, right now not really needed
|
pub qtype: Type, // NOTE: should be QTYPE, right now not really needed
|
||||||
|
@ -63,6 +68,7 @@ pub struct Question {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||||
pub struct Header {
|
pub struct Header {
|
||||||
pub id: u16,
|
pub id: u16,
|
||||||
pub flags: u16, // |QR| Opcode |AA|TC|RD|RA| Z | RCODE | ; 1 | 4 | 1 | 1 | 1 | 1 | 3 | 4
|
pub flags: u16, // |QR| Opcode |AA|TC|RD|RA| Z | RCODE | ; 1 | 4 | 1 | 1 | 1 | 1 | 3 | 4
|
||||||
|
@ -73,6 +79,7 @@ pub struct Header {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||||
pub struct Message {
|
pub struct Message {
|
||||||
pub header: Header,
|
pub header: Header,
|
||||||
pub question: Vec<Question>,
|
pub question: Vec<Question>,
|
||||||
|
@ -82,6 +89,7 @@ pub struct Message {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||||
pub struct RR {
|
pub struct RR {
|
||||||
pub name: LabelString,
|
pub name: LabelString,
|
||||||
pub _type: Type,
|
pub _type: Type,
|
||||||
|
|
Loading…
Reference in a new issue