Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add wasmi fuzzing and comment some outdated targets for fuzzing wasm #3

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ sudo apt install -y build-essential libtool-bin python3 cmake automake bison lib
cargo +nightly install --force afl
```

You're good to go now, build warf with `make build` ;)
You're good to go now, build warf with `cd ./warf && make build` ;)
2 changes: 1 addition & 1 deletion docs/INTEGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ WebAssembly implementation from scratch in Safe Rust with zero dependencies - [g

## wasm3 (C++/Rust)

- [wasm3](https://github.com/wasm3/wasm3) - high performance WebAssembly interpreter written in C. - [rust bindings](https://github.com/Veykril/wasm3-rs)
- [wasm3](https://github.com/wasm3/wasm3) - high performance WebAssembly interpreter written in C. - [rust bindings](https://github.com/raekfo/wasm3-rs)

<details><summary>Details</summary>
<p>
Expand Down
59 changes: 51 additions & 8 deletions warf/src/rust_fuzzers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,25 +33,32 @@ impl FuzzerHfuzz {
/// Check if `cargo hfuzz` is installed
pub fn is_available() -> Result<(), Error> {
let fuzzer_output = Command::new("cargo").arg("hfuzz").arg("version").output()?;
if !fuzzer_output.status.success() {
if fuzzer_output.status.code().unwrap() != 0 {
eprintln!("Command failed with status: {}", fuzzer_output.status);
eprintln!("stderr: {}", String::from_utf8_lossy(&fuzzer_output.stderr));
bail!("hfuzz not available, install with `cargo install honggfuzz`");
}

let stdout = String::from_utf8_lossy(&fuzzer_output.stdout);
println!("stdout: {}", stdout);

Ok(())
}

/// Create a new FuzzerHfuzz
pub fn new(config: FuzzerConfig) -> Result<FuzzerHfuzz, Error> {
// Test if fuzzer engine installed
FuzzerHfuzz::is_available()?;

let cwd = env::current_dir().context("error getting current directory")?;

let fuzzer = FuzzerHfuzz {
name: "Honggfuzz".to_string(),
dir: cwd.join("fuzzers").join("rust-honggfuzz"),
work_dir: cwd.join("workspace").join("hfuzz"),
workspace_dir: cwd.join("workspace").join("hfuzz").join("hfuzz_workspace"),
config,
};

Ok(fuzzer)
}

Expand Down Expand Up @@ -137,13 +144,49 @@ impl FuzzerHfuzz {
);

// Honggfuzz will first build than run the fuzzer using cargo
let fuzzer_bin = Command::new("cargo") // ,
.args(&["+nightly", "hfuzz", "run", &target.name()])
.env("RUSTFLAGS", &rust_args)
.env("HFUZZ_RUN_ARGS", &hfuzz_args)
//.env("HFUZZ_BUILD_ARGS", "opt-level=3")

// Check rustup which and another command

// Créer la commande
let mut command_check = Command::new("whoami");


// Afficher les détails de la commande


// Optionnel: Spécifiez le répertoire de travail si nécessaire
// command_check.current_dir("/path/to/dir");

// Exécuter la commande et obtenir la sortie
let output = command_check
.output()
.context("error executing the command")?;

// Afficher les détails de l'exécution


// Vérifier le statut de la commande

eprintln!("Command failed with status: {}", output.status);
eprintln!("stderr: {}", String::from_utf8_lossy(&output.stderr));
// La commande a réussi, afficher la sortie
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));

// ==================================================

let mut command = Command::new("rustup");
command
.args(&["run", "nightly", "cargo", "hfuzz", "run", &target.name()])
.env("RUST_BACKTRACE", "full")
.env("RUSTFLAGS", rust_args)
.env("HFUZZ_RUN_ARGS", hfuzz_args)
.env("HFUZZ_INPUT", corpora_dir)
.current_dir(&self.work_dir)
.current_dir(&self.work_dir);



// Exécuter la commande
let fuzzer_bin = command
.spawn()
.context(format!(
"error starting {} to run {}",
Expand Down
15 changes: 15 additions & 0 deletions warf/src/targets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ pub enum Targets {
// wasmi
WasmiValidate,
WasmiInstantiate,
WasmiTranslate,
WasmiTranslateMetered,
WasmiExecute,
// parity_wasm
ParityWasmDeserialize,
// wasmer
Expand Down Expand Up @@ -59,6 +62,9 @@ impl Targets {
// wasmi
Targets::WasmiValidate => "wasmi_validate",
Targets::WasmiInstantiate => "wasmi_instantiate",
Targets::WasmiTranslate => "wasmi_translate",
Targets::WasmiTranslateMetered => "wasmi_translate_metered",
Targets::WasmiExecute => "wasmi_execute",
// parity_wasm
Targets::ParityWasmDeserialize => "parity_wasm_deserialize",
// wasmer
Expand Down Expand Up @@ -110,6 +116,9 @@ impl Targets {
// wasmi
Targets::WasmiValidate
| Targets::WasmiInstantiate
| Targets::WasmiTranslate
| Targets::WasmiTranslateMetered
| Targets::WasmiExecute
// parity_wasm
| Targets::ParityWasmDeserialize
// wasmer
Expand Down Expand Up @@ -161,6 +170,9 @@ impl Targets {
// wasmi
Targets::WasmiValidate
| Targets::WasmiInstantiate
| Targets::WasmiTranslate
| Targets::WasmiTranslateMetered
| Targets::WasmiExecute
// parity_wasm
| Targets::ParityWasmDeserialize
// wasmer
Expand Down Expand Up @@ -212,6 +224,9 @@ impl Targets {
// wasmi
Targets::WasmiValidate
| Targets::WasmiInstantiate
| Targets::WasmiTranslate
| Targets::WasmiTranslateMetered
| Targets::WasmiExecute
// parity_wasm
| Targets::ParityWasmDeserialize
// wasmer
Expand Down
15 changes: 9 additions & 6 deletions warf/targets/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@ authors = ["Patrick Ventuzelo <[email protected]>"]
edition = "2018"

[dependencies]
wasmi = "*"
wasmi-validation = "*"
wasmi = { git = "https://github.com/wasmi-labs/wasmi" }
parity-wasm = "0.41.0"
wasmer-runtime = "*"
wasmer-singlepass-backend = "*"
#wasmer = "*"
#wasmer-singlepass-backend = "*"
wasmtime = "*"
# lightbeam = "*"
lightbeam = "*"
wasmparser = "*"
binaryen = "*"
wabt = "*"
Expand All @@ -20,5 +19,9 @@ wain-validate = "*"
wain-syntax-binary = "*"
wat = "*"
wast = "*"
wasm3 = { git = "https://github.com/Veykril/wasm3-rs", features=["build-bindgen"]}
#wasm3 = { git = "https://github.com/raekfo/wasm3-rs", features=["build-bindgen"]}
fizzy = "0.6.0-dev"
wasm-smith = "=0.13.1"
arbitrary = { version = "=1.3.2", features = ["derive"] }
wasmi-stack = { package = "wasmi", version = "0.31.2" }

19 changes: 19 additions & 0 deletions warf/targets/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ We are checking that all those different implementation return
the same thing i.e. true or false in our cases.
*/

mod utils;

pub fn fuzz_diff_parsing(data: &[u8]) {
let a = parity_wasm::parity_wasm_deserialize(&data);
let b = wasmer::fuzz_wasmer_compile_clif(&data);
Expand Down Expand Up @@ -122,6 +124,23 @@ pub fn fuzz_wasmi_validate(data: &[u8]) {
pub fn fuzz_wasmi_instantiate(data: &[u8]) {
let _ = wasmi::wasmi_instantiate(&data);
}

pub fn fuzz_wasmi_translate(data: &[u8]) {
let _ = wasmi::wasmi_translate(&data);
}

pub fn fuzz_wasmi_translate_metered(data: &[u8]) {
let _ = wasmi::wasmi_translate_metered(&data);
}


pub fn fuzz_wasmi_execute(data: &[u8]) {
let _ = wasmi::wasmi_execute(&data);
}




// debug target
pub fn debug_wasmi_validate(data: &[u8]) -> bool {
wasmi::wasmi_validate(&data)
Expand Down
79 changes: 79 additions & 0 deletions warf/targets/src/utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use arbitrary::Arbitrary;
use wasmi::{core::ValType, Val};

/// The configuration used to produce Wasmi compatible fuzzing Wasm modules.
#[derive(Debug, Arbitrary)]
pub struct ExecConfig;

impl wasm_smith::Config for ExecConfig {
fn export_everything(&self) -> bool {
true
}
fn allow_start_export(&self) -> bool {
false
}
fn reference_types_enabled(&self) -> bool {
false
}
fn max_imports(&self) -> usize {
0
}
fn max_memory_pages(&self, is_64: bool) -> u64 {
match is_64 {
true => {
// Note: wasmi does not support 64-bit memory, yet.
0
}
false => 1_000,
}
}
fn max_data_segments(&self) -> usize {
10_000
}
fn max_element_segments(&self) -> usize {
10_000
}
fn max_exports(&self) -> usize {
10_000
}
fn max_elements(&self) -> usize {
10_000
}
fn min_funcs(&self) -> usize {
1
}
fn max_funcs(&self) -> usize {
10_000
}
fn max_globals(&self) -> usize {
10_000
}
fn max_table_elements(&self) -> u32 {
10_000
}
fn max_values(&self) -> usize {
10_000
}
fn max_instructions(&self) -> usize {
100_000
}
}

/// Converts a [`ValType`] into a [`Val`] with default initialization of 1.
///
/// # ToDo
///
/// We actually want the bytes buffer given by the `Arbitrary` crate to influence
/// the values chosen for the resulting [`Val`]. Also we ideally want to produce
/// zeroed, positive, negative and NaN values for their respective types.
pub fn ty_to_val(ty: &ValType) -> Val {
match ty {
ValType::I32 => Val::I32(1),
ValType::I64 => Val::I64(1),
ValType::F32 => Val::F32(1.0.into()),
ValType::F64 => Val::F64(1.0.into()),
unsupported => panic!(
"execution fuzzing does not support reference types, yet but found: {unsupported:?}"
),
}
}
8 changes: 5 additions & 3 deletions warf/targets/src/wasm3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ wasm3 (Rust binding using FFI)
- https://github.com/Veykril/wasm3-rs
************************************************/

use wasm3::Environment;
use wasm3::Module;

pub fn fuzz_wasm3_parser_ffi(data: &[u8]) -> bool {
/*

let env = Environment::new().expect("Unable to create environment");
let _rt = env
.create_runtime(1024 * 60)
.expect("Unable to create runtime");
Module::parse(&env, &data).is_ok()
*/

true
}
20 changes: 18 additions & 2 deletions warf/targets/src/wasmer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,50 @@ WASMER:

/// Fuzzing `wasmer::validate`
pub fn fuzz_wasmer_validate(data: &[u8]) -> bool {
/*
extern crate wasmer_runtime;
wasmer_runtime::validate(&data)
*/
true
}

/// Fuzzing wasmer::compile with Cranelift compiler backend
pub fn fuzz_wasmer_compile_clif(data: &[u8]) -> bool {
use wasmer_runtime::compile;
compile(&data).is_ok()
/*

use wasmer_runtime::compile;
compile(&data).is_ok()
*/
true
}

/// Fuzzing `wasmer::compile` with `SinglePass` compiler backend
pub fn fuzz_wasmer_compile_singlepass(data: &[u8]) -> bool {
/*
use wasmer_runtime::compile_with;
use wasmer_singlepass_backend::SinglePassCompiler;
compile_with(&data, &SinglePassCompiler::new()).is_ok()
*/
true
}

/// Fuzzing `wasmer::instantiate` with empty import_object
pub fn fuzz_wasmer_instantiate(data: &[u8]) -> bool {
/*
use wasmer_runtime::{imports, instantiate};
let import_object = imports! {};
*/
// allow_missing_functions should prevent wasmer to reject
// modules with imported functions but generate more false positive bugs
// import_object.allow_missing_functions = true;

/*
instantiate(&data, &import_object).is_ok()
*/

// TODO(RM3): improve or create new fuzz harness that iterate
// over module functions and call them all
true
}

/*
Expand Down
Loading
Loading