AngoraFuzzer / Angora

Angora is a mutation-based fuzzer. The main goal of Angora is to increase branch coverage by solving path constraints without symbolic execution.
Apache License 2.0
917 stars 166 forks source link

Can't support single-core machine? #15

Closed CCCCCrash closed 5 years ago

CCCCCrash commented 5 years ago

When i run angora on a single-core machine, there will be an error

root@c2f338f707d8:/data# /angora/angora_fuzzer --sync_afl -A -i seeds -o output -t ./track/install/bin/file -- ./fast/install/bin/file -m ./fast/install/share/misc/magic.mgc @@
 WARN  angora::fuzz_main > dir has existed. "output"
 INFO  angora::fuzz_main > depot: DepotDir { inputs_dir: "output/angora/queue", hangs_dir: "output/angora/hangs", crashes_dir: "output/angora/crashes", seeds_dir: "seeds" }
 INFO  angora::fuzz_main > CommandOpt { id: 0, main: ("./fast/install/bin/file", ["-m", "./fast/install/share/misc/magic.mgc", "@@"]), track: ("./track/install/bin/file", ["-m", "./fast/install/share/misc/magic.mgc", "@@"]), tmp_dir: "output/angora/tmp", out_file: "output/angora/tmp/cur_input", forksrv_socket_path: "output/angora/tmp/forksrv_socket", track_path: "output/angora/tmp/track", is_stdin: false, search_method: Gd, mem_limit: 200, time_limit: 1, is_raw: true, ld_library: "$LD_LIBRARY_PATH:/clang+llvm/lib", enable_afl: false, enable_exploitation: true }
 INFO  angora::executor::forksrv > All right -- Init ForkServer output/angora/tmp/forksrv_socket_0 successfully!
 INFO  angora::depot::sync       > sync       1 file from seeds.
 INFO  angora::bind_cpu          > Found 1 cores.
 INFO  angora::bind_cpu          > Free Cpus: []
thread 'main' panicked at 'index out of bounds: the len is 0 but the index is 0', /rustc/a2b0f247bf741a1a9729363dda8628a938f1fe58/src/libcore/slice/mod.rs:2455:10
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
             at src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:39
   1: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:70
   2: std::panicking::default_hook::{{closure}}
             at src/libstd/sys_common/backtrace.rs:58
             at src/libstd/panicking.rs:200
   3: std::panicking::default_hook
             at src/libstd/panicking.rs:215
   4: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:478
   5: std::panicking::continue_panic_fmt
             at src/libstd/panicking.rs:385
   6: rust_begin_unwind
             at src/libstd/panicking.rs:312
   7: core::panicking::panic_fmt
             at src/libcore/panicking.rs:85
   8: core::panicking::panic_bounds_check
             at src/libcore/panicking.rs:61
   9: angora::fuzz_main::fuzz_main
  10: fuzzer::main
  11: std::rt::lang_start::{{closure}}
  12: std::panicking::try::do_call
             at src/libstd/rt.rs:49
             at src/libstd/panicking.rs:297
  13: __rust_maybe_catch_panic
             at src/libpanic_unwind/lib.rs:92
  14: std::rt::lang_start_internal
             at src/libstd/panicking.rs:276
             at src/libstd/panic.rs:388
             at src/libstd/rt.rs:48
  15: main
  16: __libc_start_main
  17: _start
 INFO  angora::depot::dump       > dump constraints and chart..

After i review the code, i find the error occurred in the fuzz_main.rs

fn init_cpus_and_run_fuzzing_threads(
    num_jobs: usize,
    running: &Arc<AtomicBool>,
    command_option: &command::CommandOpt,
    global_branches: &Arc<branches::GlobalBranches>,
    depot: &Arc<depot::Depot>,
    stats: &Arc<RwLock<stats::ChartStats>>,
) -> (Vec<thread::JoinHandle<()>>, Arc<AtomicUsize>) {
    let child_count = Arc::new(AtomicUsize::new(0));
    let mut handlers = vec![];
    let free_cpus = bind_cpu::find_free_cpus(num_jobs);
    let free_cpus_len = free_cpus.len();
    for thread_id in 0..num_jobs {
        let c = child_count.clone();
        let r = running.clone();
        let cmd = command_option.specify(thread_id + 1);
        let d = depot.clone();
        let b = global_branches.clone();
        let s = stats.clone();
        let cid = free_cpus[thread_id];
        let handler = thread::spawn(move || {
            c.fetch_add(1, Ordering::SeqCst);
            if free_cpus_len > thread_id {
                bind_cpu::bind_thread_to_cpu_core(cid);
            }
            fuzz_loop::fuzz_loop(r, cmd, d, b, s);
        });
        handlers.push(handler);
    }
    (handlers, child_count)
}

the free_cpus will be [] if i run it on a single-core machine, num_jobs was set 1 in fuzzer.rs default. so, in the line 20,let cid = free_cpus[thread_id];,free_cpus[thread_id] will produce an error.

if i set -j 0 in the command when run the fuzzer on a single-core machine, it can't run correctly.

Thank for your attention.

maverick117 commented 5 years ago

Okay, I fixed the bug that would introduce the indexing error. Now the fuzzer will not bind to any CPUs if the number of available ones is less than the job number.

Please see if this fixes your problem.

CCCCCrash commented 5 years ago

@maverick117 Yep, Now angora runs normally, That's great!

maverick117 commented 5 years ago

Glad to hear it.