Skip to content
This repository has been archived by the owner on Sep 4, 2024. It is now read-only.

Commit

Permalink
add fuzzing harness for simple_http
Browse files Browse the repository at this point in the history
  • Loading branch information
apoelstra committed Nov 19, 2022
1 parent f44a535 commit 8d2ec83
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
target
Cargo.lock

fuzz/hfuzz_workspace/
fuzz/hfuzz_target/
4 changes: 4 additions & 0 deletions fuzz/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

target
corpus
artifacts
24 changes: 24 additions & 0 deletions fuzz/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[package]
name = "jsonrpc-fuzz"
version = "0.0.1"
authors = ["Automatically generated"]
publish = false

[package.metadata]
cargo-fuzz = true

[features]
honggfuzz_fuzz = ["honggfuzz"]

[dependencies]
honggfuzz = { version = "0.5", optional = true, default-features = false }
jsonrpc = { path = ".." }

# Prevent this from interfering with workspaces
[workspace]
members = ["."]

[[bin]]
name = "simple_http"
path = "fuzz_targets/simple_http.rs"

60 changes: 60 additions & 0 deletions fuzz/fuzz_targets/simple_http.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@

extern crate jsonrpc;

#[cfg(not(fuzzing))]
compile_error!("You must set RUSTFLAGS=--cfg=fuzzing to run these test, or run the actual fuzz harness.");

use jsonrpc::Client;
use jsonrpc::simple_http::SimpleHttpTransport;
use jsonrpc::simple_http::FUZZ_TCP_SOCK;

use std::io;

fn do_test(data: &[u8]) {
*FUZZ_TCP_SOCK.lock().unwrap() = Some(io::Cursor::new(data.to_vec()));

let t = SimpleHttpTransport::builder()
.url("localhost:123").expect("parse url")
.auth("", None)
.build();

let client = Client::with_transport(t);
let request = client.build_request("uptime", &[]);
let _ = client.send_request(request);
}

#[cfg(feature = "honggfuzz")]
fn main() {
loop {
honggfuzz::fuzz!(|data| {
do_test(data);
});
}
}

#[cfg(test)]
mod tests {
fn extend_vec_from_hex(hex: &str) -> Vec<u8> {
let mut out = vec![];
let mut b = 0;
for (idx, c) in hex.as_bytes().iter().enumerate() {
b <<= 4;
match *c {
b'A'..=b'F' => b |= c - b'A' + 10,
b'a'..=b'f' => b |= c - b'a' + 10,
b'0'..=b'9' => b |= c - b'0',
_ => panic!("Bad hex"),
}
if (idx & 1) == 1 {
out.push(b);
b = 0;
}
}
out
}

#[test]
fn duplicate_crash() {
super::do_test(&extend_vec_from_hex("00"));
}
}
40 changes: 40 additions & 0 deletions fuzz/travis-fuzz.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/bin/bash
set -e

# Check that input files are correct Windows file names
incorrectFilenames=$(find . -type f -name "*,*" -o -name "*:*" -o -name "*<*" -o -name "*>*" -o -name "*|*" -o -name "*\?*" -o -name "*\**" -o -name "*\"*" | wc -l)

if [ ${incorrectFilenames} -gt 0 ]; then
echo 'Exiting early due to Windows-incompatible filenames in this tree. If this is happening'
echo 'to you on a local run, deleting the `hfuzz_workspace/` directory will probably fix it.'
exit 2
fi

if [ "$1" == "" ]; then
TARGETS=fuzz_targets/*
else
TARGETS=fuzz_targets/"$1".rs
fi

cargo --version
rustc --version

# Testing
cargo install --force honggfuzz --no-default-features
for TARGET in $TARGETS; do
echo "Fuzzing target $TARGET"
FILENAME=$(basename $TARGET)
FILE="${FILENAME%.*}"
if [ -d hfuzz_input/$FILE ]; then
HFUZZ_INPUT_ARGS="-f hfuzz_input/$FILE/input"
fi
HFUZZ_BUILD_ARGS="--features honggfuzz_fuzz" HFUZZ_RUN_ARGS="--run_time 30 --exit_upon_crash -v $HFUZZ_INPUT_ARGS" cargo hfuzz run $FILE

if [ -f hfuzz_workspace/$FILE/HONGGFUZZ.REPORT.TXT ]; then
cat hfuzz_workspace/$FILE/HONGGFUZZ.REPORT.TXT
for CASE in hfuzz_workspace/$FILE/SIG*; do
cat $CASE | xxd -p -c1000
done
exit 1
fi
done
3 changes: 3 additions & 0 deletions src/simple_http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ impl Default for SimpleHttpTransport {
DEFAULT_PORT,
),
path: "/".to_owned(),
#[cfg(fuzzing)]
timeout: Duration::from_millis(1),
#[cfg(not(fuzzing))]
timeout: Duration::from_secs(15),
basic_auth: None,
#[cfg(feature = "proxy")]
Expand Down

0 comments on commit 8d2ec83

Please sign in to comment.