mirror of
https://github.com/ZeusWPI/ZNS.git
synced 2024-10-29 21:14:27 +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.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
|
@ -66,6 +66,15 @@ dependencies = [
|
|||
"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]]
|
||||
name = "asn1"
|
||||
version = "0.16.2"
|
||||
|
@ -149,6 +158,8 @@ version = "1.1.13"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72db2f7947ecee9b03b510377e8bb9077afa27176fdbff55c51027e976fdcc48"
|
||||
dependencies = [
|
||||
"jobserver",
|
||||
"libc",
|
||||
"shlex",
|
||||
]
|
||||
|
||||
|
@ -255,6 +266,17 @@ dependencies = [
|
|||
"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]]
|
||||
name = "diesel"
|
||||
version = "2.2.2"
|
||||
|
@ -640,6 +662,15 @@ version = "1.0.11"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
||||
|
||||
[[package]]
|
||||
name = "jobserver"
|
||||
version = "0.1.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.70"
|
||||
|
@ -655,6 +686,17 @@ version = "0.2.158"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.14"
|
||||
|
@ -1614,6 +1656,7 @@ checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
|
|||
name = "zns"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
"base64",
|
||||
"int-enum",
|
||||
"thiserror",
|
||||
|
@ -1645,3 +1688,11 @@ dependencies = [
|
|||
"tokio",
|
||||
"zns",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zns-fuzz"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"libfuzzer-sys",
|
||||
"zns",
|
||||
]
|
||||
|
|
|
@ -5,4 +5,5 @@ members = [
|
|||
"zns",
|
||||
"zns-cli",
|
||||
"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"
|
||||
int-enum = "1.1"
|
||||
thiserror = "1.0"
|
||||
arbitrary = { version = "^1.3.2", optional = true, features = ["derive"] }
|
||||
|
||||
[dev-dependencies]
|
||||
zns = { path = ".", features = ["test-utils"] }
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use std::fmt::Display;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||
pub struct LabelString(Vec<String>);
|
||||
|
||||
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> {
|
||||
if position >= self.position - 2 {
|
||||
if self.position < 2 || position >= self.position - 2 {
|
||||
Err(ZNSError::Reader {
|
||||
message: String::from("Seeking into the future is not allowed!!"),
|
||||
})
|
||||
} else {
|
||||
let mut reader = Reader::new(&self.buffer[..self.position]);
|
||||
let mut reader = Reader::new(&self.buffer[..self.position - 1]);
|
||||
reader.position = position;
|
||||
Ok(reader)
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ mod tests {
|
|||
|
||||
let new_reader = reader.seek(1);
|
||||
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);
|
||||
assert!(new_reader.is_err());
|
||||
|
|
|
@ -3,6 +3,7 @@ use int_enum::IntEnum;
|
|||
use crate::labelstring::LabelString;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||
pub enum Type {
|
||||
Type(RRType),
|
||||
Other(u16),
|
||||
|
@ -10,6 +11,7 @@ pub enum Type {
|
|||
|
||||
#[repr(u16)]
|
||||
#[derive(Debug, Clone, PartialEq, IntEnum)]
|
||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||
pub enum RRType {
|
||||
A = 1,
|
||||
SOA = 6,
|
||||
|
@ -20,6 +22,7 @@ pub enum RRType {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||
pub enum Class {
|
||||
Class(RRClass),
|
||||
Other(u16),
|
||||
|
@ -27,6 +30,7 @@ pub enum Class {
|
|||
|
||||
#[repr(u16)]
|
||||
#[derive(Debug, Clone, PartialEq, IntEnum)]
|
||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||
pub enum RRClass {
|
||||
IN = 1,
|
||||
NONE = 254,
|
||||
|
@ -56,6 +60,7 @@ pub enum Opcode {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||
pub struct Question {
|
||||
pub qname: LabelString,
|
||||
pub qtype: Type, // NOTE: should be QTYPE, right now not really needed
|
||||
|
@ -63,6 +68,7 @@ pub struct Question {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||
pub struct Header {
|
||||
pub id: u16,
|
||||
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)]
|
||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||
pub struct Message {
|
||||
pub header: Header,
|
||||
pub question: Vec<Question>,
|
||||
|
@ -82,6 +89,7 @@ pub struct Message {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||
pub struct RR {
|
||||
pub name: LabelString,
|
||||
pub _type: Type,
|
||||
|
|
Loading…
Reference in a new issue