cranelift: CLIF Fuzzer limit instructions executed in interpreter

This commit is contained in:
Afonso Bordado
2021-07-05 14:38:53 +01:00
parent 1532516a36
commit fb1201cb60

View File

@@ -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),
}