cranelift: CLIF Fuzzer limit instructions executed in interpreter
This commit is contained in:
@@ -7,14 +7,17 @@ use cranelift_filetests::function_runner::{CompiledFunction, SingleFunctionCompi
|
||||
use cranelift_fuzzgen::*;
|
||||
use cranelift_interpreter::environment::FuncIndex;
|
||||
use cranelift_interpreter::environment::FunctionStore;
|
||||
use cranelift_interpreter::interpreter::{Interpreter, InterpreterState};
|
||||
use cranelift_interpreter::interpreter::{Interpreter, InterpreterError, InterpreterState};
|
||||
use cranelift_interpreter::step::ControlFlow;
|
||||
use cranelift_interpreter::step::CraneliftTrap;
|
||||
|
||||
const INTERPRETER_FUEL: u64 = 4096;
|
||||
|
||||
#[derive(Debug)]
|
||||
enum RunResult {
|
||||
Success(Vec<DataValue>),
|
||||
Trap(CraneliftTrap),
|
||||
Timeout,
|
||||
Error(Box<dyn std::error::Error>),
|
||||
}
|
||||
|
||||
@@ -36,7 +39,8 @@ fn run_in_interpreter(interpreter: &mut Interpreter, args: &[DataValue]) -> RunR
|
||||
Ok(ControlFlow::Return(results)) => RunResult::Success(results.to_vec()),
|
||||
Ok(ControlFlow::Trap(trap)) => RunResult::Trap(trap),
|
||||
Ok(cf) => RunResult::Error(format!("Unrecognized exit ControlFlow: {:?}", cf).into()),
|
||||
Err(e) => RunResult::Error(format!("InterpreterError: {:?}", e).into()),
|
||||
Err(InterpreterError::FuelExhausted) => RunResult::Timeout,
|
||||
Err(e) => RunResult::Error(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,12 +50,12 @@ fn run_in_host(compiled_fn: &CompiledFunction, args: &[DataValue]) -> RunResult
|
||||
}
|
||||
|
||||
fuzz_target!(|testcase: TestCase| {
|
||||
let mut interpreter = {
|
||||
let build_interpreter = || {
|
||||
let mut env = FunctionStore::default();
|
||||
env.add(testcase.func.name.to_string(), &testcase.func);
|
||||
|
||||
let state = InterpreterState::default().with_function_store(env);
|
||||
let interpreter = Interpreter::new(state);
|
||||
let interpreter = Interpreter::new(state).with_fuel(Some(INTERPRETER_FUEL));
|
||||
interpreter
|
||||
};
|
||||
|
||||
@@ -60,6 +64,9 @@ fuzz_target!(|testcase: TestCase| {
|
||||
let compiled_fn = host_compiler.compile(testcase.func.clone()).unwrap();
|
||||
|
||||
for args in &testcase.inputs {
|
||||
// We rebuild the interpreter every run so that we don't accidentally carry over any state
|
||||
// between runs, such as fuel remaining.
|
||||
let mut interpreter = build_interpreter();
|
||||
let int_res = run_in_interpreter(&mut interpreter, args);
|
||||
match int_res {
|
||||
RunResult::Success(_) => {}
|
||||
@@ -71,6 +78,10 @@ fuzz_target!(|testcase: TestCase| {
|
||||
// not justify implementing it again here.
|
||||
return;
|
||||
}
|
||||
RunResult::Timeout => {
|
||||
// We probably generated an infinite loop, we can ignore this
|
||||
return;
|
||||
}
|
||||
RunResult::Error(_) => panic!("interpreter failed: {:?}", int_res),
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user