MCPcopy Create free account
hub / github.com/MultiFuzz/MultiFuzz / run

Method run

hail-fuzz/src/extension.rs:263–336  ·  view source on GitHub ↗
(fuzzer: &mut Fuzzer, stats: &mut monitor::LocalStats)

Source from the content-addressed store, hash-verified

261
262impl FuzzerStage for MultiStreamExtendStage {
263 fn run(fuzzer: &mut Fuzzer, stats: &mut monitor::LocalStats) -> anyhow::Result<StageExit> {
264 let mut state = match MultiStreamExtendStage::start(fuzzer) {
265 Ok(data) => data,
266 Err(err) => return Ok(err.into()),
267 };
268
269 loop {
270 if state.attempts == 0 {
271 // Check if there any pending partial extensions to try.
272 if let Err(exit) = state.prepare_new_input(fuzzer) {
273 // Done with this stage.
274 fuzzer.prefix_snapshot = None;
275 return Ok(exit);
276 }
277 }
278 state.attempts -= 1;
279
280 let Some(exit) = state.exec_one(fuzzer)
281 else {
282 return Ok(StageExit::Interrupted);
283 };
284
285 let mut new_mmio_addr = false;
286 if matches!(exit, VmExit::UnhandledException((ExceptionCode::ReadWatch, _))) {
287 // If the mutated input ends at a new location then consider saving it, for a second
288 // multi-stream extension stage.
289 let end_addr = fuzzer.vm.cpu.read_pc();
290 if state.end_addrs.insert(end_addr) {
291 state.rare_input = Some((end_addr, fuzzer.state.input.clone()));
292 }
293 else if state.rare_input.as_ref().map_or(false, |(addr, _)| *addr == end_addr) {
294 // We found the same ending point again (meaning this was not a rare input).
295 state.rare_input = None;
296 }
297
298 // If fuzzing stops because a different stream was read from, added to the list of
299 // streams we are extending.
300 if let Some(addr) = fuzzer.state.input.last_read {
301 // Record metadata for the input causing the exit. This is used to increase
302 // the size of extensions on inputs with a large number of exits.
303 let metadata = fuzzer.corpus.metadata.streams.entry(addr).or_default();
304 metadata.reached_end_of_stream += 1;
305
306 if let Some(id) = fuzzer.input_id {
307 *fuzzer.corpus[id]
308 .stage_data::<LengthExtData>(Stage::MultiStreamExtend)
309 .stream_exits
310 .entry(addr)
311 .or_default() += 1;
312 }
313
314 state.streams_to_mutate.entry(addr).or_insert_with(|| {
315 new_mmio_addr = true;
316 fuzzer.get_extension_factor(addr)
317 });
318 };
319 }
320

Callers

nothing calls this directly

Calls 7

save_metadataFunction · 0.85
prepare_new_inputMethod · 0.80
exec_oneMethod · 0.80
cloneMethod · 0.80
get_extension_factorMethod · 0.80
check_exit_stateMethod · 0.80
update_statsMethod · 0.80

Tested by

no test coverage detected