From c944a70056bcf8beb7d02ad17a4ff48c25b303d6 Mon Sep 17 00:00:00 2001 From: Romain Malmain Date: Thu, 26 Sep 2024 14:29:33 +0200 Subject: [PATCH] Linux kernel fuzzing example (#2496) * linux kernel (x509_cert) and process fuzzing example * rework filters * update to latest qemu * working for process and kernel fuzzing * new i2s mutator for binary only fuzzers * refactoring modules with new filtering interface * add state as parameter of harness * hide unused global in usermode * Script for stub bindings generation * do not try to check whether it is worth generating the bindings, always generate when the env variable is on. * add taplo to fmt_all.sh * Moved fuzzers (again) in a target-centric way. * fix rust 2024 warnings. * new libafl_qemu harness structure. * rename qemu_systemmode into qemu_baremetal * fix qemu baremetal makefile * fix formatter --------- Co-authored-by: Toka --- .github/workflows/build_and_test.yml | 109 +- .github/workflows/md-config.json | 3 + README.md | 2 +- fuzzers/README.md | 13 +- .../frida_executable_libpng/.gitignore | 0 .../frida_executable_libpng/Cargo.toml | 0 .../frida_executable_libpng/Makefile.toml | 0 .../frida_executable_libpng/README.md | 0 .../corpus/not_kitty.png | Bin .../corpus/not_kitty_alpha.png | Bin .../corpus/not_kitty_gamma.png | Bin .../corpus/not_kitty_icc.png | Bin .../frida_executable_libpng/harness.cc | 0 .../frida_executable_libpng/src/fuzzer.rs | 0 .../frida_executable_libpng/src/lib.rs | 0 .../frida_gdiplus/.gitignore | 0 .../frida_gdiplus/Cargo.toml | 0 .../frida_gdiplus/Makefile.toml | 0 .../frida_gdiplus/README.md | 0 .../frida_gdiplus/cargo/.config | 0 .../frida_gdiplus/cmplog_test.asm | 0 .../frida_gdiplus/cmplog_test.def | 0 .../frida_gdiplus/corpus/not_kitty.png | Bin .../frida_gdiplus/corpus/not_kitty_alpha.png | Bin .../frida_gdiplus/corpus/not_kitty_gamma.png | Bin .../frida_gdiplus/corpus/not_kitty_icc.png | Bin .../frida_gdiplus/harness.cc | 0 .../frida_gdiplus/src/fuzzer.rs | 0 .../frida_gdiplus/src/main.rs | 0 .../frida_libpng/.gitignore | 0 .../frida_libpng/Cargo.toml | 0 .../frida_libpng/Makefile.toml | 0 .../frida_libpng/README.md | 0 .../frida_libpng/corpus/not_kitty.png | Bin .../frida_libpng/corpus/not_kitty_alpha.png | Bin .../frida_libpng/corpus/not_kitty_gamma.png | Bin .../frida_libpng/corpus/not_kitty_icc.png | Bin .../frida_libpng/harness.cc | 0 .../frida_libpng/harness_win.cpp | 0 .../frida_libpng/src/fuzzer.rs | 0 .../frida_libpng/src/main.rs | 0 .../fuzzbench_fork_qemu/.gitignore | 0 .../fuzzbench_fork_qemu/Cargo.toml | 0 .../fuzzbench_fork_qemu/Makefile.toml | 2 +- .../fuzzbench_fork_qemu/libfuzzer_main.c | 0 .../fuzzbench_fork_qemu/src/fuzzer.rs | 4 +- .../fuzzbench_fork_qemu/src/main.rs | 0 .../fuzzbench_qemu/.gitignore | 0 .../fuzzbench_qemu/Cargo.toml | 0 .../fuzzbench_qemu/Makefile.toml | 4 +- .../fuzzbench_qemu}/README.md | 0 .../fuzzbench_qemu/libfuzzer_main.c | 0 .../fuzzbench_qemu/src/fuzzer.rs | 59 +- .../fuzzbench_qemu/src/main.rs | 0 .../python_qemu/README.md | 0 .../{qemu => binary-only}/python_qemu/fuzz.c | 0 .../python_qemu/fuzzer.py | 0 .../qemu_cmin/.gitignore | 0 .../qemu_cmin/Cargo.toml | 0 .../qemu_cmin/Makefile.toml | 0 .../{qemu => binary-only}/qemu_cmin/README.md | 0 .../{qemu => binary-only}/qemu_cmin/build.rs | 0 .../qemu_cmin}/corpus/not_kitty.png | Bin .../qemu_cmin}/corpus/not_kitty_alpha.png | Bin .../qemu_cmin}/corpus/not_kitty_gamma.png | Bin .../qemu_cmin}/corpus/not_kitty_icc.png | Bin .../qemu_cmin/harness.cc | 0 .../qemu_cmin/src/fuzzer.rs | 4 +- .../qemu_cmin/src/main.rs | 0 .../qemu_coverage/.gitignore | 0 .../qemu_coverage/Cargo.toml | 0 .../qemu_coverage/Makefile.toml | 0 .../qemu_coverage/README.md | 0 .../qemu_coverage/build.rs | 0 .../qemu_coverage}/corpus/not_kitty.png | Bin .../qemu_coverage}/corpus/not_kitty_alpha.png | Bin .../qemu_coverage}/corpus/not_kitty_gamma.png | Bin .../qemu_coverage}/corpus/not_kitty_icc.png | Bin .../qemu_coverage/harness.cc | 0 .../qemu_coverage/src/fuzzer.rs | 29 +- .../qemu_coverage/src/main.rs | 0 .../qemu_launcher/.gitignore | 0 .../qemu_launcher/Cargo.toml | 0 .../qemu_launcher/Makefile.toml | 0 .../qemu_launcher/README.md | 0 .../qemu_launcher/build.rs | 0 .../qemu_launcher}/corpus/not_kitty.png | Bin .../qemu_launcher}/corpus/not_kitty_alpha.png | Bin .../qemu_launcher}/corpus/not_kitty_gamma.png | Bin .../qemu_launcher}/corpus/not_kitty_icc.png | Bin .../qemu_launcher/harness.cc | 0 .../qemu_launcher/injection_test/.gitignore | 0 .../qemu_launcher/injection_test/Makefile | 0 .../qemu_launcher/injection_test/README.md | 0 .../qemu_launcher/injection_test/example.db | Bin .../qemu_launcher/injection_test/sqltest.c | 0 .../qemu_launcher/injections.toml | 0 .../qemu_launcher/injections.yaml | 0 .../qemu_launcher/src/client.rs | 18 +- .../qemu_launcher/src/fuzzer.rs | 0 .../qemu_launcher/src/harness.rs | 0 .../qemu_launcher/src/instance.rs | 5 +- .../qemu_launcher/src/main.rs | 0 .../qemu_launcher/src/options.rs | 0 .../qemu_launcher/src/version.rs | 0 .../tinyinst_simple/Cargo.toml | 0 .../tinyinst_simple/Makefile.toml | 0 .../tinyinst_simple/README.md | 0 .../tinyinst_simple/src/main.rs | 0 .../tinyinst_simple/test/crash_input.txt | 0 .../tinyinst_simple/test/ok_input.txt | 0 .../tinyinst_simple/test/test.cpp | 0 .../fuzzbench_forkserver}/.gitignore | 0 .../fuzzbench_forkserver/Cargo.toml | 0 .../fuzzbench_forkserver/src/main.rs | 0 .../fuzzbench_forkserver_cmplog/Cargo.toml | 0 .../fuzzbench_forkserver_cmplog/src/main.rs | 0 .../test/compile.sh | 0 .../test/test-cmplog.c | 0 .../libafl-fuzz/.gitignore | 0 .../libafl-fuzz/Cargo.toml | 0 .../libafl-fuzz/Makefile.toml | 0 .../libafl-fuzz/README.md | 0 .../libafl-fuzz/rustfmt.toml | 0 .../libafl-fuzz/src/afl_stats.rs | 0 .../libafl-fuzz/src/corpus.rs | 0 .../libafl-fuzz/src/env_parser.rs | 0 .../libafl-fuzz/src/executor.rs | 0 .../libafl-fuzz/src/feedback/filepath.rs | 0 .../libafl-fuzz/src/feedback/mod.rs | 0 .../src/feedback/persistent_record.rs | 0 .../libafl-fuzz/src/feedback/seed.rs | 0 .../libafl-fuzz/src/fuzzer.rs | 0 .../libafl-fuzz/src/hooks.rs | 0 .../libafl-fuzz/src/main.rs | 0 .../libafl-fuzz/src/scheduler.rs | 0 .../libafl-fuzz/src/stages/mod.rs | 0 .../src/stages/mutational_stage.rs | 0 .../libafl-fuzz/src/stages/time_tracker.rs | 0 .../libafl-fuzz/test/seeds-frida/init | 0 .../libafl-fuzz/test/seeds/init | 0 .../libafl-fuzz/test/seeds_cmplog/init | 0 .../libafl-fuzz/test/seeds_frida/init | 0 .../libafl-fuzz/test/seeds_qemu/init | 0 .../libafl-fuzz/test/seeds_unicorn/in | 0 .../libafl-fuzz/test/seeds_unicorn_cmpcov/in | 0 .../libafl-fuzz/test/test-cmpcov.c | 0 .../libafl-fuzz/test/test-cmplog.c | 0 .../libafl-fuzz/test/test-instr.c | 0 .../libafl-fuzz/test/test.sh | 0 .../nyx_libxml2_parallel/Cargo.toml | 0 .../nyx_libxml2_parallel/Makefile.toml | 0 .../nyx_libxml2_parallel/README.md | 0 .../nyx_libxml2_parallel/setup_libxml2.sh | 0 .../nyx_libxml2_parallel/src/bin/libafl_cc.rs | 0 .../src/bin/libafl_cxx.rs | 0 .../nyx_libxml2_parallel/src/main.rs | 0 .../nyx_libxml2_standalone/Cargo.toml | 0 .../nyx_libxml2_standalone/Makefile.toml | 0 .../nyx_libxml2_standalone/README.md | 0 .../nyx_libxml2_standalone/setup_libxml2.sh | 0 .../src/bin/libafl_cc.rs | 0 .../src/bin/libafl_cxx.rs | 0 .../nyx_libxml2_standalone/src/main.rs | 0 .../qemu_baremetal}/.gitignore | 0 .../qemu_baremetal}/Cargo.toml | 9 +- .../qemu_baremetal}/Makefile.toml | 52 +- .../qemu_baremetal}/README.md | 7 +- .../qemu_baremetal}/build.rs | 2 +- .../qemu_baremetal}/corpus/random | 0 .../qemu_baremetal}/corpus/zero | Bin .../qemu_baremetal}/example/main.c | 9 +- .../qemu_baremetal}/example/mps2_m3.ld | 0 .../qemu_baremetal}/example/startup.c | 0 .../qemu_baremetal}/src/fuzzer_breakpoint.rs | 12 +- .../qemu_baremetal/src/fuzzer_low_level.rs} | 99 +- .../qemu_baremetal}/src/fuzzer_sync_exit.rs | 12 +- .../qemu_baremetal}/src/main.rs | 8 +- .../full-system/qemu_linux_kernel/.gitignore | 2 + .../full-system/qemu_linux_kernel/Cargo.toml | 35 + .../qemu_linux_kernel/Makefile.toml | 183 ++ .../full-system/qemu_linux_kernel/README.md | 33 + .../full-system/qemu_linux_kernel/build.rs | 5 + .../qemu_linux_kernel/corpus/random | 1 + .../full-system/qemu_linux_kernel/corpus/zero | Bin 0 -> 5 bytes .../qemu_linux_kernel/runtime/entrypoint.sh | 4 + .../qemu_linux_kernel/setup/Makefile | 9 + .../qemu_linux_kernel/setup/harness.c | 170 ++ .../qemu_linux_kernel/setup/setup.sh | 6 + .../qemu_linux_kernel/setup/user.c | 19 + .../qemu_linux_kernel/setup/x509-parser.h | 46 + .../qemu_linux_kernel/src/fuzzer.rs | 211 +++ .../full-system/qemu_linux_kernel/src/main.rs | 14 + .../full-system/qemu_linux_process/.gitignore | 2 + .../full-system/qemu_linux_process/Cargo.toml | 32 + .../qemu_linux_process/Makefile.toml | 202 +++ .../full-system/qemu_linux_process/README.md | 34 + .../full-system/qemu_linux_process/build.rs | 5 + .../qemu_linux_process/corpus/random | 1 + .../qemu_linux_process/corpus/zero | Bin 0 -> 5 bytes .../qemu_linux_process/example/harness.c | 44 + .../qemu_linux_process/runtime/entrypoint.sh | 5 + .../qemu_linux_process/setup/setup.sh | 3 + .../qemu_linux_process/src/fuzzer.rs | 213 +++ .../qemu_linux_process/src/main.rs | 14 + .../nautilus_sync/.gitignore | 0 .../nautilus_sync/Cargo.toml | 0 .../nautilus_sync/Makefile.toml | 2 +- .../nautilus_sync/rust-toolchain | 0 .../nautilus_sync/src/bin/libafl_cc.rs | 0 .../nautilus_sync}/src/bin/libafl_cxx.rs | 0 .../nautilus_sync/src/lib.rs | 0 .../cargo_fuzz/Cargo.toml | 0 .../cargo_fuzz/Makefile.toml | 0 .../cargo_fuzz/README.md | 0 .../cargo_fuzz/fuzz/.gitignore | 0 .../cargo_fuzz/fuzz/Cargo.toml | 0 .../fuzz/fuzz_targets/fuzz_target_1.rs | 0 .../cargo_fuzz/src/lib.rs | 0 .../dynamic_analysis/Cargo.toml | 0 .../dynamic_analysis/Makefile.toml | 0 .../dynamic_analysis/README.md | 0 .../dynamic_analysis/build.rs | 0 .../dynamic_analysis/build.sh | 0 .../dynamic_analysis/clean.sh | 0 .../dynamic_analysis/cms_transform_fuzzer.cc | 0 .../dynamic_analysis/concatenator.py | 0 .../dynamic_analysis/corpus/seed | Bin .../dynamic_analysis/src/bin/libafl_cc.rs | 0 .../dynamic_analysis}/src/bin/libafl_cxx.rs | 0 .../dynamic_analysis/src/lib.rs | 0 .../dynamic_analysis}/stub_rt.c | 0 .../fuzzbench}/.gitignore | 0 .../fuzzbench/Cargo.toml | 0 .../fuzzbench/Makefile.toml | 0 .../fuzzbench}/README.md | 0 .../{fuzzbench => inprocess}/fuzzbench/fuzz.c | 0 .../fuzzbench/src/bin/libafl_cc.rs | 0 .../fuzzbench}/src/bin/libafl_cxx.rs | 0 .../fuzzbench/src/lib.rs | 0 .../fuzzbench}/stub_rt.c | 0 .../fuzzbench_ctx/Cargo.toml | 0 .../fuzzbench_ctx/Makefile.toml | 0 .../fuzzbench_ctx/fuzz.c | 0 .../fuzzbench_ctx/src/bin/libafl_cc.rs | 0 .../fuzzbench_ctx}/src/bin/libafl_cxx.rs | 0 .../fuzzbench_ctx/src/lib.rs | 0 .../fuzzbench_ctx}/stub_rt.c | 0 .../fuzzbench_text/.gitignore | 0 .../fuzzbench_text/Cargo.toml | 0 .../fuzzbench_text/Makefile.toml | 0 .../fuzzbench_text/README.md | 0 .../fuzzbench_text/fuzz.c | 0 .../fuzzbench_text/src/bin/libafl_cc.rs | 0 .../fuzzbench_text}/src/bin/libafl_cxx.rs | 0 .../fuzzbench_text/src/lib.rs | 0 .../libfuzzer_libmozjpeg/.gitignore | 0 .../libfuzzer_libmozjpeg/Cargo.toml | 0 .../libfuzzer_libmozjpeg/Makefile.toml | 0 .../libfuzzer_libmozjpeg/README.md | 0 .../libfuzzer_libmozjpeg/build.rs | 0 .../libfuzzer_libmozjpeg/corpus/blank.jpg | Bin .../libfuzzer_libmozjpeg/harness.cc | 0 .../libfuzzer_libmozjpeg/hook_allocs.c | 0 .../libfuzzer_libmozjpeg/jpeg.dict | 0 .../libfuzzer_libmozjpeg/src/bin/libafl_cc.rs | 0 .../src/bin/libafl_cxx.rs | 0 .../libfuzzer_libmozjpeg/src/lib.rs | 0 .../libfuzzer_libpng/.gitignore | 0 .../libfuzzer_libpng/Cargo.toml | 0 .../libfuzzer_libpng/Makefile.toml | 0 .../libfuzzer_libpng/README.md | 0 .../libfuzzer_libpng}/corpus/not_kitty.png | Bin .../corpus/not_kitty_alpha.png | Bin .../corpus/not_kitty_gamma.png | Bin .../corpus/not_kitty_icc.png | Bin .../libfuzzer_libpng/harness.cc | 0 .../libfuzzer_libpng/src/bin/libafl_cc.rs | 0 .../libfuzzer_libpng}/src/bin/libafl_cxx.rs | 0 .../libfuzzer_libpng/src/lib.rs | 0 .../libfuzzer_libpng_accounting/.gitignore | 0 .../libfuzzer_libpng_accounting/Cargo.toml | 0 .../libfuzzer_libpng_accounting/Makefile.toml | 0 .../libfuzzer_libpng_accounting/README.md | 0 .../corpus/not_kitty.png | Bin .../corpus/not_kitty_alpha.png | Bin .../corpus/not_kitty_gamma.png | Bin .../corpus/not_kitty_icc.png | Bin .../libfuzzer_libpng_accounting/harness.cc | 0 .../src/bin/libafl_cc.rs | 0 .../src/bin/libafl_cxx.rs | 0 .../libfuzzer_libpng_accounting/src/lib.rs | 0 .../libfuzzer_libpng_centralized/.gitignore | 0 .../libfuzzer_libpng_centralized/Cargo.toml | 0 .../Makefile.toml | 0 .../libfuzzer_libpng_centralized/README.md | 0 .../corpus}/not_kitty.png | Bin .../corpus}/not_kitty_alpha.png | Bin .../corpus}/not_kitty_gamma.png | Bin .../corpus}/not_kitty_icc.png | Bin .../libfuzzer_libpng_centralized/harness.cc | 0 .../src/bin/libafl_cc.rs | 0 .../src/bin/libafl_cxx.rs | 0 .../libfuzzer_libpng_centralized/src/lib.rs | 0 .../libfuzzer_libpng_cmin/.gitignore | 0 .../libfuzzer_libpng_cmin/Cargo.toml | 0 .../libfuzzer_libpng_cmin/Makefile.toml | 0 .../libfuzzer_libpng_cmin/README.md | 0 .../corpus/not_kitty.png | Bin .../corpus/not_kitty_alpha.png | Bin .../corpus/not_kitty_gamma.png | Bin .../corpus/not_kitty_icc.png | Bin .../libfuzzer_libpng_cmin/harness.cc | 0 .../src/bin/libafl_cc.rs | 0 .../src/bin/libafl_cxx.rs | 0 .../libfuzzer_libpng_cmin/src/lib.rs | 0 .../libfuzzer_libpng_launcher/.gitignore | 0 .../libfuzzer_libpng_launcher/Cargo.toml | 0 .../libfuzzer_libpng_launcher/Makefile.toml | 0 .../libfuzzer_libpng_launcher/README.md | 0 .../corpus/not_kitty.png | Bin .../corpus/not_kitty_alpha.png | Bin .../corpus/not_kitty_gamma.png | Bin .../corpus/not_kitty_icc.png | Bin .../libfuzzer_libpng_launcher/harness.cc | 0 .../src/bin/libafl_ar.rs | 0 .../src/bin/libafl_cc.rs | 0 .../src/bin/libafl_cxx.rs | 0 .../src/bin/libafl_libtool.rs | 0 .../libfuzzer_libpng_launcher/src/lib.rs | 0 .../libfuzzer_libpng_norestart/.gitignore | 0 .../libfuzzer_libpng_norestart/Cargo.toml | 0 .../libfuzzer_libpng_norestart/Makefile.toml | 0 .../libfuzzer_libpng_norestart/README.md | 0 .../libfuzzer_libpng_norestart/harness.cc | 0 .../seeds}/not_kitty.png | Bin .../seeds}/not_kitty_alpha.png | Bin .../seeds}/not_kitty_gamma.png | Bin .../seeds}/not_kitty_icc.png | Bin .../src/bin/libafl_cc.rs | 0 .../src/bin/libafl_cxx.rs | 0 .../libfuzzer_libpng_norestart/src/lib.rs | 0 .../libfuzzer_libpng_tcp_manager/.gitignore | 0 .../libfuzzer_libpng_tcp_manager/Cargo.toml | 0 .../Makefile.toml | 0 .../libfuzzer_libpng_tcp_manager/README.md | 0 .../corpus/not_kitty.png | Bin .../corpus/not_kitty_alpha.png | Bin .../corpus/not_kitty_gamma.png | Bin .../corpus/not_kitty_icc.png | Bin .../libfuzzer_libpng_tcp_manager/harness.cc | 0 .../src/bin/libafl_cc.rs | 0 .../src/bin/libafl_cxx.rs | 0 .../libfuzzer_libpng_tcp_manager/src/lib.rs | 0 .../libfuzzer_stb_image/.gitignore | 0 .../libfuzzer_stb_image/Cargo.toml | 0 .../libfuzzer_stb_image/Makefile.toml | 0 .../libfuzzer_stb_image/README.md | 0 .../libfuzzer_stb_image/build.rs | 0 .../libfuzzer_stb_image/corpus/not_kitty.png | Bin .../corpus/not_kitty_alpha.png | Bin .../corpus/not_kitty_gamma.png | Bin .../corpus/not_kitty_icc.png | Bin .../libfuzzer_stb_image/harness.c | 0 .../libfuzzer_stb_image/src/main.rs | 0 .../libfuzzer_stb_image/stb_image.h | 0 .../Makefile.toml | 0 .../libfuzzer_stb_image_concolic/README.md | 0 .../fuzzer/.gitignore | 0 .../fuzzer/Cargo.toml | 0 .../fuzzer/build.rs | 0 .../fuzzer/corpus/not_kitty.png | Bin .../fuzzer/corpus/not_kitty_alpha.png | Bin .../fuzzer/corpus/not_kitty_gamma.png | Bin .../fuzzer/corpus/not_kitty_icc.png | Bin .../fuzzer/harness.c | 0 .../fuzzer/harness_symcc.c | 0 .../fuzzer/src/main.rs | 0 .../fuzzer/stb_image.h | 0 .../runtime/Cargo.toml | 0 .../runtime/src/lib.rs | 0 .../libfuzzer_stb_image_sugar/.gitignore | 0 .../libfuzzer_stb_image_sugar/Cargo.toml | 0 .../libfuzzer_stb_image_sugar/Makefile.toml | 0 .../libfuzzer_stb_image_sugar/README.md | 0 .../libfuzzer_stb_image_sugar/build.rs | 0 .../corpus/not_kitty.png | Bin .../corpus/not_kitty_alpha.png | Bin .../corpus/not_kitty_gamma.png | Bin .../corpus/not_kitty_icc.png | Bin .../libfuzzer_stb_image_sugar/harness.c | 0 .../libfuzzer_stb_image_sugar/src/main.rs | 0 .../libfuzzer_stb_image_sugar/stb_image.h | 0 .../libfuzzer_windows_asan/.gitignore | 0 .../libfuzzer_windows_asan/Cargo.toml | 0 .../libfuzzer_windows_asan/Makefile.toml | 0 .../libfuzzer_windows_asan/README.md | 0 .../libfuzzer_windows_asan/corpus/hello_world | 0 .../libfuzzer_windows_asan/harness.cpp | 0 .../src/bin/libafl_cc.rs | 0 .../src/bin/libafl_cxx.rs | 0 .../libfuzzer_windows_asan/src/lib.rs | 0 .../push_harness/.gitignore | 0 .../push_harness/Cargo.toml | 0 .../push_harness/README.md | 0 .../push_harness/src/main.rs | 0 .../push_stage_harness/.gitignore | 0 .../push_stage_harness/Cargo.toml | 0 .../push_stage_harness/README.md | 0 .../push_stage_harness/src/main.rs | 0 .../Cargo.toml | 0 .../README.md | 0 .../sqlite_centralized_multi_machine/build.sh | 0 .../run_child.sh | 0 .../run_parent.sh | 0 .../src/bin/libafl_cc.rs | 0 .../src/bin/libafl_cxx.rs | 0 .../src/lib.rs | 0 .../{others => inprocess}/tutorial/Cargo.toml | 0 .../tutorial/rust-toolchain | 0 .../tutorial/src/bin/libafl_cc.rs | 0 .../tutorial/src/bin/libafl_cxx.rs | 0 .../tutorial/src/input.rs | 0 .../{others => inprocess}/tutorial/src/lib.rs | 0 .../tutorial/src/metadata.rs | 0 .../tutorial/src/mutator.rs | 0 .../{others => inprocess}/tutorial/target.c | 0 .../src/common/nautilus/grammartec/context.rs | 8 +- libafl/src/common/nautilus/grammartec/rule.rs | 8 +- libafl/src/common/nautilus/grammartec/tree.rs | 6 +- libafl/src/corpus/inmemory.rs | 8 +- libafl/src/events/events_hooks/mod.rs | 6 - libafl/src/events/launcher.rs | 2 +- libafl/src/events/llmp/mgr.rs | 4 +- libafl/src/events/tcp.rs | 3 +- libafl/src/executors/command.rs | 1 - libafl/src/executors/hooks/inprocess_fork.rs | 1 - libafl/src/executors/hooks/unix.rs | 2 +- libafl/src/executors/inprocess/stateful.rs | 22 +- libafl/src/executors/inprocess_fork/mod.rs | 1 - libafl/src/mutators/token_mutations.rs | 207 +++ libafl_bolts/src/lib.rs | 14 + libafl_bolts/src/llmp.rs | 10 +- libafl_bolts/src/rands/mod.rs | 6 + libafl_frida/src/asan/asan_rt.rs | 2 +- libafl_frida/src/asan/hook_funcs.rs | 2 + libafl_qemu/build_linux.rs | 26 + libafl_qemu/libafl_qemu_build/src/build.rs | 17 +- libafl_qemu/libafl_qemu_build/src/lib.rs | 192 +-- .../src/x86_64_stub_bindings.rs | 130 +- libafl_qemu/runtime/libafl_qemu.h | 274 +-- libafl_qemu/runtime/libafl_qemu_arch.h | 248 +++ libafl_qemu/runtime/libafl_qemu_defs.h | 37 + libafl_qemu/runtime/libafl_qemu_impl.h | 84 + .../runtime/libafl_qemu_stub_bindings.rs | 1478 ++++++++++++++++- libafl_qemu/src/arch/x86_64.rs | 4 +- libafl_qemu/src/command/mod.rs | 324 ++-- libafl_qemu/src/command/parser.rs | 108 +- libafl_qemu/src/emu/builder.rs | 4 +- libafl_qemu/src/emu/drivers.rs | 152 +- libafl_qemu/src/emu/hooks.rs | 8 +- libafl_qemu/src/emu/mod.rs | 98 +- libafl_qemu/src/emu/snapshot.rs | 2 + libafl_qemu/src/emu/systemmode.rs | 16 +- libafl_qemu/src/executor.rs | 41 +- libafl_qemu/src/modules/calls.rs | 50 +- libafl_qemu/src/modules/cmplog.rs | 131 +- libafl_qemu/src/modules/edges.rs | 914 +++++----- libafl_qemu/src/modules/mod.rs | 348 ++-- libafl_qemu/src/modules/systemmode/mod.rs | 27 - libafl_qemu/src/modules/usermode/asan.rs | 45 +- .../src/modules/usermode/asan_guest.rs | 60 +- libafl_qemu/src/modules/usermode/drcov.rs | 70 +- .../src/modules/usermode/injections.rs | 16 +- libafl_qemu/src/modules/usermode/mod.rs | 16 - libafl_qemu/src/modules/usermode/snapshot.rs | 19 +- libafl_qemu/src/qemu/mod.rs | 56 +- libafl_sugar/src/qemu.rs | 19 +- libafl_targets/src/libfuzzer/mutators.rs | 2 +- scripts/fmt_all.sh | 9 + scripts/gen_stub_bindings.sh | 9 + utils/libafl_fmt/src/main.rs | 23 +- 482 files changed, 5430 insertions(+), 1697 deletions(-) rename fuzzers/{frida => binary-only}/frida_executable_libpng/.gitignore (100%) rename fuzzers/{frida => binary-only}/frida_executable_libpng/Cargo.toml (100%) rename fuzzers/{frida => binary-only}/frida_executable_libpng/Makefile.toml (100%) rename fuzzers/{frida => binary-only}/frida_executable_libpng/README.md (100%) rename fuzzers/{frida => binary-only}/frida_executable_libpng/corpus/not_kitty.png (100%) rename fuzzers/{frida => binary-only}/frida_executable_libpng/corpus/not_kitty_alpha.png (100%) rename fuzzers/{frida => binary-only}/frida_executable_libpng/corpus/not_kitty_gamma.png (100%) rename fuzzers/{frida => binary-only}/frida_executable_libpng/corpus/not_kitty_icc.png (100%) rename fuzzers/{frida => binary-only}/frida_executable_libpng/harness.cc (100%) rename fuzzers/{frida => binary-only}/frida_executable_libpng/src/fuzzer.rs (100%) rename fuzzers/{frida => binary-only}/frida_executable_libpng/src/lib.rs (100%) rename fuzzers/{frida => binary-only}/frida_gdiplus/.gitignore (100%) rename fuzzers/{frida => binary-only}/frida_gdiplus/Cargo.toml (100%) rename fuzzers/{frida => binary-only}/frida_gdiplus/Makefile.toml (100%) rename fuzzers/{frida => binary-only}/frida_gdiplus/README.md (100%) rename fuzzers/{frida => binary-only}/frida_gdiplus/cargo/.config (100%) rename fuzzers/{frida => binary-only}/frida_gdiplus/cmplog_test.asm (100%) rename fuzzers/{frida => binary-only}/frida_gdiplus/cmplog_test.def (100%) rename fuzzers/{frida => binary-only}/frida_gdiplus/corpus/not_kitty.png (100%) rename fuzzers/{frida => binary-only}/frida_gdiplus/corpus/not_kitty_alpha.png (100%) rename fuzzers/{frida => binary-only}/frida_gdiplus/corpus/not_kitty_gamma.png (100%) rename fuzzers/{frida => binary-only}/frida_gdiplus/corpus/not_kitty_icc.png (100%) rename fuzzers/{frida => binary-only}/frida_gdiplus/harness.cc (100%) rename fuzzers/{frida => binary-only}/frida_gdiplus/src/fuzzer.rs (100%) rename fuzzers/{frida => binary-only}/frida_gdiplus/src/main.rs (100%) rename fuzzers/{frida => binary-only}/frida_libpng/.gitignore (100%) rename fuzzers/{frida => binary-only}/frida_libpng/Cargo.toml (100%) rename fuzzers/{frida => binary-only}/frida_libpng/Makefile.toml (100%) rename fuzzers/{frida => binary-only}/frida_libpng/README.md (100%) rename fuzzers/{frida => binary-only}/frida_libpng/corpus/not_kitty.png (100%) rename fuzzers/{frida => binary-only}/frida_libpng/corpus/not_kitty_alpha.png (100%) rename fuzzers/{frida => binary-only}/frida_libpng/corpus/not_kitty_gamma.png (100%) rename fuzzers/{frida => binary-only}/frida_libpng/corpus/not_kitty_icc.png (100%) rename fuzzers/{frida => binary-only}/frida_libpng/harness.cc (100%) rename fuzzers/{frida => binary-only}/frida_libpng/harness_win.cpp (100%) rename fuzzers/{frida => binary-only}/frida_libpng/src/fuzzer.rs (100%) rename fuzzers/{frida => binary-only}/frida_libpng/src/main.rs (100%) rename fuzzers/{fuzzbench => binary-only}/fuzzbench_fork_qemu/.gitignore (100%) rename fuzzers/{fuzzbench => binary-only}/fuzzbench_fork_qemu/Cargo.toml (100%) rename fuzzers/{fuzzbench => binary-only}/fuzzbench_fork_qemu/Makefile.toml (97%) rename fuzzers/{fuzzbench => binary-only}/fuzzbench_fork_qemu/libfuzzer_main.c (100%) rename fuzzers/{fuzzbench => binary-only}/fuzzbench_fork_qemu/src/fuzzer.rs (98%) rename fuzzers/{fuzzbench => binary-only}/fuzzbench_fork_qemu/src/main.rs (100%) rename fuzzers/{fuzzbench => binary-only}/fuzzbench_qemu/.gitignore (100%) rename fuzzers/{fuzzbench => binary-only}/fuzzbench_qemu/Cargo.toml (100%) rename fuzzers/{fuzzbench => binary-only}/fuzzbench_qemu/Makefile.toml (96%) rename fuzzers/{fuzzbench/fuzzbench => binary-only/fuzzbench_qemu}/README.md (100%) rename fuzzers/{fuzzbench => binary-only}/fuzzbench_qemu/libfuzzer_main.c (100%) rename fuzzers/{fuzzbench => binary-only}/fuzzbench_qemu/src/fuzzer.rs (90%) rename fuzzers/{fuzzbench => binary-only}/fuzzbench_qemu/src/main.rs (100%) rename fuzzers/{qemu => binary-only}/python_qemu/README.md (100%) rename fuzzers/{qemu => binary-only}/python_qemu/fuzz.c (100%) rename fuzzers/{qemu => binary-only}/python_qemu/fuzzer.py (100%) rename fuzzers/{qemu => binary-only}/qemu_cmin/.gitignore (100%) rename fuzzers/{qemu => binary-only}/qemu_cmin/Cargo.toml (100%) rename fuzzers/{qemu => binary-only}/qemu_cmin/Makefile.toml (100%) rename fuzzers/{qemu => binary-only}/qemu_cmin/README.md (100%) rename fuzzers/{qemu => binary-only}/qemu_cmin/build.rs (100%) rename fuzzers/{libpng/libfuzzer_libpng => binary-only/qemu_cmin}/corpus/not_kitty.png (100%) rename fuzzers/{libpng/libfuzzer_libpng => binary-only/qemu_cmin}/corpus/not_kitty_alpha.png (100%) rename fuzzers/{libpng/libfuzzer_libpng => binary-only/qemu_cmin}/corpus/not_kitty_gamma.png (100%) rename fuzzers/{libpng/libfuzzer_libpng => binary-only/qemu_cmin}/corpus/not_kitty_icc.png (100%) rename fuzzers/{qemu => binary-only}/qemu_cmin/harness.cc (100%) rename fuzzers/{qemu => binary-only}/qemu_cmin/src/fuzzer.rs (97%) rename fuzzers/{qemu => binary-only}/qemu_cmin/src/main.rs (100%) rename fuzzers/{qemu => binary-only}/qemu_coverage/.gitignore (100%) rename fuzzers/{qemu => binary-only}/qemu_coverage/Cargo.toml (100%) rename fuzzers/{qemu => binary-only}/qemu_coverage/Makefile.toml (100%) rename fuzzers/{qemu => binary-only}/qemu_coverage/README.md (100%) rename fuzzers/{qemu => binary-only}/qemu_coverage/build.rs (100%) rename fuzzers/{libpng/libfuzzer_libpng_accounting => binary-only/qemu_coverage}/corpus/not_kitty.png (100%) rename fuzzers/{libpng/libfuzzer_libpng_accounting => binary-only/qemu_coverage}/corpus/not_kitty_alpha.png (100%) rename fuzzers/{libpng/libfuzzer_libpng_accounting => binary-only/qemu_coverage}/corpus/not_kitty_gamma.png (100%) rename fuzzers/{libpng/libfuzzer_libpng_accounting => binary-only/qemu_coverage}/corpus/not_kitty_icc.png (100%) rename fuzzers/{qemu => binary-only}/qemu_coverage/harness.cc (100%) rename fuzzers/{qemu => binary-only}/qemu_coverage/src/fuzzer.rs (94%) rename fuzzers/{qemu => binary-only}/qemu_coverage/src/main.rs (100%) rename fuzzers/{qemu => binary-only}/qemu_launcher/.gitignore (100%) rename fuzzers/{qemu => binary-only}/qemu_launcher/Cargo.toml (100%) rename fuzzers/{qemu => binary-only}/qemu_launcher/Makefile.toml (100%) rename fuzzers/{qemu => binary-only}/qemu_launcher/README.md (100%) rename fuzzers/{qemu => binary-only}/qemu_launcher/build.rs (100%) rename fuzzers/{libpng/libfuzzer_libpng_centralized => binary-only/qemu_launcher}/corpus/not_kitty.png (100%) rename fuzzers/{libpng/libfuzzer_libpng_centralized => binary-only/qemu_launcher}/corpus/not_kitty_alpha.png (100%) rename fuzzers/{libpng/libfuzzer_libpng_centralized => binary-only/qemu_launcher}/corpus/not_kitty_gamma.png (100%) rename fuzzers/{libpng/libfuzzer_libpng_centralized => binary-only/qemu_launcher}/corpus/not_kitty_icc.png (100%) rename fuzzers/{qemu => binary-only}/qemu_launcher/harness.cc (100%) rename fuzzers/{qemu => binary-only}/qemu_launcher/injection_test/.gitignore (100%) rename fuzzers/{qemu => binary-only}/qemu_launcher/injection_test/Makefile (100%) rename fuzzers/{qemu => binary-only}/qemu_launcher/injection_test/README.md (100%) rename fuzzers/{qemu => binary-only}/qemu_launcher/injection_test/example.db (100%) rename fuzzers/{qemu => binary-only}/qemu_launcher/injection_test/sqltest.c (100%) rename fuzzers/{qemu => binary-only}/qemu_launcher/injections.toml (100%) rename fuzzers/{qemu => binary-only}/qemu_launcher/injections.yaml (100%) rename fuzzers/{qemu => binary-only}/qemu_launcher/src/client.rs (94%) rename fuzzers/{qemu => binary-only}/qemu_launcher/src/fuzzer.rs (100%) rename fuzzers/{qemu => binary-only}/qemu_launcher/src/harness.rs (100%) rename fuzzers/{qemu => binary-only}/qemu_launcher/src/instance.rs (98%) rename fuzzers/{qemu => binary-only}/qemu_launcher/src/main.rs (100%) rename fuzzers/{qemu => binary-only}/qemu_launcher/src/options.rs (100%) rename fuzzers/{qemu => binary-only}/qemu_launcher/src/version.rs (100%) rename fuzzers/{others => binary-only}/tinyinst_simple/Cargo.toml (100%) rename fuzzers/{others => binary-only}/tinyinst_simple/Makefile.toml (100%) rename fuzzers/{others => binary-only}/tinyinst_simple/README.md (100%) rename fuzzers/{others => binary-only}/tinyinst_simple/src/main.rs (100%) rename fuzzers/{others => binary-only}/tinyinst_simple/test/crash_input.txt (100%) rename fuzzers/{others => binary-only}/tinyinst_simple/test/ok_input.txt (100%) rename fuzzers/{others => binary-only}/tinyinst_simple/test/test.cpp (100%) rename fuzzers/{fuzzbench/fuzzbench => forkserver/fuzzbench_forkserver}/.gitignore (100%) rename fuzzers/{fuzzbench => forkserver}/fuzzbench_forkserver/Cargo.toml (100%) rename fuzzers/{fuzzbench => forkserver}/fuzzbench_forkserver/src/main.rs (100%) rename fuzzers/{fuzzbench => forkserver}/fuzzbench_forkserver_cmplog/Cargo.toml (100%) rename fuzzers/{fuzzbench => forkserver}/fuzzbench_forkserver_cmplog/src/main.rs (100%) rename fuzzers/{fuzzbench => forkserver}/fuzzbench_forkserver_cmplog/test/compile.sh (100%) rename fuzzers/{fuzzbench => forkserver}/fuzzbench_forkserver_cmplog/test/test-cmplog.c (100%) rename fuzzers/{others => forkserver}/libafl-fuzz/.gitignore (100%) rename fuzzers/{others => forkserver}/libafl-fuzz/Cargo.toml (100%) rename fuzzers/{others => forkserver}/libafl-fuzz/Makefile.toml (100%) rename fuzzers/{others => forkserver}/libafl-fuzz/README.md (100%) rename fuzzers/{others => forkserver}/libafl-fuzz/rustfmt.toml (100%) rename fuzzers/{others => forkserver}/libafl-fuzz/src/afl_stats.rs (100%) rename fuzzers/{others => forkserver}/libafl-fuzz/src/corpus.rs (100%) rename fuzzers/{others => forkserver}/libafl-fuzz/src/env_parser.rs (100%) rename fuzzers/{others => forkserver}/libafl-fuzz/src/executor.rs (100%) rename fuzzers/{others => forkserver}/libafl-fuzz/src/feedback/filepath.rs (100%) rename fuzzers/{others => forkserver}/libafl-fuzz/src/feedback/mod.rs (100%) rename fuzzers/{others => forkserver}/libafl-fuzz/src/feedback/persistent_record.rs (100%) rename fuzzers/{others => forkserver}/libafl-fuzz/src/feedback/seed.rs (100%) rename fuzzers/{others => forkserver}/libafl-fuzz/src/fuzzer.rs (100%) rename fuzzers/{others => forkserver}/libafl-fuzz/src/hooks.rs (100%) rename fuzzers/{others => forkserver}/libafl-fuzz/src/main.rs (100%) rename fuzzers/{others => forkserver}/libafl-fuzz/src/scheduler.rs (100%) rename fuzzers/{others => forkserver}/libafl-fuzz/src/stages/mod.rs (100%) rename fuzzers/{others => forkserver}/libafl-fuzz/src/stages/mutational_stage.rs (100%) rename fuzzers/{others => forkserver}/libafl-fuzz/src/stages/time_tracker.rs (100%) rename fuzzers/{others => forkserver}/libafl-fuzz/test/seeds-frida/init (100%) rename fuzzers/{others => forkserver}/libafl-fuzz/test/seeds/init (100%) rename fuzzers/{others => forkserver}/libafl-fuzz/test/seeds_cmplog/init (100%) rename fuzzers/{others => forkserver}/libafl-fuzz/test/seeds_frida/init (100%) rename fuzzers/{others => forkserver}/libafl-fuzz/test/seeds_qemu/init (100%) rename fuzzers/{others => forkserver}/libafl-fuzz/test/seeds_unicorn/in (100%) rename fuzzers/{others => forkserver}/libafl-fuzz/test/seeds_unicorn_cmpcov/in (100%) rename fuzzers/{others => forkserver}/libafl-fuzz/test/test-cmpcov.c (100%) rename fuzzers/{others => forkserver}/libafl-fuzz/test/test-cmplog.c (100%) rename fuzzers/{others => forkserver}/libafl-fuzz/test/test-instr.c (100%) rename fuzzers/{others => forkserver}/libafl-fuzz/test/test.sh (100%) rename fuzzers/{nyx => full-system}/nyx_libxml2_parallel/Cargo.toml (100%) rename fuzzers/{nyx => full-system}/nyx_libxml2_parallel/Makefile.toml (100%) rename fuzzers/{nyx => full-system}/nyx_libxml2_parallel/README.md (100%) rename fuzzers/{nyx => full-system}/nyx_libxml2_parallel/setup_libxml2.sh (100%) rename fuzzers/{nyx => full-system}/nyx_libxml2_parallel/src/bin/libafl_cc.rs (100%) rename fuzzers/{fuzzbench/fuzzbench => full-system/nyx_libxml2_parallel}/src/bin/libafl_cxx.rs (100%) rename fuzzers/{nyx => full-system}/nyx_libxml2_parallel/src/main.rs (100%) rename fuzzers/{nyx => full-system}/nyx_libxml2_standalone/Cargo.toml (100%) rename fuzzers/{nyx => full-system}/nyx_libxml2_standalone/Makefile.toml (100%) rename fuzzers/{nyx => full-system}/nyx_libxml2_standalone/README.md (100%) rename fuzzers/{nyx => full-system}/nyx_libxml2_standalone/setup_libxml2.sh (100%) rename fuzzers/{nyx => full-system}/nyx_libxml2_standalone/src/bin/libafl_cc.rs (100%) rename fuzzers/{fuzzbench/fuzzbench_ctx => full-system/nyx_libxml2_standalone}/src/bin/libafl_cxx.rs (100%) rename fuzzers/{nyx => full-system}/nyx_libxml2_standalone/src/main.rs (100%) rename fuzzers/{qemu/qemu_systemmode => full-system/qemu_baremetal}/.gitignore (100%) rename fuzzers/{qemu/qemu_systemmode => full-system/qemu_baremetal}/Cargo.toml (80%) rename fuzzers/{qemu/qemu_systemmode => full-system/qemu_baremetal}/Makefile.toml (74%) rename fuzzers/{qemu/qemu_systemmode => full-system/qemu_baremetal}/README.md (83%) rename fuzzers/{qemu/qemu_systemmode => full-system/qemu_baremetal}/build.rs (86%) rename fuzzers/{qemu/qemu_systemmode => full-system/qemu_baremetal}/corpus/random (100%) rename fuzzers/{qemu/qemu_systemmode => full-system/qemu_baremetal}/corpus/zero (100%) rename fuzzers/{qemu/qemu_systemmode => full-system/qemu_baremetal}/example/main.c (89%) rename fuzzers/{qemu/qemu_systemmode => full-system/qemu_baremetal}/example/mps2_m3.ld (100%) rename fuzzers/{qemu/qemu_systemmode => full-system/qemu_baremetal}/example/startup.c (100%) rename fuzzers/{qemu/qemu_systemmode => full-system/qemu_baremetal}/src/fuzzer_breakpoint.rs (95%) rename fuzzers/{qemu/qemu_systemmode/src/fuzzer_classic.rs => full-system/qemu_baremetal/src/fuzzer_low_level.rs} (77%) rename fuzzers/{qemu/qemu_systemmode => full-system/qemu_baremetal}/src/fuzzer_sync_exit.rs (94%) rename fuzzers/{qemu/qemu_systemmode => full-system/qemu_baremetal}/src/main.rs (78%) create mode 100644 fuzzers/full-system/qemu_linux_kernel/.gitignore create mode 100644 fuzzers/full-system/qemu_linux_kernel/Cargo.toml create mode 100644 fuzzers/full-system/qemu_linux_kernel/Makefile.toml create mode 100644 fuzzers/full-system/qemu_linux_kernel/README.md create mode 100644 fuzzers/full-system/qemu_linux_kernel/build.rs create mode 100644 fuzzers/full-system/qemu_linux_kernel/corpus/random create mode 100644 fuzzers/full-system/qemu_linux_kernel/corpus/zero create mode 100644 fuzzers/full-system/qemu_linux_kernel/runtime/entrypoint.sh create mode 100644 fuzzers/full-system/qemu_linux_kernel/setup/Makefile create mode 100644 fuzzers/full-system/qemu_linux_kernel/setup/harness.c create mode 100644 fuzzers/full-system/qemu_linux_kernel/setup/setup.sh create mode 100644 fuzzers/full-system/qemu_linux_kernel/setup/user.c create mode 100644 fuzzers/full-system/qemu_linux_kernel/setup/x509-parser.h create mode 100644 fuzzers/full-system/qemu_linux_kernel/src/fuzzer.rs create mode 100644 fuzzers/full-system/qemu_linux_kernel/src/main.rs create mode 100644 fuzzers/full-system/qemu_linux_process/.gitignore create mode 100644 fuzzers/full-system/qemu_linux_process/Cargo.toml create mode 100644 fuzzers/full-system/qemu_linux_process/Makefile.toml create mode 100644 fuzzers/full-system/qemu_linux_process/README.md create mode 100644 fuzzers/full-system/qemu_linux_process/build.rs create mode 100644 fuzzers/full-system/qemu_linux_process/corpus/random create mode 100644 fuzzers/full-system/qemu_linux_process/corpus/zero create mode 100644 fuzzers/full-system/qemu_linux_process/example/harness.c create mode 100644 fuzzers/full-system/qemu_linux_process/runtime/entrypoint.sh create mode 100644 fuzzers/full-system/qemu_linux_process/setup/setup.sh create mode 100644 fuzzers/full-system/qemu_linux_process/src/fuzzer.rs create mode 100644 fuzzers/full-system/qemu_linux_process/src/main.rs rename fuzzers/{others => grammar-aware}/nautilus_sync/.gitignore (100%) rename fuzzers/{others => grammar-aware}/nautilus_sync/Cargo.toml (100%) rename fuzzers/{others => grammar-aware}/nautilus_sync/Makefile.toml (98%) rename fuzzers/{others => grammar-aware}/nautilus_sync/rust-toolchain (100%) rename fuzzers/{others => grammar-aware}/nautilus_sync/src/bin/libafl_cc.rs (100%) rename fuzzers/{fuzzbench/fuzzbench_text => grammar-aware/nautilus_sync}/src/bin/libafl_cxx.rs (100%) rename fuzzers/{others => grammar-aware}/nautilus_sync/src/lib.rs (100%) rename fuzzers/{others => inprocess}/cargo_fuzz/Cargo.toml (100%) rename fuzzers/{others => inprocess}/cargo_fuzz/Makefile.toml (100%) rename fuzzers/{others => inprocess}/cargo_fuzz/README.md (100%) rename fuzzers/{others => inprocess}/cargo_fuzz/fuzz/.gitignore (100%) rename fuzzers/{others => inprocess}/cargo_fuzz/fuzz/Cargo.toml (100%) rename fuzzers/{others => inprocess}/cargo_fuzz/fuzz/fuzz_targets/fuzz_target_1.rs (100%) rename fuzzers/{others => inprocess}/cargo_fuzz/src/lib.rs (100%) rename fuzzers/{others => inprocess}/dynamic_analysis/Cargo.toml (100%) rename fuzzers/{others => inprocess}/dynamic_analysis/Makefile.toml (100%) rename fuzzers/{others => inprocess}/dynamic_analysis/README.md (100%) rename fuzzers/{others => inprocess}/dynamic_analysis/build.rs (100%) rename fuzzers/{others => inprocess}/dynamic_analysis/build.sh (100%) rename fuzzers/{others => inprocess}/dynamic_analysis/clean.sh (100%) rename fuzzers/{others => inprocess}/dynamic_analysis/cms_transform_fuzzer.cc (100%) rename fuzzers/{others => inprocess}/dynamic_analysis/concatenator.py (100%) rename fuzzers/{others => inprocess}/dynamic_analysis/corpus/seed (100%) rename fuzzers/{others => inprocess}/dynamic_analysis/src/bin/libafl_cc.rs (100%) rename fuzzers/{libpng/libfuzzer_libpng => inprocess/dynamic_analysis}/src/bin/libafl_cxx.rs (100%) rename fuzzers/{others => inprocess}/dynamic_analysis/src/lib.rs (100%) rename fuzzers/{fuzzbench/fuzzbench => inprocess/dynamic_analysis}/stub_rt.c (100%) rename fuzzers/{fuzzbench/fuzzbench_forkserver => inprocess/fuzzbench}/.gitignore (100%) rename fuzzers/{fuzzbench => inprocess}/fuzzbench/Cargo.toml (100%) rename fuzzers/{fuzzbench => inprocess}/fuzzbench/Makefile.toml (100%) rename fuzzers/{fuzzbench/fuzzbench_qemu => inprocess/fuzzbench}/README.md (100%) rename fuzzers/{fuzzbench => inprocess}/fuzzbench/fuzz.c (100%) rename fuzzers/{fuzzbench => inprocess}/fuzzbench/src/bin/libafl_cc.rs (100%) rename fuzzers/{libpng/libfuzzer_libpng_accounting => inprocess/fuzzbench}/src/bin/libafl_cxx.rs (100%) rename fuzzers/{fuzzbench => inprocess}/fuzzbench/src/lib.rs (100%) rename fuzzers/{fuzzbench/fuzzbench_ctx => inprocess/fuzzbench}/stub_rt.c (100%) rename fuzzers/{fuzzbench => inprocess}/fuzzbench_ctx/Cargo.toml (100%) rename fuzzers/{fuzzbench => inprocess}/fuzzbench_ctx/Makefile.toml (100%) rename fuzzers/{fuzzbench => inprocess}/fuzzbench_ctx/fuzz.c (100%) rename fuzzers/{fuzzbench => inprocess}/fuzzbench_ctx/src/bin/libafl_cc.rs (100%) rename fuzzers/{libpng/libfuzzer_libpng_centralized => inprocess/fuzzbench_ctx}/src/bin/libafl_cxx.rs (100%) rename fuzzers/{fuzzbench => inprocess}/fuzzbench_ctx/src/lib.rs (100%) rename fuzzers/{others/dynamic_analysis => inprocess/fuzzbench_ctx}/stub_rt.c (100%) rename fuzzers/{fuzzbench => inprocess}/fuzzbench_text/.gitignore (100%) rename fuzzers/{fuzzbench => inprocess}/fuzzbench_text/Cargo.toml (100%) rename fuzzers/{fuzzbench => inprocess}/fuzzbench_text/Makefile.toml (100%) rename fuzzers/{fuzzbench => inprocess}/fuzzbench_text/README.md (100%) rename fuzzers/{fuzzbench => inprocess}/fuzzbench_text/fuzz.c (100%) rename fuzzers/{fuzzbench => inprocess}/fuzzbench_text/src/bin/libafl_cc.rs (100%) rename fuzzers/{libpng/libfuzzer_libpng_cmin => inprocess/fuzzbench_text}/src/bin/libafl_cxx.rs (100%) rename fuzzers/{fuzzbench => inprocess}/fuzzbench_text/src/lib.rs (100%) rename fuzzers/{others => inprocess}/libfuzzer_libmozjpeg/.gitignore (100%) rename fuzzers/{others => inprocess}/libfuzzer_libmozjpeg/Cargo.toml (100%) rename fuzzers/{others => inprocess}/libfuzzer_libmozjpeg/Makefile.toml (100%) rename fuzzers/{others => inprocess}/libfuzzer_libmozjpeg/README.md (100%) rename fuzzers/{others => inprocess}/libfuzzer_libmozjpeg/build.rs (100%) rename fuzzers/{others => inprocess}/libfuzzer_libmozjpeg/corpus/blank.jpg (100%) rename fuzzers/{others => inprocess}/libfuzzer_libmozjpeg/harness.cc (100%) rename fuzzers/{others => inprocess}/libfuzzer_libmozjpeg/hook_allocs.c (100%) rename fuzzers/{others => inprocess}/libfuzzer_libmozjpeg/jpeg.dict (100%) rename fuzzers/{others => inprocess}/libfuzzer_libmozjpeg/src/bin/libafl_cc.rs (100%) rename fuzzers/{libpng/libfuzzer_libpng_launcher => inprocess/libfuzzer_libmozjpeg}/src/bin/libafl_cxx.rs (100%) rename fuzzers/{others => inprocess}/libfuzzer_libmozjpeg/src/lib.rs (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng/.gitignore (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng/Cargo.toml (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng/Makefile.toml (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng/README.md (100%) rename fuzzers/{libpng/libfuzzer_libpng_cmin => inprocess/libfuzzer_libpng}/corpus/not_kitty.png (100%) rename fuzzers/{libpng/libfuzzer_libpng_cmin => inprocess/libfuzzer_libpng}/corpus/not_kitty_alpha.png (100%) rename fuzzers/{libpng/libfuzzer_libpng_cmin => inprocess/libfuzzer_libpng}/corpus/not_kitty_gamma.png (100%) rename fuzzers/{libpng/libfuzzer_libpng_cmin => inprocess/libfuzzer_libpng}/corpus/not_kitty_icc.png (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng/harness.cc (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng/src/bin/libafl_cc.rs (100%) rename fuzzers/{libpng/libfuzzer_libpng_norestart => inprocess/libfuzzer_libpng}/src/bin/libafl_cxx.rs (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng/src/lib.rs (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_accounting/.gitignore (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_accounting/Cargo.toml (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_accounting/Makefile.toml (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_accounting/README.md (100%) rename fuzzers/{libpng/libfuzzer_libpng_launcher => inprocess/libfuzzer_libpng_accounting}/corpus/not_kitty.png (100%) rename fuzzers/{libpng/libfuzzer_libpng_launcher => inprocess/libfuzzer_libpng_accounting}/corpus/not_kitty_alpha.png (100%) rename fuzzers/{libpng/libfuzzer_libpng_launcher => inprocess/libfuzzer_libpng_accounting}/corpus/not_kitty_gamma.png (100%) rename fuzzers/{libpng/libfuzzer_libpng_launcher => inprocess/libfuzzer_libpng_accounting}/corpus/not_kitty_icc.png (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_accounting/harness.cc (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_accounting/src/bin/libafl_cc.rs (100%) rename fuzzers/{libpng/libfuzzer_libpng_tcp_manager => inprocess/libfuzzer_libpng_accounting}/src/bin/libafl_cxx.rs (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_accounting/src/lib.rs (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_centralized/.gitignore (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_centralized/Cargo.toml (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_centralized/Makefile.toml (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_centralized/README.md (100%) rename fuzzers/{libpng/libfuzzer_libpng_norestart/seeds => inprocess/libfuzzer_libpng_centralized/corpus}/not_kitty.png (100%) rename fuzzers/{libpng/libfuzzer_libpng_norestart/seeds => inprocess/libfuzzer_libpng_centralized/corpus}/not_kitty_alpha.png (100%) rename fuzzers/{libpng/libfuzzer_libpng_norestart/seeds => inprocess/libfuzzer_libpng_centralized/corpus}/not_kitty_gamma.png (100%) rename fuzzers/{libpng/libfuzzer_libpng_norestart/seeds => inprocess/libfuzzer_libpng_centralized/corpus}/not_kitty_icc.png (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_centralized/harness.cc (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_centralized/src/bin/libafl_cc.rs (100%) rename fuzzers/{nyx/nyx_libxml2_parallel => inprocess/libfuzzer_libpng_centralized}/src/bin/libafl_cxx.rs (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_centralized/src/lib.rs (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_cmin/.gitignore (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_cmin/Cargo.toml (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_cmin/Makefile.toml (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_cmin/README.md (100%) rename fuzzers/{libpng/libfuzzer_libpng_tcp_manager => inprocess/libfuzzer_libpng_cmin}/corpus/not_kitty.png (100%) rename fuzzers/{libpng/libfuzzer_libpng_tcp_manager => inprocess/libfuzzer_libpng_cmin}/corpus/not_kitty_alpha.png (100%) rename fuzzers/{libpng/libfuzzer_libpng_tcp_manager => inprocess/libfuzzer_libpng_cmin}/corpus/not_kitty_gamma.png (100%) rename fuzzers/{libpng/libfuzzer_libpng_tcp_manager => inprocess/libfuzzer_libpng_cmin}/corpus/not_kitty_icc.png (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_cmin/harness.cc (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_cmin/src/bin/libafl_cc.rs (100%) rename fuzzers/{nyx/nyx_libxml2_standalone => inprocess/libfuzzer_libpng_cmin}/src/bin/libafl_cxx.rs (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_cmin/src/lib.rs (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_launcher/.gitignore (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_launcher/Cargo.toml (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_launcher/Makefile.toml (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_launcher/README.md (100%) rename fuzzers/{qemu/qemu_cmin => inprocess/libfuzzer_libpng_launcher}/corpus/not_kitty.png (100%) rename fuzzers/{qemu/qemu_cmin => inprocess/libfuzzer_libpng_launcher}/corpus/not_kitty_alpha.png (100%) rename fuzzers/{qemu/qemu_cmin => inprocess/libfuzzer_libpng_launcher}/corpus/not_kitty_gamma.png (100%) rename fuzzers/{qemu/qemu_cmin => inprocess/libfuzzer_libpng_launcher}/corpus/not_kitty_icc.png (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_launcher/harness.cc (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_launcher/src/bin/libafl_ar.rs (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_launcher/src/bin/libafl_cc.rs (100%) rename fuzzers/{others/dynamic_analysis => inprocess/libfuzzer_libpng_launcher}/src/bin/libafl_cxx.rs (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_launcher/src/bin/libafl_libtool.rs (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_launcher/src/lib.rs (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_norestart/.gitignore (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_norestart/Cargo.toml (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_norestart/Makefile.toml (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_norestart/README.md (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_norestart/harness.cc (100%) rename fuzzers/{qemu/qemu_coverage/corpus => inprocess/libfuzzer_libpng_norestart/seeds}/not_kitty.png (100%) rename fuzzers/{qemu/qemu_coverage/corpus => inprocess/libfuzzer_libpng_norestart/seeds}/not_kitty_alpha.png (100%) rename fuzzers/{qemu/qemu_coverage/corpus => inprocess/libfuzzer_libpng_norestart/seeds}/not_kitty_gamma.png (100%) rename fuzzers/{qemu/qemu_coverage/corpus => inprocess/libfuzzer_libpng_norestart/seeds}/not_kitty_icc.png (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_norestart/src/bin/libafl_cc.rs (100%) rename fuzzers/{others/libfuzzer_libmozjpeg => inprocess/libfuzzer_libpng_norestart}/src/bin/libafl_cxx.rs (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_norestart/src/lib.rs (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_tcp_manager/.gitignore (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_tcp_manager/Cargo.toml (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_tcp_manager/Makefile.toml (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_tcp_manager/README.md (100%) rename fuzzers/{qemu/qemu_launcher => inprocess/libfuzzer_libpng_tcp_manager}/corpus/not_kitty.png (100%) rename fuzzers/{qemu/qemu_launcher => inprocess/libfuzzer_libpng_tcp_manager}/corpus/not_kitty_alpha.png (100%) rename fuzzers/{qemu/qemu_launcher => inprocess/libfuzzer_libpng_tcp_manager}/corpus/not_kitty_gamma.png (100%) rename fuzzers/{qemu/qemu_launcher => inprocess/libfuzzer_libpng_tcp_manager}/corpus/not_kitty_icc.png (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_tcp_manager/harness.cc (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_tcp_manager/src/bin/libafl_cc.rs (100%) rename fuzzers/{others/nautilus_sync => inprocess/libfuzzer_libpng_tcp_manager}/src/bin/libafl_cxx.rs (100%) rename fuzzers/{libpng => inprocess}/libfuzzer_libpng_tcp_manager/src/lib.rs (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image/.gitignore (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image/Cargo.toml (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image/Makefile.toml (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image/README.md (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image/build.rs (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image/corpus/not_kitty.png (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image/corpus/not_kitty_alpha.png (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image/corpus/not_kitty_gamma.png (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image/corpus/not_kitty_icc.png (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image/harness.c (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image/src/main.rs (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image/stb_image.h (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image_concolic/Makefile.toml (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image_concolic/README.md (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image_concolic/fuzzer/.gitignore (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image_concolic/fuzzer/Cargo.toml (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image_concolic/fuzzer/build.rs (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image_concolic/fuzzer/corpus/not_kitty.png (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image_concolic/fuzzer/corpus/not_kitty_alpha.png (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image_concolic/fuzzer/corpus/not_kitty_gamma.png (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image_concolic/fuzzer/corpus/not_kitty_icc.png (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image_concolic/fuzzer/harness.c (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image_concolic/fuzzer/harness_symcc.c (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image_concolic/fuzzer/src/main.rs (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image_concolic/fuzzer/stb_image.h (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image_concolic/runtime/Cargo.toml (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image_concolic/runtime/src/lib.rs (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image_sugar/.gitignore (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image_sugar/Cargo.toml (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image_sugar/Makefile.toml (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image_sugar/README.md (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image_sugar/build.rs (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image_sugar/corpus/not_kitty.png (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image_sugar/corpus/not_kitty_alpha.png (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image_sugar/corpus/not_kitty_gamma.png (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image_sugar/corpus/not_kitty_icc.png (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image_sugar/harness.c (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image_sugar/src/main.rs (100%) rename fuzzers/{stb => inprocess}/libfuzzer_stb_image_sugar/stb_image.h (100%) rename fuzzers/{others => inprocess}/libfuzzer_windows_asan/.gitignore (100%) rename fuzzers/{others => inprocess}/libfuzzer_windows_asan/Cargo.toml (100%) rename fuzzers/{others => inprocess}/libfuzzer_windows_asan/Makefile.toml (100%) rename fuzzers/{others => inprocess}/libfuzzer_windows_asan/README.md (100%) rename fuzzers/{others => inprocess}/libfuzzer_windows_asan/corpus/hello_world (100%) rename fuzzers/{others => inprocess}/libfuzzer_windows_asan/harness.cpp (100%) rename fuzzers/{others => inprocess}/libfuzzer_windows_asan/src/bin/libafl_cc.rs (100%) rename fuzzers/{others => inprocess}/libfuzzer_windows_asan/src/bin/libafl_cxx.rs (100%) rename fuzzers/{others => inprocess}/libfuzzer_windows_asan/src/lib.rs (100%) rename fuzzers/{others => inprocess}/push_harness/.gitignore (100%) rename fuzzers/{others => inprocess}/push_harness/Cargo.toml (100%) rename fuzzers/{others => inprocess}/push_harness/README.md (100%) rename fuzzers/{others => inprocess}/push_harness/src/main.rs (100%) rename fuzzers/{others => inprocess}/push_stage_harness/.gitignore (100%) rename fuzzers/{others => inprocess}/push_stage_harness/Cargo.toml (100%) rename fuzzers/{others => inprocess}/push_stage_harness/README.md (100%) rename fuzzers/{others => inprocess}/push_stage_harness/src/main.rs (100%) rename fuzzers/{others => inprocess}/sqlite_centralized_multi_machine/Cargo.toml (100%) rename fuzzers/{others => inprocess}/sqlite_centralized_multi_machine/README.md (100%) rename fuzzers/{others => inprocess}/sqlite_centralized_multi_machine/build.sh (100%) rename fuzzers/{others => inprocess}/sqlite_centralized_multi_machine/run_child.sh (100%) rename fuzzers/{others => inprocess}/sqlite_centralized_multi_machine/run_parent.sh (100%) rename fuzzers/{others => inprocess}/sqlite_centralized_multi_machine/src/bin/libafl_cc.rs (100%) rename fuzzers/{others => inprocess}/sqlite_centralized_multi_machine/src/bin/libafl_cxx.rs (100%) rename fuzzers/{others => inprocess}/sqlite_centralized_multi_machine/src/lib.rs (100%) rename fuzzers/{others => inprocess}/tutorial/Cargo.toml (100%) rename fuzzers/{others => inprocess}/tutorial/rust-toolchain (100%) rename fuzzers/{others => inprocess}/tutorial/src/bin/libafl_cc.rs (100%) rename fuzzers/{others => inprocess}/tutorial/src/bin/libafl_cxx.rs (100%) rename fuzzers/{others => inprocess}/tutorial/src/input.rs (100%) rename fuzzers/{others => inprocess}/tutorial/src/lib.rs (100%) rename fuzzers/{others => inprocess}/tutorial/src/metadata.rs (100%) rename fuzzers/{others => inprocess}/tutorial/src/mutator.rs (100%) rename fuzzers/{others => inprocess}/tutorial/target.c (100%) create mode 100644 libafl_qemu/runtime/libafl_qemu_arch.h create mode 100644 libafl_qemu/runtime/libafl_qemu_defs.h create mode 100644 libafl_qemu/runtime/libafl_qemu_impl.h create mode 100755 scripts/gen_stub_bindings.sh diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index daa9211d07..a4a63f0f2f 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -206,7 +206,7 @@ jobs: - name: Run a maturin build run: export LLVM_CONFIG=llvm-config-${{env.MAIN_LLVM_VERSION}} && cd ./bindings/pylibafl && python3 -m venv .env && . .env/bin/activate && pip install --upgrade --force-reinstall . && ./test.sh - name: Run python test - run: . ./bindings/pylibafl/.env/bin/activate # && cd ./fuzzers/qemu/python_qemu/ && python3 fuzzer.py 2>&1 | grep "Bye" + run: . ./bindings/pylibafl/.env/bin/activate # && cd ./fuzzers/binary-only/python_qemu/ && python3 fuzzer.py 2>&1 | grep "Bye" cargo-fmt: runs-on: ubuntu-24.04 @@ -269,55 +269,53 @@ jobs: - ./fuzzers/baby/backtrace_baby_fuzzers/command_executor - ./fuzzers/baby/backtrace_baby_fuzzers/forkserver_executor + # Binary-only + - ./fuzzers/binary-only/fuzzbench_fork_qemu + - ./fuzzers/binary-only/frida_executable_libpng + - ./fuzzers/binary-only/frida_gdiplus + - ./fuzzers/binary-only/frida_libpng + - ./fuzzers/binary-only/fuzzbench_qemu + - ./fuzzers/binary-only/tinyinst_simple + # Forkserver - ./fuzzers/forkserver/forkserver_simple - ./fuzzers/forkserver/forkserver_libafl_cc + - ./fuzzers/forkserver/fuzzbench_forkserver + - ./fuzzers/forkserver/fuzzbench_forkserver_cmplog + - ./fuzzers/forkserver/libafl-fuzz - # Frida - - ./fuzzers/frida/frida_executable_libpng - - ./fuzzers/frida/frida_gdiplus - - ./fuzzers/frida/frida_libpng + # Full-system + - ./fuzzers/full-system/nyx_libxml2_standalone + - ./fuzzers/full-system/nyx_libxml2_parallel - # Fuzzbench - - ./fuzzers/fuzzbench/fuzzbench - - ./fuzzers/fuzzbench/fuzzbench_qemu - - ./fuzzers/fuzzbench/fuzzbench_fork_qemu - - ./fuzzers/fuzzbench/fuzzbench_text - - ./fuzzers/fuzzbench/fuzzbench_ctx - - ./fuzzers/fuzzbench/fuzzbench_forkserver_cmplog - - ./fuzzers/fuzzbench/fuzzbench_forkserver + # Grammar-aware + - ./fuzzers/grammar-aware/nautilus_sync - # LibPNG - - ./fuzzers/libpng/libfuzzer_libpng - - ./fuzzers/libpng/libfuzzer_libpng_launcher - - ./fuzzers/libpng/libfuzzer_libpng_accounting - - ./fuzzers/libpng/libfuzzer_libpng_centralized - - ./fuzzers/libpng/libfuzzer_libpng_cmin - - ./fuzzers/libpng/libfuzzer_libpng_norestart - # - ./fuzzers/libpng/libfuzzer_libpng_tcp_manager - - # Nyx - - ./fuzzers/nyx/nyx_libxml2_standalone - - ./fuzzers/nyx/nyx_libxml2_parallel - - # Stb - - ./fuzzers/stb/libfuzzer_stb_image_sugar - - ./fuzzers/stb/libfuzzer_stb_image - # - ./fuzzers/stb/libfuzzer_stb_image_concolic + # In-process + - ./fuzzers/inprocess/cargo_fuzz + # - ./fuzzers/inprocess/dynamic_analysis + - ./fuzzers/inprocess/fuzzbench + - ./fuzzers/inprocess/fuzzbench_text + - ./fuzzers/inprocess/fuzzbench_ctx + - ./fuzzers/inprocess/libfuzzer_libmozjpeg + - ./fuzzers/inprocess/libfuzzer_libpng + - ./fuzzers/inprocess/libfuzzer_libpng_launcher + - ./fuzzers/inprocess/libfuzzer_libpng_accounting + - ./fuzzers/inprocess/libfuzzer_libpng_centralized + - ./fuzzers/inprocess/libfuzzer_libpng_cmin + - ./fuzzers/inprocess/libfuzzer_libpng_norestart + # - ./fuzzers/inprocess/libfuzzer_libpng_tcp_manager + - ./fuzzers/inprocess/libfuzzer_stb_image_sugar + - ./fuzzers/inprocess/libfuzzer_stb_image + # - ./fuzzers/inprocess/libfuzzer_stb_image_concolic + # - ./fuzzers/inprocess/libfuzzer_windows_asan + - ./fuzzers/inprocess/push_harness + - ./fuzzers/inprocess/push_stage_harness + # - ./fuzzers/inprocess/sqlite_centralized_multi_machine + - ./fuzzers/inprocess/tutorial # Others - - ./fuzzers/others/cargo_fuzz - # - ./fuzzers/others/dynamic_analysis - ./fuzzers/others/libafl_atheris - - ./fuzzers/others/libafl-fuzz - - ./fuzzers/others/libfuzzer_libmozjpeg - # - ./fuzzers/others/libfuzzer_windows_asan - - ./fuzzers/others/nautilus_sync - - ./fuzzers/others/push_harness - - ./fuzzers/others/push_stage_harness - # - ./fuzzers/others/sqlite_centralized_multi_machine - - ./fuzzers/others/tinyinst_simple - - ./fuzzers/others/tutorial runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 @@ -356,10 +354,15 @@ jobs: matrix: os: [ubuntu-24.04] fuzzer: - - ./fuzzers/qemu/qemu_cmin - - ./fuzzers/qemu/qemu_systemmode - - ./fuzzers/qemu/qemu_coverage - - ./fuzzers/qemu/qemu_launcher + # Binary only + - ./fuzzers/binary-only/qemu_cmin + - ./fuzzers/binary-only/qemu_coverage + - ./fuzzers/binary-only/qemu_launcher + + # Full-system + - ./fuzzers/full-system/qemu_baremetal + # - ./fuzzers/full-system/qemu_linux_kernel + #- ./fuzzers/full-system/qemu_linux_process runs-on: [ self-hosted, qemu ] container: registry.gitlab.com/qemu-project/qemu/qemu/ubuntu2204:latest @@ -426,8 +429,8 @@ jobs: steps: - uses: actions/checkout@v4 - uses: ./.github/workflows/windows-tester-prepare - - name: Build fuzzers/frida_libpng - run: cd fuzzers/frida/frida_libpng/ && cargo make test + - name: Build fuzzers/binary-only/frida_libpng + run: cd fuzzers/binary-only/frida_libpng/ && cargo make test windows-frida-libfuzzer-stb-image: runs-on: windows-latest @@ -436,8 +439,8 @@ jobs: steps: - uses: actions/checkout@v4 - uses: ./.github/workflows/windows-tester-prepare - - name: Build fuzzers/stb/libfuzzer_stb_image - run: cd fuzzers/stb/libfuzzer_stb_image && cargo build --release + - name: Build fuzzers/inprocess/libfuzzer_stb_image + run: cd fuzzers/inprocess/libfuzzer_stb_image && cargo build --release windows-frida-gdiplus: runs-on: windows-latest @@ -446,8 +449,8 @@ jobs: steps: - uses: actions/checkout@v4 - uses: ./.github/workflows/windows-tester-prepare - - name: Build fuzzers/frida/frida_gdiplus - run: cd fuzzers/frida/frida_gdiplus/ && cargo make test && cargo make test_cmplog + - name: Build fuzzers/binary-only/frida_gdiplus + run: cd fuzzers/binary-only/frida_gdiplus/ && cargo make test && cargo make test_cmplog windows-tinyinst-simple: runs-on: windows-latest @@ -458,8 +461,8 @@ jobs: run: cargo install cxxbridge-cmd - uses: actions/checkout@v4 - uses: ./.github/workflows/windows-tester-prepare - - name: Build fuzzers/others/tinyinst_simple - run: cd fuzzers/others/tinyinst_simple/ && cargo make test + - name: Build fuzzers/binary-only/tinyinst_simple + run: cd fuzzers/binary-only/tinyinst_simple/ && cargo make test windows-clippy: runs-on: windows-latest diff --git a/.github/workflows/md-config.json b/.github/workflows/md-config.json index 3ec0ece19b..ae7e387a29 100644 --- a/.github/workflows/md-config.json +++ b/.github/workflows/md-config.json @@ -2,6 +2,9 @@ "ignorePatterns": [ { "pattern": "^https://crates.io" + }, + { + "pattern": "^https://github.com/AFLplusplus/linux-qemu-image-builder" } ], "aliveStatusCodes": [0, 200, 403] diff --git a/README.md b/README.md index e382d10682..72f6926755 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ cargo make run as long as the fuzzer directory has `Makefile.toml` file. -The best-tested fuzzer is [`./fuzzers/libpng/libfuzzer_libpng`](./fuzzers/libpng/libfuzzer_libpng), a multicore libfuzzer-like fuzzer using LibAFL for a libpng harness. +The best-tested fuzzer is [`./fuzzers/inprocess/libfuzzer_libpng`](./fuzzers/inprocess/libfuzzer_libpng), a multicore libfuzzer-like fuzzer using LibAFL for a libpng harness. ## Resources diff --git a/fuzzers/README.md b/fuzzers/README.md index 3971102fad..3224a27648 100644 --- a/fuzzers/README.md +++ b/fuzzers/README.md @@ -6,18 +6,17 @@ You can find here all the example fuzzers built on top of LibAFL. They are sorted by fuzzer types: - `baby`: Minimal fuzzers demonstrating a specific feature. +- `binary-only`: Fuzzers for binary-only targets. - `forkserver`: Fuzzers using a forkserver-style executor. -- `frida`: Fuzzers using [Frida](../libafl_frida). +- `full-system`: Fuzzers for full-system targets (kernels, firmwares, etc...). - `fuzzbench`: Fuzzbench fuzzers. -- `libpng`: Fuzzers targeting libpng. -- `nyx`: Fuzzers based on [Nyx](../libafl_nyx). -- `others`: Various fuzzers, with no specific categories. -- `qemu`: Fuzzers using [Qemu](../libafl_qemu). -- `stb`: Fuzzers targeting stb. +- `grammar-aware`: Grammar-aware fuzzers. +- `inprocess`: In-process fuzzers, whn they don't fit another more specific type. +- `others`: Fuzzers for specific / specialized things, that do not go in a specific category. ## Paper Artifacts -Multiple papers based on LibAFL have been published alongside artifacts. +Multiple papers based on LibAFL have been published and include artifacts. Here is a list of LibAFL artifacts: - Fuzzbench implementation: https://github.com/AFLplusplus/libafl_fuzzbench diff --git a/fuzzers/frida/frida_executable_libpng/.gitignore b/fuzzers/binary-only/frida_executable_libpng/.gitignore similarity index 100% rename from fuzzers/frida/frida_executable_libpng/.gitignore rename to fuzzers/binary-only/frida_executable_libpng/.gitignore diff --git a/fuzzers/frida/frida_executable_libpng/Cargo.toml b/fuzzers/binary-only/frida_executable_libpng/Cargo.toml similarity index 100% rename from fuzzers/frida/frida_executable_libpng/Cargo.toml rename to fuzzers/binary-only/frida_executable_libpng/Cargo.toml diff --git a/fuzzers/frida/frida_executable_libpng/Makefile.toml b/fuzzers/binary-only/frida_executable_libpng/Makefile.toml similarity index 100% rename from fuzzers/frida/frida_executable_libpng/Makefile.toml rename to fuzzers/binary-only/frida_executable_libpng/Makefile.toml diff --git a/fuzzers/frida/frida_executable_libpng/README.md b/fuzzers/binary-only/frida_executable_libpng/README.md similarity index 100% rename from fuzzers/frida/frida_executable_libpng/README.md rename to fuzzers/binary-only/frida_executable_libpng/README.md diff --git a/fuzzers/frida/frida_executable_libpng/corpus/not_kitty.png b/fuzzers/binary-only/frida_executable_libpng/corpus/not_kitty.png similarity index 100% rename from fuzzers/frida/frida_executable_libpng/corpus/not_kitty.png rename to fuzzers/binary-only/frida_executable_libpng/corpus/not_kitty.png diff --git a/fuzzers/frida/frida_executable_libpng/corpus/not_kitty_alpha.png b/fuzzers/binary-only/frida_executable_libpng/corpus/not_kitty_alpha.png similarity index 100% rename from fuzzers/frida/frida_executable_libpng/corpus/not_kitty_alpha.png rename to fuzzers/binary-only/frida_executable_libpng/corpus/not_kitty_alpha.png diff --git a/fuzzers/frida/frida_executable_libpng/corpus/not_kitty_gamma.png b/fuzzers/binary-only/frida_executable_libpng/corpus/not_kitty_gamma.png similarity index 100% rename from fuzzers/frida/frida_executable_libpng/corpus/not_kitty_gamma.png rename to fuzzers/binary-only/frida_executable_libpng/corpus/not_kitty_gamma.png diff --git a/fuzzers/frida/frida_executable_libpng/corpus/not_kitty_icc.png b/fuzzers/binary-only/frida_executable_libpng/corpus/not_kitty_icc.png similarity index 100% rename from fuzzers/frida/frida_executable_libpng/corpus/not_kitty_icc.png rename to fuzzers/binary-only/frida_executable_libpng/corpus/not_kitty_icc.png diff --git a/fuzzers/frida/frida_executable_libpng/harness.cc b/fuzzers/binary-only/frida_executable_libpng/harness.cc similarity index 100% rename from fuzzers/frida/frida_executable_libpng/harness.cc rename to fuzzers/binary-only/frida_executable_libpng/harness.cc diff --git a/fuzzers/frida/frida_executable_libpng/src/fuzzer.rs b/fuzzers/binary-only/frida_executable_libpng/src/fuzzer.rs similarity index 100% rename from fuzzers/frida/frida_executable_libpng/src/fuzzer.rs rename to fuzzers/binary-only/frida_executable_libpng/src/fuzzer.rs diff --git a/fuzzers/frida/frida_executable_libpng/src/lib.rs b/fuzzers/binary-only/frida_executable_libpng/src/lib.rs similarity index 100% rename from fuzzers/frida/frida_executable_libpng/src/lib.rs rename to fuzzers/binary-only/frida_executable_libpng/src/lib.rs diff --git a/fuzzers/frida/frida_gdiplus/.gitignore b/fuzzers/binary-only/frida_gdiplus/.gitignore similarity index 100% rename from fuzzers/frida/frida_gdiplus/.gitignore rename to fuzzers/binary-only/frida_gdiplus/.gitignore diff --git a/fuzzers/frida/frida_gdiplus/Cargo.toml b/fuzzers/binary-only/frida_gdiplus/Cargo.toml similarity index 100% rename from fuzzers/frida/frida_gdiplus/Cargo.toml rename to fuzzers/binary-only/frida_gdiplus/Cargo.toml diff --git a/fuzzers/frida/frida_gdiplus/Makefile.toml b/fuzzers/binary-only/frida_gdiplus/Makefile.toml similarity index 100% rename from fuzzers/frida/frida_gdiplus/Makefile.toml rename to fuzzers/binary-only/frida_gdiplus/Makefile.toml diff --git a/fuzzers/frida/frida_gdiplus/README.md b/fuzzers/binary-only/frida_gdiplus/README.md similarity index 100% rename from fuzzers/frida/frida_gdiplus/README.md rename to fuzzers/binary-only/frida_gdiplus/README.md diff --git a/fuzzers/frida/frida_gdiplus/cargo/.config b/fuzzers/binary-only/frida_gdiplus/cargo/.config similarity index 100% rename from fuzzers/frida/frida_gdiplus/cargo/.config rename to fuzzers/binary-only/frida_gdiplus/cargo/.config diff --git a/fuzzers/frida/frida_gdiplus/cmplog_test.asm b/fuzzers/binary-only/frida_gdiplus/cmplog_test.asm similarity index 100% rename from fuzzers/frida/frida_gdiplus/cmplog_test.asm rename to fuzzers/binary-only/frida_gdiplus/cmplog_test.asm diff --git a/fuzzers/frida/frida_gdiplus/cmplog_test.def b/fuzzers/binary-only/frida_gdiplus/cmplog_test.def similarity index 100% rename from fuzzers/frida/frida_gdiplus/cmplog_test.def rename to fuzzers/binary-only/frida_gdiplus/cmplog_test.def diff --git a/fuzzers/frida/frida_gdiplus/corpus/not_kitty.png b/fuzzers/binary-only/frida_gdiplus/corpus/not_kitty.png similarity index 100% rename from fuzzers/frida/frida_gdiplus/corpus/not_kitty.png rename to fuzzers/binary-only/frida_gdiplus/corpus/not_kitty.png diff --git a/fuzzers/frida/frida_gdiplus/corpus/not_kitty_alpha.png b/fuzzers/binary-only/frida_gdiplus/corpus/not_kitty_alpha.png similarity index 100% rename from fuzzers/frida/frida_gdiplus/corpus/not_kitty_alpha.png rename to fuzzers/binary-only/frida_gdiplus/corpus/not_kitty_alpha.png diff --git a/fuzzers/frida/frida_gdiplus/corpus/not_kitty_gamma.png b/fuzzers/binary-only/frida_gdiplus/corpus/not_kitty_gamma.png similarity index 100% rename from fuzzers/frida/frida_gdiplus/corpus/not_kitty_gamma.png rename to fuzzers/binary-only/frida_gdiplus/corpus/not_kitty_gamma.png diff --git a/fuzzers/frida/frida_gdiplus/corpus/not_kitty_icc.png b/fuzzers/binary-only/frida_gdiplus/corpus/not_kitty_icc.png similarity index 100% rename from fuzzers/frida/frida_gdiplus/corpus/not_kitty_icc.png rename to fuzzers/binary-only/frida_gdiplus/corpus/not_kitty_icc.png diff --git a/fuzzers/frida/frida_gdiplus/harness.cc b/fuzzers/binary-only/frida_gdiplus/harness.cc similarity index 100% rename from fuzzers/frida/frida_gdiplus/harness.cc rename to fuzzers/binary-only/frida_gdiplus/harness.cc diff --git a/fuzzers/frida/frida_gdiplus/src/fuzzer.rs b/fuzzers/binary-only/frida_gdiplus/src/fuzzer.rs similarity index 100% rename from fuzzers/frida/frida_gdiplus/src/fuzzer.rs rename to fuzzers/binary-only/frida_gdiplus/src/fuzzer.rs diff --git a/fuzzers/frida/frida_gdiplus/src/main.rs b/fuzzers/binary-only/frida_gdiplus/src/main.rs similarity index 100% rename from fuzzers/frida/frida_gdiplus/src/main.rs rename to fuzzers/binary-only/frida_gdiplus/src/main.rs diff --git a/fuzzers/frida/frida_libpng/.gitignore b/fuzzers/binary-only/frida_libpng/.gitignore similarity index 100% rename from fuzzers/frida/frida_libpng/.gitignore rename to fuzzers/binary-only/frida_libpng/.gitignore diff --git a/fuzzers/frida/frida_libpng/Cargo.toml b/fuzzers/binary-only/frida_libpng/Cargo.toml similarity index 100% rename from fuzzers/frida/frida_libpng/Cargo.toml rename to fuzzers/binary-only/frida_libpng/Cargo.toml diff --git a/fuzzers/frida/frida_libpng/Makefile.toml b/fuzzers/binary-only/frida_libpng/Makefile.toml similarity index 100% rename from fuzzers/frida/frida_libpng/Makefile.toml rename to fuzzers/binary-only/frida_libpng/Makefile.toml diff --git a/fuzzers/frida/frida_libpng/README.md b/fuzzers/binary-only/frida_libpng/README.md similarity index 100% rename from fuzzers/frida/frida_libpng/README.md rename to fuzzers/binary-only/frida_libpng/README.md diff --git a/fuzzers/frida/frida_libpng/corpus/not_kitty.png b/fuzzers/binary-only/frida_libpng/corpus/not_kitty.png similarity index 100% rename from fuzzers/frida/frida_libpng/corpus/not_kitty.png rename to fuzzers/binary-only/frida_libpng/corpus/not_kitty.png diff --git a/fuzzers/frida/frida_libpng/corpus/not_kitty_alpha.png b/fuzzers/binary-only/frida_libpng/corpus/not_kitty_alpha.png similarity index 100% rename from fuzzers/frida/frida_libpng/corpus/not_kitty_alpha.png rename to fuzzers/binary-only/frida_libpng/corpus/not_kitty_alpha.png diff --git a/fuzzers/frida/frida_libpng/corpus/not_kitty_gamma.png b/fuzzers/binary-only/frida_libpng/corpus/not_kitty_gamma.png similarity index 100% rename from fuzzers/frida/frida_libpng/corpus/not_kitty_gamma.png rename to fuzzers/binary-only/frida_libpng/corpus/not_kitty_gamma.png diff --git a/fuzzers/frida/frida_libpng/corpus/not_kitty_icc.png b/fuzzers/binary-only/frida_libpng/corpus/not_kitty_icc.png similarity index 100% rename from fuzzers/frida/frida_libpng/corpus/not_kitty_icc.png rename to fuzzers/binary-only/frida_libpng/corpus/not_kitty_icc.png diff --git a/fuzzers/frida/frida_libpng/harness.cc b/fuzzers/binary-only/frida_libpng/harness.cc similarity index 100% rename from fuzzers/frida/frida_libpng/harness.cc rename to fuzzers/binary-only/frida_libpng/harness.cc diff --git a/fuzzers/frida/frida_libpng/harness_win.cpp b/fuzzers/binary-only/frida_libpng/harness_win.cpp similarity index 100% rename from fuzzers/frida/frida_libpng/harness_win.cpp rename to fuzzers/binary-only/frida_libpng/harness_win.cpp diff --git a/fuzzers/frida/frida_libpng/src/fuzzer.rs b/fuzzers/binary-only/frida_libpng/src/fuzzer.rs similarity index 100% rename from fuzzers/frida/frida_libpng/src/fuzzer.rs rename to fuzzers/binary-only/frida_libpng/src/fuzzer.rs diff --git a/fuzzers/frida/frida_libpng/src/main.rs b/fuzzers/binary-only/frida_libpng/src/main.rs similarity index 100% rename from fuzzers/frida/frida_libpng/src/main.rs rename to fuzzers/binary-only/frida_libpng/src/main.rs diff --git a/fuzzers/fuzzbench/fuzzbench_fork_qemu/.gitignore b/fuzzers/binary-only/fuzzbench_fork_qemu/.gitignore similarity index 100% rename from fuzzers/fuzzbench/fuzzbench_fork_qemu/.gitignore rename to fuzzers/binary-only/fuzzbench_fork_qemu/.gitignore diff --git a/fuzzers/fuzzbench/fuzzbench_fork_qemu/Cargo.toml b/fuzzers/binary-only/fuzzbench_fork_qemu/Cargo.toml similarity index 100% rename from fuzzers/fuzzbench/fuzzbench_fork_qemu/Cargo.toml rename to fuzzers/binary-only/fuzzbench_fork_qemu/Cargo.toml diff --git a/fuzzers/fuzzbench/fuzzbench_fork_qemu/Makefile.toml b/fuzzers/binary-only/fuzzbench_fork_qemu/Makefile.toml similarity index 97% rename from fuzzers/fuzzbench/fuzzbench_fork_qemu/Makefile.toml rename to fuzzers/binary-only/fuzzbench_fork_qemu/Makefile.toml index b5c4a904a0..228e7bfca0 100644 --- a/fuzzers/fuzzbench/fuzzbench_fork_qemu/Makefile.toml +++ b/fuzzers/binary-only/fuzzbench_fork_qemu/Makefile.toml @@ -52,7 +52,7 @@ make -C libpng-1.6.37 cc -c "${PROJECT_DIR}/libfuzzer_main.c" # Build the libpng harness c++ \ - ../../libpng/libfuzzer_libpng/harness.cc \ + ../../inprocess/libfuzzer_libpng/harness.cc \ ./libpng-1.6.37/.libs/libpng16.a \ ./libfuzzer_main.o \ -I./libpng-1.6.37/ \ diff --git a/fuzzers/fuzzbench/fuzzbench_fork_qemu/libfuzzer_main.c b/fuzzers/binary-only/fuzzbench_fork_qemu/libfuzzer_main.c similarity index 100% rename from fuzzers/fuzzbench/fuzzbench_fork_qemu/libfuzzer_main.c rename to fuzzers/binary-only/fuzzbench_fork_qemu/libfuzzer_main.c diff --git a/fuzzers/fuzzbench/fuzzbench_fork_qemu/src/fuzzer.rs b/fuzzers/binary-only/fuzzbench_fork_qemu/src/fuzzer.rs similarity index 98% rename from fuzzers/fuzzbench/fuzzbench_fork_qemu/src/fuzzer.rs rename to fuzzers/binary-only/fuzzbench_fork_qemu/src/fuzzer.rs index 12cfae19f4..31f15b217d 100644 --- a/fuzzers/fuzzbench/fuzzbench_fork_qemu/src/fuzzer.rs +++ b/fuzzers/binary-only/fuzzbench_fork_qemu/src/fuzzer.rs @@ -50,7 +50,7 @@ use libafl_qemu::{ filter_qemu_args, modules::{ cmplog::{CmpLogChildModule, CmpLogMap, CmpLogObserver}, - edges::{EdgeCoverageChildModule, EDGES_MAP_PTR, EDGES_MAP_SIZE_IN_USE}, + edges::{StdEdgeCoverageChildModule, EDGES_MAP_PTR, EDGES_MAP_SIZE_IN_USE}, }, Emulator, GuestReg, MmapPerms, QemuExitError, QemuExitReason, QemuForkExecutor, QemuShutdownCause, Regs, @@ -151,7 +151,7 @@ fn fuzz( let env: Vec<(String, String)> = env::vars().collect(); let emulator_modules = tuple_list!( - EdgeCoverageChildModule::default(), + StdEdgeCoverageChildModule::builder().build(), CmpLogChildModule::default(), ); diff --git a/fuzzers/fuzzbench/fuzzbench_fork_qemu/src/main.rs b/fuzzers/binary-only/fuzzbench_fork_qemu/src/main.rs similarity index 100% rename from fuzzers/fuzzbench/fuzzbench_fork_qemu/src/main.rs rename to fuzzers/binary-only/fuzzbench_fork_qemu/src/main.rs diff --git a/fuzzers/fuzzbench/fuzzbench_qemu/.gitignore b/fuzzers/binary-only/fuzzbench_qemu/.gitignore similarity index 100% rename from fuzzers/fuzzbench/fuzzbench_qemu/.gitignore rename to fuzzers/binary-only/fuzzbench_qemu/.gitignore diff --git a/fuzzers/fuzzbench/fuzzbench_qemu/Cargo.toml b/fuzzers/binary-only/fuzzbench_qemu/Cargo.toml similarity index 100% rename from fuzzers/fuzzbench/fuzzbench_qemu/Cargo.toml rename to fuzzers/binary-only/fuzzbench_qemu/Cargo.toml diff --git a/fuzzers/fuzzbench/fuzzbench_qemu/Makefile.toml b/fuzzers/binary-only/fuzzbench_qemu/Makefile.toml similarity index 96% rename from fuzzers/fuzzbench/fuzzbench_qemu/Makefile.toml rename to fuzzers/binary-only/fuzzbench_qemu/Makefile.toml index b1b5f80196..20dc7fe165 100644 --- a/fuzzers/fuzzbench/fuzzbench_qemu/Makefile.toml +++ b/fuzzers/binary-only/fuzzbench_qemu/Makefile.toml @@ -52,7 +52,7 @@ make -C libpng-1.6.37 cc -c "${PROJECT_DIR}/libfuzzer_main.c" # Build the libpng harness c++ \ - ../../libpng/libfuzzer_libpng/harness.cc \ + ../../inprocess/libfuzzer_libpng/harness.cc \ ./libpng-1.6.37/.libs/libpng16.a \ ./libfuzzer_main.o \ -I./libpng-1.6.37/ \ @@ -76,7 +76,7 @@ args = [ "./${FUZZER_NAME}", "--", "--libafl-in", - "../../libpng/libfuzzer_libpng/corpus", + "../../inprocess/libfuzzer_libpng/corpus", "--libafl-out", "./out", "./${FUZZER_NAME}", diff --git a/fuzzers/fuzzbench/fuzzbench/README.md b/fuzzers/binary-only/fuzzbench_qemu/README.md similarity index 100% rename from fuzzers/fuzzbench/fuzzbench/README.md rename to fuzzers/binary-only/fuzzbench_qemu/README.md diff --git a/fuzzers/fuzzbench/fuzzbench_qemu/libfuzzer_main.c b/fuzzers/binary-only/fuzzbench_qemu/libfuzzer_main.c similarity index 100% rename from fuzzers/fuzzbench/fuzzbench_qemu/libfuzzer_main.c rename to fuzzers/binary-only/fuzzbench_qemu/libfuzzer_main.c diff --git a/fuzzers/fuzzbench/fuzzbench_qemu/src/fuzzer.rs b/fuzzers/binary-only/fuzzbench_qemu/src/fuzzer.rs similarity index 90% rename from fuzzers/fuzzbench/fuzzbench_qemu/src/fuzzer.rs rename to fuzzers/binary-only/fuzzbench_qemu/src/fuzzer.rs index 919d9c8111..3ab7a5b484 100644 --- a/fuzzers/fuzzbench/fuzzbench_qemu/src/fuzzer.rs +++ b/fuzzers/binary-only/fuzzbench_qemu/src/fuzzer.rs @@ -51,7 +51,7 @@ use libafl_qemu::{ // asan::{init_with_asan, QemuAsanHelper}, modules::cmplog::{CmpLogModule, CmpLogObserver}, modules::edges::{ - edges_map_mut_ptr, EdgeCoverageModule, EDGES_MAP_SIZE_IN_USE, MAX_EDGES_FOUND, + edges_map_mut_ptr, StdEdgeCoverageModule, EDGES_MAP_SIZE_IN_USE, MAX_EDGES_FOUND, }, Emulator, GuestReg, @@ -326,38 +326,39 @@ fn fuzz( let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); // The wrapped harness function, calling out to the LLVM-style harness - let mut harness = |_emulator: &mut Emulator<_, _, _, _, _>, input: &BytesInput| { - let target = input.target_bytes(); - let mut buf = target.as_slice(); - let mut len = buf.len(); - if len > MAX_INPUT_SIZE { - buf = &buf[0..MAX_INPUT_SIZE]; - len = MAX_INPUT_SIZE; - } - - unsafe { - qemu.write_mem(input_addr, buf); - - qemu.write_reg(Regs::Rdi, input_addr).unwrap(); - qemu.write_reg(Regs::Rsi, len as GuestReg).unwrap(); - qemu.write_reg(Regs::Rip, test_one_input_ptr).unwrap(); - qemu.write_reg(Regs::Rsp, stack_ptr).unwrap(); - - match qemu.run() { - Ok(QemuExitReason::Breakpoint(_)) => {} - Ok(QemuExitReason::End(QemuShutdownCause::HostSignal(Signal::SigInterrupt))) => { - process::exit(0) - } - Err(QemuExitError::UnexpectedExit) => return ExitKind::Crash, - _ => panic!("Unexpected QEMU exit."), + let mut harness = + |_emulator: &mut Emulator<_, _, _, _, _>, _state: &mut _, input: &BytesInput| { + let target = input.target_bytes(); + let mut buf = target.as_slice(); + let mut len = buf.len(); + if len > MAX_INPUT_SIZE { + buf = &buf[0..MAX_INPUT_SIZE]; + len = MAX_INPUT_SIZE; } - } - ExitKind::Ok - }; + unsafe { + qemu.write_mem(input_addr, buf); + + qemu.write_reg(Regs::Rdi, input_addr).unwrap(); + qemu.write_reg(Regs::Rsi, len as GuestReg).unwrap(); + qemu.write_reg(Regs::Rip, test_one_input_ptr).unwrap(); + qemu.write_reg(Regs::Rsp, stack_ptr).unwrap(); + + match qemu.run() { + Ok(QemuExitReason::Breakpoint(_)) => {} + Ok(QemuExitReason::End(QemuShutdownCause::HostSignal( + Signal::SigInterrupt, + ))) => process::exit(0), + Err(QemuExitError::UnexpectedExit) => return ExitKind::Crash, + _ => panic!("Unexpected QEMU exit."), + } + } + + ExitKind::Ok + }; let modules = tuple_list!( - EdgeCoverageModule::default(), + StdEdgeCoverageModule::builder().build(), CmpLogModule::default(), // QemuAsanHelper::default(asan), //QemuSnapshotHelper::new() diff --git a/fuzzers/fuzzbench/fuzzbench_qemu/src/main.rs b/fuzzers/binary-only/fuzzbench_qemu/src/main.rs similarity index 100% rename from fuzzers/fuzzbench/fuzzbench_qemu/src/main.rs rename to fuzzers/binary-only/fuzzbench_qemu/src/main.rs diff --git a/fuzzers/qemu/python_qemu/README.md b/fuzzers/binary-only/python_qemu/README.md similarity index 100% rename from fuzzers/qemu/python_qemu/README.md rename to fuzzers/binary-only/python_qemu/README.md diff --git a/fuzzers/qemu/python_qemu/fuzz.c b/fuzzers/binary-only/python_qemu/fuzz.c similarity index 100% rename from fuzzers/qemu/python_qemu/fuzz.c rename to fuzzers/binary-only/python_qemu/fuzz.c diff --git a/fuzzers/qemu/python_qemu/fuzzer.py b/fuzzers/binary-only/python_qemu/fuzzer.py similarity index 100% rename from fuzzers/qemu/python_qemu/fuzzer.py rename to fuzzers/binary-only/python_qemu/fuzzer.py diff --git a/fuzzers/qemu/qemu_cmin/.gitignore b/fuzzers/binary-only/qemu_cmin/.gitignore similarity index 100% rename from fuzzers/qemu/qemu_cmin/.gitignore rename to fuzzers/binary-only/qemu_cmin/.gitignore diff --git a/fuzzers/qemu/qemu_cmin/Cargo.toml b/fuzzers/binary-only/qemu_cmin/Cargo.toml similarity index 100% rename from fuzzers/qemu/qemu_cmin/Cargo.toml rename to fuzzers/binary-only/qemu_cmin/Cargo.toml diff --git a/fuzzers/qemu/qemu_cmin/Makefile.toml b/fuzzers/binary-only/qemu_cmin/Makefile.toml similarity index 100% rename from fuzzers/qemu/qemu_cmin/Makefile.toml rename to fuzzers/binary-only/qemu_cmin/Makefile.toml diff --git a/fuzzers/qemu/qemu_cmin/README.md b/fuzzers/binary-only/qemu_cmin/README.md similarity index 100% rename from fuzzers/qemu/qemu_cmin/README.md rename to fuzzers/binary-only/qemu_cmin/README.md diff --git a/fuzzers/qemu/qemu_cmin/build.rs b/fuzzers/binary-only/qemu_cmin/build.rs similarity index 100% rename from fuzzers/qemu/qemu_cmin/build.rs rename to fuzzers/binary-only/qemu_cmin/build.rs diff --git a/fuzzers/libpng/libfuzzer_libpng/corpus/not_kitty.png b/fuzzers/binary-only/qemu_cmin/corpus/not_kitty.png similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng/corpus/not_kitty.png rename to fuzzers/binary-only/qemu_cmin/corpus/not_kitty.png diff --git a/fuzzers/libpng/libfuzzer_libpng/corpus/not_kitty_alpha.png b/fuzzers/binary-only/qemu_cmin/corpus/not_kitty_alpha.png similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng/corpus/not_kitty_alpha.png rename to fuzzers/binary-only/qemu_cmin/corpus/not_kitty_alpha.png diff --git a/fuzzers/libpng/libfuzzer_libpng/corpus/not_kitty_gamma.png b/fuzzers/binary-only/qemu_cmin/corpus/not_kitty_gamma.png similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng/corpus/not_kitty_gamma.png rename to fuzzers/binary-only/qemu_cmin/corpus/not_kitty_gamma.png diff --git a/fuzzers/libpng/libfuzzer_libpng/corpus/not_kitty_icc.png b/fuzzers/binary-only/qemu_cmin/corpus/not_kitty_icc.png similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng/corpus/not_kitty_icc.png rename to fuzzers/binary-only/qemu_cmin/corpus/not_kitty_icc.png diff --git a/fuzzers/qemu/qemu_cmin/harness.cc b/fuzzers/binary-only/qemu_cmin/harness.cc similarity index 100% rename from fuzzers/qemu/qemu_cmin/harness.cc rename to fuzzers/binary-only/qemu_cmin/harness.cc diff --git a/fuzzers/qemu/qemu_cmin/src/fuzzer.rs b/fuzzers/binary-only/qemu_cmin/src/fuzzer.rs similarity index 97% rename from fuzzers/qemu/qemu_cmin/src/fuzzer.rs rename to fuzzers/binary-only/qemu_cmin/src/fuzzer.rs index 4c1517450a..0928835c1e 100644 --- a/fuzzers/qemu/qemu_cmin/src/fuzzer.rs +++ b/fuzzers/binary-only/qemu_cmin/src/fuzzer.rs @@ -28,7 +28,7 @@ use libafl_bolts::{ }; use libafl_qemu::{ elf::EasyElf, - modules::edges::{EdgeCoverageChildModule, EDGES_MAP_PTR, EDGES_MAP_SIZE_IN_USE}, + modules::edges::{StdEdgeCoverageChildModule, EDGES_MAP_PTR, EDGES_MAP_SIZE_IN_USE}, ArchExtras, CallingConvention, Emulator, GuestAddr, GuestReg, MmapPerms, Qemu, QemuExitError, QemuExitReason, QemuForkExecutor, QemuShutdownCause, Regs, }; @@ -218,7 +218,7 @@ pub fn fuzz() -> Result<(), Error> { ExitKind::Ok }; - let modules = tuple_list!(EdgeCoverageChildModule::default(),); + let modules = tuple_list!(StdEdgeCoverageChildModule::builder().build()); let emulator = Emulator::empty().qemu(qemu).modules(modules).build()?; diff --git a/fuzzers/qemu/qemu_cmin/src/main.rs b/fuzzers/binary-only/qemu_cmin/src/main.rs similarity index 100% rename from fuzzers/qemu/qemu_cmin/src/main.rs rename to fuzzers/binary-only/qemu_cmin/src/main.rs diff --git a/fuzzers/qemu/qemu_coverage/.gitignore b/fuzzers/binary-only/qemu_coverage/.gitignore similarity index 100% rename from fuzzers/qemu/qemu_coverage/.gitignore rename to fuzzers/binary-only/qemu_coverage/.gitignore diff --git a/fuzzers/qemu/qemu_coverage/Cargo.toml b/fuzzers/binary-only/qemu_coverage/Cargo.toml similarity index 100% rename from fuzzers/qemu/qemu_coverage/Cargo.toml rename to fuzzers/binary-only/qemu_coverage/Cargo.toml diff --git a/fuzzers/qemu/qemu_coverage/Makefile.toml b/fuzzers/binary-only/qemu_coverage/Makefile.toml similarity index 100% rename from fuzzers/qemu/qemu_coverage/Makefile.toml rename to fuzzers/binary-only/qemu_coverage/Makefile.toml diff --git a/fuzzers/qemu/qemu_coverage/README.md b/fuzzers/binary-only/qemu_coverage/README.md similarity index 100% rename from fuzzers/qemu/qemu_coverage/README.md rename to fuzzers/binary-only/qemu_coverage/README.md diff --git a/fuzzers/qemu/qemu_coverage/build.rs b/fuzzers/binary-only/qemu_coverage/build.rs similarity index 100% rename from fuzzers/qemu/qemu_coverage/build.rs rename to fuzzers/binary-only/qemu_coverage/build.rs diff --git a/fuzzers/libpng/libfuzzer_libpng_accounting/corpus/not_kitty.png b/fuzzers/binary-only/qemu_coverage/corpus/not_kitty.png similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_accounting/corpus/not_kitty.png rename to fuzzers/binary-only/qemu_coverage/corpus/not_kitty.png diff --git a/fuzzers/libpng/libfuzzer_libpng_accounting/corpus/not_kitty_alpha.png b/fuzzers/binary-only/qemu_coverage/corpus/not_kitty_alpha.png similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_accounting/corpus/not_kitty_alpha.png rename to fuzzers/binary-only/qemu_coverage/corpus/not_kitty_alpha.png diff --git a/fuzzers/libpng/libfuzzer_libpng_accounting/corpus/not_kitty_gamma.png b/fuzzers/binary-only/qemu_coverage/corpus/not_kitty_gamma.png similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_accounting/corpus/not_kitty_gamma.png rename to fuzzers/binary-only/qemu_coverage/corpus/not_kitty_gamma.png diff --git a/fuzzers/libpng/libfuzzer_libpng_accounting/corpus/not_kitty_icc.png b/fuzzers/binary-only/qemu_coverage/corpus/not_kitty_icc.png similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_accounting/corpus/not_kitty_icc.png rename to fuzzers/binary-only/qemu_coverage/corpus/not_kitty_icc.png diff --git a/fuzzers/qemu/qemu_coverage/harness.cc b/fuzzers/binary-only/qemu_coverage/harness.cc similarity index 100% rename from fuzzers/qemu/qemu_coverage/harness.cc rename to fuzzers/binary-only/qemu_coverage/harness.cc diff --git a/fuzzers/qemu/qemu_coverage/src/fuzzer.rs b/fuzzers/binary-only/qemu_coverage/src/fuzzer.rs similarity index 94% rename from fuzzers/qemu/qemu_coverage/src/fuzzer.rs rename to fuzzers/binary-only/qemu_coverage/src/fuzzer.rs index 8cea932a25..8852109250 100644 --- a/fuzzers/qemu/qemu_coverage/src/fuzzer.rs +++ b/fuzzers/binary-only/qemu_coverage/src/fuzzer.rs @@ -27,7 +27,7 @@ use libafl_bolts::{ }; use libafl_qemu::{ elf::EasyElf, - modules::{drcov::DrCovModule, QemuInstrumentationAddressRangeFilter}, + modules::{drcov::DrCovModule, StdAddressFilter}, ArchExtras, CallingConvention, Emulator, GuestAddr, GuestReg, MmapPerms, Qemu, QemuExecutor, QemuExitReason, QemuRWError, QemuShutdownCause, Regs, }; @@ -175,18 +175,19 @@ pub fn fuzz() { } }; - let mut harness = |_emulator: &mut Emulator<_, _, _, _, _>, input: &BytesInput| { - let target = input.target_bytes(); - let mut buf = target.as_slice(); - let mut len = buf.len(); - if len > MAX_INPUT_SIZE { - buf = &buf[0..MAX_INPUT_SIZE]; - len = MAX_INPUT_SIZE; - } - let len = len as GuestReg; - reset(buf, len).unwrap(); - ExitKind::Ok - }; + let mut harness = + |_emulator: &mut Emulator<_, _, _, _, _>, _state: &mut _, input: &BytesInput| { + let target = input.target_bytes(); + let mut buf = target.as_slice(); + let mut len = buf.len(); + if len > MAX_INPUT_SIZE { + buf = &buf[0..MAX_INPUT_SIZE]; + len = MAX_INPUT_SIZE; + } + let len = len as GuestReg; + reset(buf, len).unwrap(); + ExitKind::Ok + }; let mut run_client = |state: Option<_>, mut mgr: LlmpRestartingEventManager<_, _, _>, core_id| { @@ -233,7 +234,7 @@ pub fn fuzz() { cov_path.set_file_name(format!("{coverage_name}-{core:03}.{coverage_extension}")); let emulator_modules = tuple_list!(DrCovModule::new( - QemuInstrumentationAddressRangeFilter::None, + StdAddressFilter::default(), cov_path, false, )); diff --git a/fuzzers/qemu/qemu_coverage/src/main.rs b/fuzzers/binary-only/qemu_coverage/src/main.rs similarity index 100% rename from fuzzers/qemu/qemu_coverage/src/main.rs rename to fuzzers/binary-only/qemu_coverage/src/main.rs diff --git a/fuzzers/qemu/qemu_launcher/.gitignore b/fuzzers/binary-only/qemu_launcher/.gitignore similarity index 100% rename from fuzzers/qemu/qemu_launcher/.gitignore rename to fuzzers/binary-only/qemu_launcher/.gitignore diff --git a/fuzzers/qemu/qemu_launcher/Cargo.toml b/fuzzers/binary-only/qemu_launcher/Cargo.toml similarity index 100% rename from fuzzers/qemu/qemu_launcher/Cargo.toml rename to fuzzers/binary-only/qemu_launcher/Cargo.toml diff --git a/fuzzers/qemu/qemu_launcher/Makefile.toml b/fuzzers/binary-only/qemu_launcher/Makefile.toml similarity index 100% rename from fuzzers/qemu/qemu_launcher/Makefile.toml rename to fuzzers/binary-only/qemu_launcher/Makefile.toml diff --git a/fuzzers/qemu/qemu_launcher/README.md b/fuzzers/binary-only/qemu_launcher/README.md similarity index 100% rename from fuzzers/qemu/qemu_launcher/README.md rename to fuzzers/binary-only/qemu_launcher/README.md diff --git a/fuzzers/qemu/qemu_launcher/build.rs b/fuzzers/binary-only/qemu_launcher/build.rs similarity index 100% rename from fuzzers/qemu/qemu_launcher/build.rs rename to fuzzers/binary-only/qemu_launcher/build.rs diff --git a/fuzzers/libpng/libfuzzer_libpng_centralized/corpus/not_kitty.png b/fuzzers/binary-only/qemu_launcher/corpus/not_kitty.png similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_centralized/corpus/not_kitty.png rename to fuzzers/binary-only/qemu_launcher/corpus/not_kitty.png diff --git a/fuzzers/libpng/libfuzzer_libpng_centralized/corpus/not_kitty_alpha.png b/fuzzers/binary-only/qemu_launcher/corpus/not_kitty_alpha.png similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_centralized/corpus/not_kitty_alpha.png rename to fuzzers/binary-only/qemu_launcher/corpus/not_kitty_alpha.png diff --git a/fuzzers/libpng/libfuzzer_libpng_centralized/corpus/not_kitty_gamma.png b/fuzzers/binary-only/qemu_launcher/corpus/not_kitty_gamma.png similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_centralized/corpus/not_kitty_gamma.png rename to fuzzers/binary-only/qemu_launcher/corpus/not_kitty_gamma.png diff --git a/fuzzers/libpng/libfuzzer_libpng_centralized/corpus/not_kitty_icc.png b/fuzzers/binary-only/qemu_launcher/corpus/not_kitty_icc.png similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_centralized/corpus/not_kitty_icc.png rename to fuzzers/binary-only/qemu_launcher/corpus/not_kitty_icc.png diff --git a/fuzzers/qemu/qemu_launcher/harness.cc b/fuzzers/binary-only/qemu_launcher/harness.cc similarity index 100% rename from fuzzers/qemu/qemu_launcher/harness.cc rename to fuzzers/binary-only/qemu_launcher/harness.cc diff --git a/fuzzers/qemu/qemu_launcher/injection_test/.gitignore b/fuzzers/binary-only/qemu_launcher/injection_test/.gitignore similarity index 100% rename from fuzzers/qemu/qemu_launcher/injection_test/.gitignore rename to fuzzers/binary-only/qemu_launcher/injection_test/.gitignore diff --git a/fuzzers/qemu/qemu_launcher/injection_test/Makefile b/fuzzers/binary-only/qemu_launcher/injection_test/Makefile similarity index 100% rename from fuzzers/qemu/qemu_launcher/injection_test/Makefile rename to fuzzers/binary-only/qemu_launcher/injection_test/Makefile diff --git a/fuzzers/qemu/qemu_launcher/injection_test/README.md b/fuzzers/binary-only/qemu_launcher/injection_test/README.md similarity index 100% rename from fuzzers/qemu/qemu_launcher/injection_test/README.md rename to fuzzers/binary-only/qemu_launcher/injection_test/README.md diff --git a/fuzzers/qemu/qemu_launcher/injection_test/example.db b/fuzzers/binary-only/qemu_launcher/injection_test/example.db similarity index 100% rename from fuzzers/qemu/qemu_launcher/injection_test/example.db rename to fuzzers/binary-only/qemu_launcher/injection_test/example.db diff --git a/fuzzers/qemu/qemu_launcher/injection_test/sqltest.c b/fuzzers/binary-only/qemu_launcher/injection_test/sqltest.c similarity index 100% rename from fuzzers/qemu/qemu_launcher/injection_test/sqltest.c rename to fuzzers/binary-only/qemu_launcher/injection_test/sqltest.c diff --git a/fuzzers/qemu/qemu_launcher/injections.toml b/fuzzers/binary-only/qemu_launcher/injections.toml similarity index 100% rename from fuzzers/qemu/qemu_launcher/injections.toml rename to fuzzers/binary-only/qemu_launcher/injections.toml diff --git a/fuzzers/qemu/qemu_launcher/injections.yaml b/fuzzers/binary-only/qemu_launcher/injections.yaml similarity index 100% rename from fuzzers/qemu/qemu_launcher/injections.yaml rename to fuzzers/binary-only/qemu_launcher/injections.yaml diff --git a/fuzzers/qemu/qemu_launcher/src/client.rs b/fuzzers/binary-only/qemu_launcher/src/client.rs similarity index 94% rename from fuzzers/qemu/qemu_launcher/src/client.rs rename to fuzzers/binary-only/qemu_launcher/src/client.rs index 9eaf39f931..d21ef96a0e 100644 --- a/fuzzers/qemu/qemu_launcher/src/client.rs +++ b/fuzzers/binary-only/qemu_launcher/src/client.rs @@ -16,8 +16,8 @@ use libafl_qemu::{ asan::{init_qemu_with_asan, AsanModule}, asan_guest::{init_qemu_with_asan_guest, AsanGuestModule}, cmplog::CmpLogModule, - edges::EdgeCoverageModule, - QemuInstrumentationAddressRangeFilter, + edges::StdEdgeCoverageModule, + StdAddressFilter, }, ArchExtras, GuestAddr, Qemu, }; @@ -68,7 +68,7 @@ impl<'a> Client<'a> { } #[allow(clippy::similar_names)] // elf != self - fn coverage_filter(&self, qemu: &Qemu) -> Result { + fn coverage_filter(&self, qemu: &Qemu) -> Result { /* Conversion is required on 32-bit targets, but not on 64-bit ones */ if let Some(includes) = &self.options.include { #[cfg_attr(target_pointer_width = "64", allow(clippy::useless_conversion))] @@ -79,7 +79,7 @@ impl<'a> Client<'a> { end: x.end.into(), }) .collect::>>(); - Ok(QemuInstrumentationAddressRangeFilter::AllowList(rules)) + Ok(StdAddressFilter::allow_list(rules)) } else if let Some(excludes) = &self.options.exclude { #[cfg_attr(target_pointer_width = "64", allow(clippy::useless_conversion))] let rules = excludes @@ -89,16 +89,14 @@ impl<'a> Client<'a> { end: x.end.into(), }) .collect::>>(); - Ok(QemuInstrumentationAddressRangeFilter::DenyList(rules)) + Ok(StdAddressFilter::deny_list(rules)) } else { let mut elf_buffer = Vec::new(); let elf = EasyElf::from_file(qemu.binary_path(), &mut elf_buffer)?; let range = elf .get_section(".text", qemu.load_addr()) .ok_or_else(|| Error::key_not_found("Failed to find .text section"))?; - Ok(QemuInstrumentationAddressRangeFilter::AllowList(vec![ - range, - ])) + Ok(StdAddressFilter::allow_list(vec![range])) } } @@ -167,7 +165,9 @@ impl<'a> Client<'a> { let is_cmplog = self.options.is_cmplog_core(core_id); - let edge_coverage_module = EdgeCoverageModule::new(self.coverage_filter(&qemu)?); + let edge_coverage_module = StdEdgeCoverageModule::builder() + .address_filter(self.coverage_filter(&qemu)?) + .build(); let instance = Instance::builder() .options(self.options) diff --git a/fuzzers/qemu/qemu_launcher/src/fuzzer.rs b/fuzzers/binary-only/qemu_launcher/src/fuzzer.rs similarity index 100% rename from fuzzers/qemu/qemu_launcher/src/fuzzer.rs rename to fuzzers/binary-only/qemu_launcher/src/fuzzer.rs diff --git a/fuzzers/qemu/qemu_launcher/src/harness.rs b/fuzzers/binary-only/qemu_launcher/src/harness.rs similarity index 100% rename from fuzzers/qemu/qemu_launcher/src/harness.rs rename to fuzzers/binary-only/qemu_launcher/src/harness.rs diff --git a/fuzzers/qemu/qemu_launcher/src/instance.rs b/fuzzers/binary-only/qemu_launcher/src/instance.rs similarity index 98% rename from fuzzers/qemu/qemu_launcher/src/instance.rs rename to fuzzers/binary-only/qemu_launcher/src/instance.rs index dd12e2d023..47037c0c14 100644 --- a/fuzzers/qemu/qemu_launcher/src/instance.rs +++ b/fuzzers/binary-only/qemu_launcher/src/instance.rs @@ -148,8 +148,9 @@ impl<'a, M: Monitor> Instance<'a, M> { state.add_metadata(tokens); let harness = Harness::new(self.qemu)?; - let mut harness = - |_emulator: &mut Emulator<_, _, _, _, _>, input: &BytesInput| harness.run(input); + let mut harness = |_emulator: &mut Emulator<_, _, _, _, _>, + _state: &mut _, + input: &BytesInput| harness.run(input); // A fuzzer with feedbacks and a corpus scheduler let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); diff --git a/fuzzers/qemu/qemu_launcher/src/main.rs b/fuzzers/binary-only/qemu_launcher/src/main.rs similarity index 100% rename from fuzzers/qemu/qemu_launcher/src/main.rs rename to fuzzers/binary-only/qemu_launcher/src/main.rs diff --git a/fuzzers/qemu/qemu_launcher/src/options.rs b/fuzzers/binary-only/qemu_launcher/src/options.rs similarity index 100% rename from fuzzers/qemu/qemu_launcher/src/options.rs rename to fuzzers/binary-only/qemu_launcher/src/options.rs diff --git a/fuzzers/qemu/qemu_launcher/src/version.rs b/fuzzers/binary-only/qemu_launcher/src/version.rs similarity index 100% rename from fuzzers/qemu/qemu_launcher/src/version.rs rename to fuzzers/binary-only/qemu_launcher/src/version.rs diff --git a/fuzzers/others/tinyinst_simple/Cargo.toml b/fuzzers/binary-only/tinyinst_simple/Cargo.toml similarity index 100% rename from fuzzers/others/tinyinst_simple/Cargo.toml rename to fuzzers/binary-only/tinyinst_simple/Cargo.toml diff --git a/fuzzers/others/tinyinst_simple/Makefile.toml b/fuzzers/binary-only/tinyinst_simple/Makefile.toml similarity index 100% rename from fuzzers/others/tinyinst_simple/Makefile.toml rename to fuzzers/binary-only/tinyinst_simple/Makefile.toml diff --git a/fuzzers/others/tinyinst_simple/README.md b/fuzzers/binary-only/tinyinst_simple/README.md similarity index 100% rename from fuzzers/others/tinyinst_simple/README.md rename to fuzzers/binary-only/tinyinst_simple/README.md diff --git a/fuzzers/others/tinyinst_simple/src/main.rs b/fuzzers/binary-only/tinyinst_simple/src/main.rs similarity index 100% rename from fuzzers/others/tinyinst_simple/src/main.rs rename to fuzzers/binary-only/tinyinst_simple/src/main.rs diff --git a/fuzzers/others/tinyinst_simple/test/crash_input.txt b/fuzzers/binary-only/tinyinst_simple/test/crash_input.txt similarity index 100% rename from fuzzers/others/tinyinst_simple/test/crash_input.txt rename to fuzzers/binary-only/tinyinst_simple/test/crash_input.txt diff --git a/fuzzers/others/tinyinst_simple/test/ok_input.txt b/fuzzers/binary-only/tinyinst_simple/test/ok_input.txt similarity index 100% rename from fuzzers/others/tinyinst_simple/test/ok_input.txt rename to fuzzers/binary-only/tinyinst_simple/test/ok_input.txt diff --git a/fuzzers/others/tinyinst_simple/test/test.cpp b/fuzzers/binary-only/tinyinst_simple/test/test.cpp similarity index 100% rename from fuzzers/others/tinyinst_simple/test/test.cpp rename to fuzzers/binary-only/tinyinst_simple/test/test.cpp diff --git a/fuzzers/fuzzbench/fuzzbench/.gitignore b/fuzzers/forkserver/fuzzbench_forkserver/.gitignore similarity index 100% rename from fuzzers/fuzzbench/fuzzbench/.gitignore rename to fuzzers/forkserver/fuzzbench_forkserver/.gitignore diff --git a/fuzzers/fuzzbench/fuzzbench_forkserver/Cargo.toml b/fuzzers/forkserver/fuzzbench_forkserver/Cargo.toml similarity index 100% rename from fuzzers/fuzzbench/fuzzbench_forkserver/Cargo.toml rename to fuzzers/forkserver/fuzzbench_forkserver/Cargo.toml diff --git a/fuzzers/fuzzbench/fuzzbench_forkserver/src/main.rs b/fuzzers/forkserver/fuzzbench_forkserver/src/main.rs similarity index 100% rename from fuzzers/fuzzbench/fuzzbench_forkserver/src/main.rs rename to fuzzers/forkserver/fuzzbench_forkserver/src/main.rs diff --git a/fuzzers/fuzzbench/fuzzbench_forkserver_cmplog/Cargo.toml b/fuzzers/forkserver/fuzzbench_forkserver_cmplog/Cargo.toml similarity index 100% rename from fuzzers/fuzzbench/fuzzbench_forkserver_cmplog/Cargo.toml rename to fuzzers/forkserver/fuzzbench_forkserver_cmplog/Cargo.toml diff --git a/fuzzers/fuzzbench/fuzzbench_forkserver_cmplog/src/main.rs b/fuzzers/forkserver/fuzzbench_forkserver_cmplog/src/main.rs similarity index 100% rename from fuzzers/fuzzbench/fuzzbench_forkserver_cmplog/src/main.rs rename to fuzzers/forkserver/fuzzbench_forkserver_cmplog/src/main.rs diff --git a/fuzzers/fuzzbench/fuzzbench_forkserver_cmplog/test/compile.sh b/fuzzers/forkserver/fuzzbench_forkserver_cmplog/test/compile.sh similarity index 100% rename from fuzzers/fuzzbench/fuzzbench_forkserver_cmplog/test/compile.sh rename to fuzzers/forkserver/fuzzbench_forkserver_cmplog/test/compile.sh diff --git a/fuzzers/fuzzbench/fuzzbench_forkserver_cmplog/test/test-cmplog.c b/fuzzers/forkserver/fuzzbench_forkserver_cmplog/test/test-cmplog.c similarity index 100% rename from fuzzers/fuzzbench/fuzzbench_forkserver_cmplog/test/test-cmplog.c rename to fuzzers/forkserver/fuzzbench_forkserver_cmplog/test/test-cmplog.c diff --git a/fuzzers/others/libafl-fuzz/.gitignore b/fuzzers/forkserver/libafl-fuzz/.gitignore similarity index 100% rename from fuzzers/others/libafl-fuzz/.gitignore rename to fuzzers/forkserver/libafl-fuzz/.gitignore diff --git a/fuzzers/others/libafl-fuzz/Cargo.toml b/fuzzers/forkserver/libafl-fuzz/Cargo.toml similarity index 100% rename from fuzzers/others/libafl-fuzz/Cargo.toml rename to fuzzers/forkserver/libafl-fuzz/Cargo.toml diff --git a/fuzzers/others/libafl-fuzz/Makefile.toml b/fuzzers/forkserver/libafl-fuzz/Makefile.toml similarity index 100% rename from fuzzers/others/libafl-fuzz/Makefile.toml rename to fuzzers/forkserver/libafl-fuzz/Makefile.toml diff --git a/fuzzers/others/libafl-fuzz/README.md b/fuzzers/forkserver/libafl-fuzz/README.md similarity index 100% rename from fuzzers/others/libafl-fuzz/README.md rename to fuzzers/forkserver/libafl-fuzz/README.md diff --git a/fuzzers/others/libafl-fuzz/rustfmt.toml b/fuzzers/forkserver/libafl-fuzz/rustfmt.toml similarity index 100% rename from fuzzers/others/libafl-fuzz/rustfmt.toml rename to fuzzers/forkserver/libafl-fuzz/rustfmt.toml diff --git a/fuzzers/others/libafl-fuzz/src/afl_stats.rs b/fuzzers/forkserver/libafl-fuzz/src/afl_stats.rs similarity index 100% rename from fuzzers/others/libafl-fuzz/src/afl_stats.rs rename to fuzzers/forkserver/libafl-fuzz/src/afl_stats.rs diff --git a/fuzzers/others/libafl-fuzz/src/corpus.rs b/fuzzers/forkserver/libafl-fuzz/src/corpus.rs similarity index 100% rename from fuzzers/others/libafl-fuzz/src/corpus.rs rename to fuzzers/forkserver/libafl-fuzz/src/corpus.rs diff --git a/fuzzers/others/libafl-fuzz/src/env_parser.rs b/fuzzers/forkserver/libafl-fuzz/src/env_parser.rs similarity index 100% rename from fuzzers/others/libafl-fuzz/src/env_parser.rs rename to fuzzers/forkserver/libafl-fuzz/src/env_parser.rs diff --git a/fuzzers/others/libafl-fuzz/src/executor.rs b/fuzzers/forkserver/libafl-fuzz/src/executor.rs similarity index 100% rename from fuzzers/others/libafl-fuzz/src/executor.rs rename to fuzzers/forkserver/libafl-fuzz/src/executor.rs diff --git a/fuzzers/others/libafl-fuzz/src/feedback/filepath.rs b/fuzzers/forkserver/libafl-fuzz/src/feedback/filepath.rs similarity index 100% rename from fuzzers/others/libafl-fuzz/src/feedback/filepath.rs rename to fuzzers/forkserver/libafl-fuzz/src/feedback/filepath.rs diff --git a/fuzzers/others/libafl-fuzz/src/feedback/mod.rs b/fuzzers/forkserver/libafl-fuzz/src/feedback/mod.rs similarity index 100% rename from fuzzers/others/libafl-fuzz/src/feedback/mod.rs rename to fuzzers/forkserver/libafl-fuzz/src/feedback/mod.rs diff --git a/fuzzers/others/libafl-fuzz/src/feedback/persistent_record.rs b/fuzzers/forkserver/libafl-fuzz/src/feedback/persistent_record.rs similarity index 100% rename from fuzzers/others/libafl-fuzz/src/feedback/persistent_record.rs rename to fuzzers/forkserver/libafl-fuzz/src/feedback/persistent_record.rs diff --git a/fuzzers/others/libafl-fuzz/src/feedback/seed.rs b/fuzzers/forkserver/libafl-fuzz/src/feedback/seed.rs similarity index 100% rename from fuzzers/others/libafl-fuzz/src/feedback/seed.rs rename to fuzzers/forkserver/libafl-fuzz/src/feedback/seed.rs diff --git a/fuzzers/others/libafl-fuzz/src/fuzzer.rs b/fuzzers/forkserver/libafl-fuzz/src/fuzzer.rs similarity index 100% rename from fuzzers/others/libafl-fuzz/src/fuzzer.rs rename to fuzzers/forkserver/libafl-fuzz/src/fuzzer.rs diff --git a/fuzzers/others/libafl-fuzz/src/hooks.rs b/fuzzers/forkserver/libafl-fuzz/src/hooks.rs similarity index 100% rename from fuzzers/others/libafl-fuzz/src/hooks.rs rename to fuzzers/forkserver/libafl-fuzz/src/hooks.rs diff --git a/fuzzers/others/libafl-fuzz/src/main.rs b/fuzzers/forkserver/libafl-fuzz/src/main.rs similarity index 100% rename from fuzzers/others/libafl-fuzz/src/main.rs rename to fuzzers/forkserver/libafl-fuzz/src/main.rs diff --git a/fuzzers/others/libafl-fuzz/src/scheduler.rs b/fuzzers/forkserver/libafl-fuzz/src/scheduler.rs similarity index 100% rename from fuzzers/others/libafl-fuzz/src/scheduler.rs rename to fuzzers/forkserver/libafl-fuzz/src/scheduler.rs diff --git a/fuzzers/others/libafl-fuzz/src/stages/mod.rs b/fuzzers/forkserver/libafl-fuzz/src/stages/mod.rs similarity index 100% rename from fuzzers/others/libafl-fuzz/src/stages/mod.rs rename to fuzzers/forkserver/libafl-fuzz/src/stages/mod.rs diff --git a/fuzzers/others/libafl-fuzz/src/stages/mutational_stage.rs b/fuzzers/forkserver/libafl-fuzz/src/stages/mutational_stage.rs similarity index 100% rename from fuzzers/others/libafl-fuzz/src/stages/mutational_stage.rs rename to fuzzers/forkserver/libafl-fuzz/src/stages/mutational_stage.rs diff --git a/fuzzers/others/libafl-fuzz/src/stages/time_tracker.rs b/fuzzers/forkserver/libafl-fuzz/src/stages/time_tracker.rs similarity index 100% rename from fuzzers/others/libafl-fuzz/src/stages/time_tracker.rs rename to fuzzers/forkserver/libafl-fuzz/src/stages/time_tracker.rs diff --git a/fuzzers/others/libafl-fuzz/test/seeds-frida/init b/fuzzers/forkserver/libafl-fuzz/test/seeds-frida/init similarity index 100% rename from fuzzers/others/libafl-fuzz/test/seeds-frida/init rename to fuzzers/forkserver/libafl-fuzz/test/seeds-frida/init diff --git a/fuzzers/others/libafl-fuzz/test/seeds/init b/fuzzers/forkserver/libafl-fuzz/test/seeds/init similarity index 100% rename from fuzzers/others/libafl-fuzz/test/seeds/init rename to fuzzers/forkserver/libafl-fuzz/test/seeds/init diff --git a/fuzzers/others/libafl-fuzz/test/seeds_cmplog/init b/fuzzers/forkserver/libafl-fuzz/test/seeds_cmplog/init similarity index 100% rename from fuzzers/others/libafl-fuzz/test/seeds_cmplog/init rename to fuzzers/forkserver/libafl-fuzz/test/seeds_cmplog/init diff --git a/fuzzers/others/libafl-fuzz/test/seeds_frida/init b/fuzzers/forkserver/libafl-fuzz/test/seeds_frida/init similarity index 100% rename from fuzzers/others/libafl-fuzz/test/seeds_frida/init rename to fuzzers/forkserver/libafl-fuzz/test/seeds_frida/init diff --git a/fuzzers/others/libafl-fuzz/test/seeds_qemu/init b/fuzzers/forkserver/libafl-fuzz/test/seeds_qemu/init similarity index 100% rename from fuzzers/others/libafl-fuzz/test/seeds_qemu/init rename to fuzzers/forkserver/libafl-fuzz/test/seeds_qemu/init diff --git a/fuzzers/others/libafl-fuzz/test/seeds_unicorn/in b/fuzzers/forkserver/libafl-fuzz/test/seeds_unicorn/in similarity index 100% rename from fuzzers/others/libafl-fuzz/test/seeds_unicorn/in rename to fuzzers/forkserver/libafl-fuzz/test/seeds_unicorn/in diff --git a/fuzzers/others/libafl-fuzz/test/seeds_unicorn_cmpcov/in b/fuzzers/forkserver/libafl-fuzz/test/seeds_unicorn_cmpcov/in similarity index 100% rename from fuzzers/others/libafl-fuzz/test/seeds_unicorn_cmpcov/in rename to fuzzers/forkserver/libafl-fuzz/test/seeds_unicorn_cmpcov/in diff --git a/fuzzers/others/libafl-fuzz/test/test-cmpcov.c b/fuzzers/forkserver/libafl-fuzz/test/test-cmpcov.c similarity index 100% rename from fuzzers/others/libafl-fuzz/test/test-cmpcov.c rename to fuzzers/forkserver/libafl-fuzz/test/test-cmpcov.c diff --git a/fuzzers/others/libafl-fuzz/test/test-cmplog.c b/fuzzers/forkserver/libafl-fuzz/test/test-cmplog.c similarity index 100% rename from fuzzers/others/libafl-fuzz/test/test-cmplog.c rename to fuzzers/forkserver/libafl-fuzz/test/test-cmplog.c diff --git a/fuzzers/others/libafl-fuzz/test/test-instr.c b/fuzzers/forkserver/libafl-fuzz/test/test-instr.c similarity index 100% rename from fuzzers/others/libafl-fuzz/test/test-instr.c rename to fuzzers/forkserver/libafl-fuzz/test/test-instr.c diff --git a/fuzzers/others/libafl-fuzz/test/test.sh b/fuzzers/forkserver/libafl-fuzz/test/test.sh similarity index 100% rename from fuzzers/others/libafl-fuzz/test/test.sh rename to fuzzers/forkserver/libafl-fuzz/test/test.sh diff --git a/fuzzers/nyx/nyx_libxml2_parallel/Cargo.toml b/fuzzers/full-system/nyx_libxml2_parallel/Cargo.toml similarity index 100% rename from fuzzers/nyx/nyx_libxml2_parallel/Cargo.toml rename to fuzzers/full-system/nyx_libxml2_parallel/Cargo.toml diff --git a/fuzzers/nyx/nyx_libxml2_parallel/Makefile.toml b/fuzzers/full-system/nyx_libxml2_parallel/Makefile.toml similarity index 100% rename from fuzzers/nyx/nyx_libxml2_parallel/Makefile.toml rename to fuzzers/full-system/nyx_libxml2_parallel/Makefile.toml diff --git a/fuzzers/nyx/nyx_libxml2_parallel/README.md b/fuzzers/full-system/nyx_libxml2_parallel/README.md similarity index 100% rename from fuzzers/nyx/nyx_libxml2_parallel/README.md rename to fuzzers/full-system/nyx_libxml2_parallel/README.md diff --git a/fuzzers/nyx/nyx_libxml2_parallel/setup_libxml2.sh b/fuzzers/full-system/nyx_libxml2_parallel/setup_libxml2.sh similarity index 100% rename from fuzzers/nyx/nyx_libxml2_parallel/setup_libxml2.sh rename to fuzzers/full-system/nyx_libxml2_parallel/setup_libxml2.sh diff --git a/fuzzers/nyx/nyx_libxml2_parallel/src/bin/libafl_cc.rs b/fuzzers/full-system/nyx_libxml2_parallel/src/bin/libafl_cc.rs similarity index 100% rename from fuzzers/nyx/nyx_libxml2_parallel/src/bin/libafl_cc.rs rename to fuzzers/full-system/nyx_libxml2_parallel/src/bin/libafl_cc.rs diff --git a/fuzzers/fuzzbench/fuzzbench/src/bin/libafl_cxx.rs b/fuzzers/full-system/nyx_libxml2_parallel/src/bin/libafl_cxx.rs similarity index 100% rename from fuzzers/fuzzbench/fuzzbench/src/bin/libafl_cxx.rs rename to fuzzers/full-system/nyx_libxml2_parallel/src/bin/libafl_cxx.rs diff --git a/fuzzers/nyx/nyx_libxml2_parallel/src/main.rs b/fuzzers/full-system/nyx_libxml2_parallel/src/main.rs similarity index 100% rename from fuzzers/nyx/nyx_libxml2_parallel/src/main.rs rename to fuzzers/full-system/nyx_libxml2_parallel/src/main.rs diff --git a/fuzzers/nyx/nyx_libxml2_standalone/Cargo.toml b/fuzzers/full-system/nyx_libxml2_standalone/Cargo.toml similarity index 100% rename from fuzzers/nyx/nyx_libxml2_standalone/Cargo.toml rename to fuzzers/full-system/nyx_libxml2_standalone/Cargo.toml diff --git a/fuzzers/nyx/nyx_libxml2_standalone/Makefile.toml b/fuzzers/full-system/nyx_libxml2_standalone/Makefile.toml similarity index 100% rename from fuzzers/nyx/nyx_libxml2_standalone/Makefile.toml rename to fuzzers/full-system/nyx_libxml2_standalone/Makefile.toml diff --git a/fuzzers/nyx/nyx_libxml2_standalone/README.md b/fuzzers/full-system/nyx_libxml2_standalone/README.md similarity index 100% rename from fuzzers/nyx/nyx_libxml2_standalone/README.md rename to fuzzers/full-system/nyx_libxml2_standalone/README.md diff --git a/fuzzers/nyx/nyx_libxml2_standalone/setup_libxml2.sh b/fuzzers/full-system/nyx_libxml2_standalone/setup_libxml2.sh similarity index 100% rename from fuzzers/nyx/nyx_libxml2_standalone/setup_libxml2.sh rename to fuzzers/full-system/nyx_libxml2_standalone/setup_libxml2.sh diff --git a/fuzzers/nyx/nyx_libxml2_standalone/src/bin/libafl_cc.rs b/fuzzers/full-system/nyx_libxml2_standalone/src/bin/libafl_cc.rs similarity index 100% rename from fuzzers/nyx/nyx_libxml2_standalone/src/bin/libafl_cc.rs rename to fuzzers/full-system/nyx_libxml2_standalone/src/bin/libafl_cc.rs diff --git a/fuzzers/fuzzbench/fuzzbench_ctx/src/bin/libafl_cxx.rs b/fuzzers/full-system/nyx_libxml2_standalone/src/bin/libafl_cxx.rs similarity index 100% rename from fuzzers/fuzzbench/fuzzbench_ctx/src/bin/libafl_cxx.rs rename to fuzzers/full-system/nyx_libxml2_standalone/src/bin/libafl_cxx.rs diff --git a/fuzzers/nyx/nyx_libxml2_standalone/src/main.rs b/fuzzers/full-system/nyx_libxml2_standalone/src/main.rs similarity index 100% rename from fuzzers/nyx/nyx_libxml2_standalone/src/main.rs rename to fuzzers/full-system/nyx_libxml2_standalone/src/main.rs diff --git a/fuzzers/qemu/qemu_systemmode/.gitignore b/fuzzers/full-system/qemu_baremetal/.gitignore similarity index 100% rename from fuzzers/qemu/qemu_systemmode/.gitignore rename to fuzzers/full-system/qemu_baremetal/.gitignore diff --git a/fuzzers/qemu/qemu_systemmode/Cargo.toml b/fuzzers/full-system/qemu_baremetal/Cargo.toml similarity index 80% rename from fuzzers/qemu/qemu_systemmode/Cargo.toml rename to fuzzers/full-system/qemu_baremetal/Cargo.toml index 58c0b7248b..4f48d9b4da 100644 --- a/fuzzers/qemu/qemu_systemmode/Cargo.toml +++ b/fuzzers/full-system/qemu_baremetal/Cargo.toml @@ -1,18 +1,19 @@ [package] -name = "qemu_systemmode" +name = "qemu_baremetal" version = "0.13.2" authors = [ "Andrea Fioraldi ", "Dominik Maier ", + "Romain Malmain ", ] edition = "2021" [features] -default = ["std", "classic"] +default = ["std", "low_level"] std = [] -classic = [ -] # The classic way to interact with LibAFL QEMU, with direct calls to QEMU's functions +low_level = [ +] # The low-level way to interact with LibAFL QEMU, with direct calls to QEMU's functions breakpoint = [] # Uses the command system, with breakpoints sync_exit = [] # Uses the command system, with sync exit. diff --git a/fuzzers/qemu/qemu_systemmode/Makefile.toml b/fuzzers/full-system/qemu_baremetal/Makefile.toml similarity index 74% rename from fuzzers/qemu/qemu_systemmode/Makefile.toml rename to fuzzers/full-system/qemu_baremetal/Makefile.toml index f7543cb358..69f71a1640 100644 --- a/fuzzers/qemu/qemu_systemmode/Makefile.toml +++ b/fuzzers/full-system/qemu_baremetal/Makefile.toml @@ -77,7 +77,7 @@ args = [ dependencies = ["image"] [tasks.run_fuzzer] -command = "${TARGET_DIR}/${PROFILE_DIR}/qemu_systemmode" +command = "${TARGET_DIR}/${PROFILE_DIR}/qemu_baremetal" args = [ "-icount", "shift=auto,align=off,sleep=off", @@ -104,30 +104,38 @@ script = ''' TMP_DIR=$(mktemp -d) cargo make build_$FEATURE -timeout 15s cargo make ${FEATURE} | tee $TMP_DIR/fuzz.log 2>&1 || true +timeout 20s ${TARGET_DIR}/${PROFILE_DIR}/qemu_baremetal -icount shift=auto,align=off,sleep=off -machine mps2-an385 -monitor null -kernel ${TARGET_DIR}/example.elf -serial null -nographic -snapshot -drive if=none,format=qcow2,file=${TARGET_DIR}/dummy.qcow2 -S | tee $TMP_DIR/fuzz.log 2>&1 || true if [ -z "$(grep 'Objective' $TMP_DIR/fuzz.log)" ]; then - echo "qemu_systemmode ${FEATURE}: Fuzzer did not find the objective in $TMP_DIR/fuzz.log" + echo "qemu_baremetal ${FEATURE}: Fuzzer did not find the objective in $TMP_DIR/fuzz.log" exit 1 else - echo "qemu_systemmode ${FEATURE}: Objective found." + echo "qemu_baremetal ${FEATURE}: Objective found." fi ''' +dependencies = ["target"] -[tasks.build_classic] +[tasks.build_low_level] command = "cargo" args = [ "make", "-e", - "FEATURE=classic", + "FEATURE=low_level", "-e", "TARGET_DEFINE=TARGET_CLASSIC", "build_fuzzer", ] -[tasks.test_classic] +[tasks.test_low_level] command = "cargo" -args = ["make", "-e", "FEATURE=classic", "test_fuzzer"] +args = [ + "make", + "-e", + "FEATURE=low_level", + "-e", + "TARGET_DEFINE=TARGET_CLASSIC", + "test_fuzzer", +] [tasks.build_breakpoint] command = "cargo" @@ -142,7 +150,14 @@ args = [ [tasks.test_breakpoint] command = "cargo" -args = ["make", "-e", "FEATURE=breakpoint", "test_fuzzer"] +args = [ + "make", + "-e", + "FEATURE=breakpoint", + "-e", + "TARGET_DEFINE=TARGET_BREAKPOINT", + "test_fuzzer", +] [tasks.build_sync_exit] command = "cargo" @@ -157,14 +172,21 @@ args = [ [tasks.test_sync_exit] command = "cargo" -args = ["make", "-e", "FEATURE=sync_exit", "test_fuzzer"] +args = [ + "make", + "-e", + "FEATURE=sync_exit", + "-e", + "TARGET_DEFINE=TARGET_SYNC_EXIT", + "test_fuzzer", +] -[tasks.classic] +[tasks.low_level] command = "cargo" args = [ "make", "-e", - "FEATURE=classic", + "FEATURE=low_level", "-e", "TARGET_DEFINE=TARGET_CLASSIC", "run_fuzzer", @@ -194,14 +216,14 @@ args = [ [tasks.test] clear = true -run_task = { name = ["test_classic", "test_breakpoint", "test_sync_exit"] } +run_task = { name = ["test_low_level", "test_breakpoint", "test_sync_exit"] } [tasks.build] clear = true -run_task = { name = ["build_classic", "build_breakpoint", "build_sync_exit"] } +run_task = { name = ["build_low_level", "build_breakpoint", "build_sync_exit"] } [tasks.run] -alias = "classic" +alias = "low_level" [tasks.clean] clear = true diff --git a/fuzzers/qemu/qemu_systemmode/README.md b/fuzzers/full-system/qemu_baremetal/README.md similarity index 83% rename from fuzzers/qemu/qemu_systemmode/README.md rename to fuzzers/full-system/qemu_baremetal/README.md index 12ad9af951..f151f3f0eb 100644 --- a/fuzzers/qemu/qemu_systemmode/README.md +++ b/fuzzers/full-system/qemu_baremetal/README.md @@ -1,10 +1,11 @@ -# Qemu systemmode with launcher +# Qemu baremetal with launcher This folder contains an example fuzzer for the qemu systemmode, using LLMP for fast multi-process fuzzing and crash detection. +The target is a simpel baremetal arm target. It comes in three flavours (can be set through features): --`classic`: The low-level way to interact with QEMU. +-`low_level`: The low-level way to interact with QEMU. -`breakpoint`: Interaction with QEMU using the command system, leveraging breakpoints. -`sync_exit`: Interaction with QEMU using the command system, leveraging sync exits. @@ -36,7 +37,7 @@ It is also possible to run the fuzzer with the other features: cargo make ``` -With feature being `classic`, `breakpoint` or `sync_exit`. +With feature being `low_level`, `breakpoint` or `sync_exit`. This will build the desired fuzzer (src/fuzzer_.rs) and a small example binary based on FreeRTOS, which can run under a qemu emulation target. Since the instrumentation is based on snapshots, QEMU needs a virtual drive (even if it is unused...). diff --git a/fuzzers/qemu/qemu_systemmode/build.rs b/fuzzers/full-system/qemu_baremetal/build.rs similarity index 86% rename from fuzzers/qemu/qemu_systemmode/build.rs rename to fuzzers/full-system/qemu_baremetal/build.rs index 7e6c08f7a2..9f2ee81991 100644 --- a/fuzzers/qemu/qemu_systemmode/build.rs +++ b/fuzzers/full-system/qemu_baremetal/build.rs @@ -13,7 +13,7 @@ macro_rules! assert_unique_feature { } fn main() { - assert_unique_feature!("classic", "breakpoint", "sync_exit"); + assert_unique_feature!("low_level", "breakpoint", "sync_exit"); build_libafl_qemu(); } diff --git a/fuzzers/qemu/qemu_systemmode/corpus/random b/fuzzers/full-system/qemu_baremetal/corpus/random similarity index 100% rename from fuzzers/qemu/qemu_systemmode/corpus/random rename to fuzzers/full-system/qemu_baremetal/corpus/random diff --git a/fuzzers/qemu/qemu_systemmode/corpus/zero b/fuzzers/full-system/qemu_baremetal/corpus/zero similarity index 100% rename from fuzzers/qemu/qemu_systemmode/corpus/zero rename to fuzzers/full-system/qemu_baremetal/corpus/zero diff --git a/fuzzers/qemu/qemu_systemmode/example/main.c b/fuzzers/full-system/qemu_baremetal/example/main.c similarity index 89% rename from fuzzers/qemu/qemu_systemmode/example/main.c rename to fuzzers/full-system/qemu_baremetal/example/main.c index 40944fab37..3e94204ae0 100644 --- a/fuzzers/qemu/qemu_systemmode/example/main.c +++ b/fuzzers/full-system/qemu_baremetal/example/main.c @@ -2,13 +2,15 @@ #include "libafl_qemu.h" #endif +#ifndef TARGET_SYNC_EXIT int __attribute__((noinline)) BREAKPOINT() { for (;;) {} } +#endif int LLVMFuzzerTestOneInput(unsigned int *Data, unsigned int Size) { #ifdef TARGET_SYNC_EXIT - LIBAFL_QEMU_START_PHYS((unsigned int)Data, Size); + libafl_qemu_start_phys((void *)Data, Size); #endif if (Data[3] == 0) { while (1) {} @@ -27,9 +29,10 @@ int LLVMFuzzerTestOneInput(unsigned int *Data, unsigned int Size) { } } #ifdef TARGET_SYNC_EXIT - LIBAFL_QEMU_END(LIBAFL_QEMU_END_OK); -#endif + libafl_qemu_end(LIBAFL_QEMU_END_OK); +#else return BREAKPOINT(); +#endif } unsigned int FUZZ_INPUT[] = { 101, 201, 700, 230, 860, 234, 980, 200, 340, 678, 230, 134, 900, diff --git a/fuzzers/qemu/qemu_systemmode/example/mps2_m3.ld b/fuzzers/full-system/qemu_baremetal/example/mps2_m3.ld similarity index 100% rename from fuzzers/qemu/qemu_systemmode/example/mps2_m3.ld rename to fuzzers/full-system/qemu_baremetal/example/mps2_m3.ld diff --git a/fuzzers/qemu/qemu_systemmode/example/startup.c b/fuzzers/full-system/qemu_baremetal/example/startup.c similarity index 100% rename from fuzzers/qemu/qemu_systemmode/example/startup.c rename to fuzzers/full-system/qemu_baremetal/example/startup.c diff --git a/fuzzers/qemu/qemu_systemmode/src/fuzzer_breakpoint.rs b/fuzzers/full-system/qemu_baremetal/src/fuzzer_breakpoint.rs similarity index 95% rename from fuzzers/qemu/qemu_systemmode/src/fuzzer_breakpoint.rs rename to fuzzers/full-system/qemu_baremetal/src/fuzzer_breakpoint.rs index 326ff5e4a6..f377724459 100644 --- a/fuzzers/qemu/qemu_systemmode/src/fuzzer_breakpoint.rs +++ b/fuzzers/full-system/qemu_baremetal/src/fuzzer_breakpoint.rs @@ -34,11 +34,10 @@ use libafl_qemu::{ emu::Emulator, executor::QemuExecutor, modules::edges::{ - edges_map_mut_ptr, EdgeCoverageModule, EDGES_MAP_SIZE_IN_USE, MAX_EDGES_FOUND, + edges_map_mut_ptr, StdEdgeCoverageModule, EDGES_MAP_SIZE_IN_USE, MAX_EDGES_FOUND, }, GuestPhysAddr, GuestReg, QemuMemoryChunk, }; - // use libafl_qemu::QemuSnapshotBuilder; // for normal qemu snapshot pub static mut MAX_INPUT_SIZE: usize = 50; @@ -90,7 +89,7 @@ pub fn fuzz() { // Initialize QEMU Emulator let emu = Emulator::builder() .qemu_cli(args) - .add_module(EdgeCoverageModule::default()) + .add_module(StdEdgeCoverageModule::builder().build()) .build() .unwrap(); @@ -121,9 +120,10 @@ pub fn fuzz() { println!("Devices = {:?}", devices); // The wrapped harness function, calling out to the LLVM-style harness - let mut harness = |emulator: &mut Emulator<_, _, _, _, _>, input: &BytesInput| unsafe { - emulator.run(input).unwrap().try_into().unwrap() - }; + let mut harness = + |emulator: &mut Emulator<_, _, _, _, _>, state: &mut _, input: &BytesInput| unsafe { + emulator.run(state, input).unwrap().try_into().unwrap() + }; // Create an observation channel using the coverage map let edges_observer = unsafe { diff --git a/fuzzers/qemu/qemu_systemmode/src/fuzzer_classic.rs b/fuzzers/full-system/qemu_baremetal/src/fuzzer_low_level.rs similarity index 77% rename from fuzzers/qemu/qemu_systemmode/src/fuzzer_classic.rs rename to fuzzers/full-system/qemu_baremetal/src/fuzzer_low_level.rs index 85871387ec..ae90034b51 100644 --- a/fuzzers/qemu/qemu_systemmode/src/fuzzer_classic.rs +++ b/fuzzers/full-system/qemu_baremetal/src/fuzzer_low_level.rs @@ -22,7 +22,6 @@ use libafl::{ use libafl_bolts::{ core_affinity::Cores, current_nanos, - os::unix_signals::{Signal, CTRL_C_EXIT}, ownedref::OwnedMutSlice, rands::StdRand, shmem::{ShMemProvider, StdShMemProvider}, @@ -34,7 +33,7 @@ use libafl_qemu::{ elf::EasyElf, executor::QemuExecutor, modules::edges::{ - edges_map_mut_ptr, EdgeCoverageModule, EDGES_MAP_SIZE_IN_USE, MAX_EDGES_FOUND, + edges_map_mut_ptr, StdEdgeCoverageModuleBuilder, EDGES_MAP_SIZE_IN_USE, MAX_EDGES_FOUND, }, Emulator, Qemu, QemuExitError, QemuExitReason, QemuRWError, QemuShutdownCause, Regs, }; @@ -104,7 +103,7 @@ pub fn fuzz() { .build() .expect("Failed to initialized QEMU"); - let emulator_modules = tuple_list!(EdgeCoverageModule::default()); + let emulator_modules = tuple_list!(StdEdgeCoverageModuleBuilder::default().build()); let emulator = Emulator::empty() .qemu(qemu) @@ -136,52 +135,56 @@ pub fn fuzz() { let snap = qemu.create_fast_snapshot(true); // The wrapped harness function, calling out to the LLVM-style harness - let mut harness = |emulator: &mut Emulator<_, _, _, _, _>, input: &BytesInput| { - let target = input.target_bytes(); - let mut buf = target.as_slice(); - let len = buf.len(); - unsafe { - if len > MAX_INPUT_SIZE { - buf = &buf[0..MAX_INPUT_SIZE]; - // len = MAX_INPUT_SIZE; + let mut harness = + |emulator: &mut Emulator<_, _, _, _, _>, _state: &mut _, input: &BytesInput| { + let target = input.target_bytes(); + let mut buf = target.as_slice(); + let len = buf.len(); + unsafe { + if len > MAX_INPUT_SIZE { + buf = &buf[0..MAX_INPUT_SIZE]; + // len = MAX_INPUT_SIZE; + } + + qemu.write_phys_mem(input_addr, buf); + + match emulator.qemu().run() { + Ok(QemuExitReason::Breakpoint(_)) => {} // continue execution, nothing to do there. + Ok(QemuExitReason::Timeout) => return ExitKind::Timeout, // timeout, propagate + Ok(QemuExitReason::End(QemuShutdownCause::HostSignal(signal))) => { + // will take care of cleanly stopping the fuzzer. + signal.handle() + } + + Err(QemuExitError::UnexpectedExit) => return ExitKind::Crash, + e => panic!("Unexpected QEMU exit: {e:?}."), + } + + // If the execution stops at any point other than the designated breakpoint (e.g. a breakpoint on a panic method) we consider it a crash + let mut pcs = (0..qemu.num_cpus()) + .map(|i| qemu.cpu_from_index(i)) + .map(|cpu| -> Result { cpu.read_reg(Regs::Pc) }); + let ret = match pcs + .find(|pc| (breakpoint..breakpoint + 5).contains(pc.as_ref().unwrap_or(&0))) + { + Some(_) => ExitKind::Ok, + None => ExitKind::Crash, + }; + + // OPTION 1: restore only the CPU state (registers et. al) + // for (i, s) in saved_cpu_states.iter().enumerate() { + // emu.cpu_from_index(i).restore_state(s); + // } + + // OPTION 2: restore a slow vanilla QEMU snapshot + // emu.load_snapshot("start", true); + + // OPTION 3: restore a fast devices+mem snapshot + qemu.restore_fast_snapshot(snap); + + ret } - - qemu.write_phys_mem(input_addr, buf); - - match emulator.qemu().run() { - Ok(QemuExitReason::Breakpoint(_)) => {} - Ok(QemuExitReason::End(QemuShutdownCause::HostSignal( - Signal::SigInterrupt, - ))) => process::exit(CTRL_C_EXIT), - Err(QemuExitError::UnexpectedExit) => return ExitKind::Crash, - _ => panic!("Unexpected QEMU exit."), - } - - // If the execution stops at any point other then the designated breakpoint (e.g. a breakpoint on a panic method) we consider it a crash - let mut pcs = (0..qemu.num_cpus()) - .map(|i| qemu.cpu_from_index(i)) - .map(|cpu| -> Result { cpu.read_reg(Regs::Pc) }); - let ret = match pcs - .find(|pc| (breakpoint..breakpoint + 5).contains(pc.as_ref().unwrap_or(&0))) - { - Some(_) => ExitKind::Ok, - None => ExitKind::Crash, - }; - - // OPTION 1: restore only the CPU state (registers et. al) - // for (i, s) in saved_cpu_states.iter().enumerate() { - // emu.cpu_from_index(i).restore_state(s); - // } - - // OPTION 2: restore a slow vanilla QEMU snapshot - // emu.load_snapshot("start", true); - - // OPTION 3: restore a fast devices+mem snapshot - qemu.restore_fast_snapshot(snap); - - ret - } - }; + }; // Create an observation channel using the coverage map let edges_observer = unsafe { diff --git a/fuzzers/qemu/qemu_systemmode/src/fuzzer_sync_exit.rs b/fuzzers/full-system/qemu_baremetal/src/fuzzer_sync_exit.rs similarity index 94% rename from fuzzers/qemu/qemu_systemmode/src/fuzzer_sync_exit.rs rename to fuzzers/full-system/qemu_baremetal/src/fuzzer_sync_exit.rs index 57b443ea67..6847e37f4f 100644 --- a/fuzzers/qemu/qemu_systemmode/src/fuzzer_sync_exit.rs +++ b/fuzzers/full-system/qemu_baremetal/src/fuzzer_sync_exit.rs @@ -30,10 +30,9 @@ use libafl_qemu::{ emu::Emulator, executor::QemuExecutor, modules::edges::{ - edges_map_mut_ptr, EdgeCoverageModule, EDGES_MAP_SIZE_IN_USE, MAX_EDGES_FOUND, + edges_map_mut_ptr, StdEdgeCoverageModule, EDGES_MAP_SIZE_IN_USE, MAX_EDGES_FOUND, }, }; - // use libafl_qemu::QemuSnapshotBuilder; for normal qemu snapshot pub fn fuzz() { @@ -54,7 +53,7 @@ pub fn fuzz() { let args: Vec = env::args().collect(); // Choose modules to use - let modules = tuple_list!(EdgeCoverageModule::default()); + let modules = tuple_list!(StdEdgeCoverageModule::builder().build()); let emu = Emulator::builder() .qemu_cli(args) @@ -65,9 +64,10 @@ pub fn fuzz() { println!("Devices = {:?}", devices); // The wrapped harness function, calling out to the LLVM-style harness - let mut harness = |emulator: &mut Emulator<_, _, _, _, _>, input: &BytesInput| unsafe { - emulator.run(input).unwrap().try_into().unwrap() - }; + let mut harness = + |emulator: &mut Emulator<_, _, _, _, _>, state: &mut _, input: &BytesInput| unsafe { + emulator.run(state, input).unwrap().try_into().unwrap() + }; // Create an observation channel using the coverage map let edges_observer = unsafe { diff --git a/fuzzers/qemu/qemu_systemmode/src/main.rs b/fuzzers/full-system/qemu_baremetal/src/main.rs similarity index 78% rename from fuzzers/qemu/qemu_systemmode/src/main.rs rename to fuzzers/full-system/qemu_baremetal/src/main.rs index 8ca48d6eb6..e03a33f3a8 100644 --- a/fuzzers/qemu/qemu_systemmode/src/main.rs +++ b/fuzzers/full-system/qemu_baremetal/src/main.rs @@ -1,6 +1,6 @@ //! A libfuzzer-like fuzzer using qemu for binary-only coverage -#[cfg(all(target_os = "linux", feature = "classic"))] -mod fuzzer_classic; +#[cfg(all(target_os = "linux", feature = "low_level"))] +mod fuzzer_low_level; #[cfg(all(target_os = "linux", feature = "breakpoint"))] mod fuzzer_breakpoint; @@ -10,8 +10,8 @@ mod fuzzer_sync_exit; #[cfg(target_os = "linux")] pub fn main() { - #[cfg(feature = "classic")] - fuzzer_classic::fuzz(); + #[cfg(feature = "low_level")] + fuzzer_low_level::fuzz(); #[cfg(feature = "breakpoint")] fuzzer_breakpoint::fuzz(); diff --git a/fuzzers/full-system/qemu_linux_kernel/.gitignore b/fuzzers/full-system/qemu_linux_kernel/.gitignore new file mode 100644 index 0000000000..a16dc44028 --- /dev/null +++ b/fuzzers/full-system/qemu_linux_kernel/.gitignore @@ -0,0 +1,2 @@ +*.qcow2 +corpus_gen/ diff --git a/fuzzers/full-system/qemu_linux_kernel/Cargo.toml b/fuzzers/full-system/qemu_linux_kernel/Cargo.toml new file mode 100644 index 0000000000..69e1dea4a7 --- /dev/null +++ b/fuzzers/full-system/qemu_linux_kernel/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "qemu_linux_kernel" +version = "0.13.2" +authors = [ + "Romain Malmain ", + "Dongjia Zhang ", +] +edition = "2021" + +[features] +shared = ["libafl_qemu/shared"] + +[profile.release] +incremental = true +debug = true +lto = "fat" +codegen-units = 1 + +[dependencies] +libafl = { path = "../../../../../libafl" } +libafl_bolts = { path = "../../../../../libafl_bolts" } +libafl_qemu = { path = "../../../../../libafl_qemu", features = [ + "x86_64", + "systemmode", + #"paranoid_debug" +] } +libafl_qemu_sys = { path = "../../../../../libafl_qemu/libafl_qemu_sys", features = [ + "x86_64", + "systemmode", + #"paranoid_debug" +] } +env_logger = "*" + +[build-dependencies] +libafl_qemu_build = { path = "../../../../../libafl_qemu/libafl_qemu_build" } diff --git a/fuzzers/full-system/qemu_linux_kernel/Makefile.toml b/fuzzers/full-system/qemu_linux_kernel/Makefile.toml new file mode 100644 index 0000000000..9fec43ecbe --- /dev/null +++ b/fuzzers/full-system/qemu_linux_kernel/Makefile.toml @@ -0,0 +1,183 @@ +env_scripts = [''' +#!@duckscript +profile = get_env PROFILE + +if eq ${profile} "dev" + set_env PROFILE_DIR debug +else + set_env PROFILE_DIR ${profile} +end +''', ''' +#!@duckscript +runs_on_ci = get_env RUN_ON_CI + +if ${runs_on_ci} + cargo_target_dir = get_env CARGO_MAKE_CRATE_TARGET_DIRECTORY + set_env TARGET_DIR ${cargo_target_dir} +end +'''] + +[env] +PROFILE = { value = "release", condition = { env_not_set = ["PROFILE"] } } +WORKING_DIR = "${CARGO_MAKE_WORKING_DIRECTORY}" +TARGET_DIR = "${CARGO_MAKE_CRATE_TARGET_DIRECTORY}" +LIBAFL_QEMU_CLONE_DIR = { value = "${CARGO_MAKE_CRATE_TARGET_DIRECTORY}/qemu-libafl-bridge", condition = { env_not_set = [ + "LIBAFL_QEMU_DIR", +] } } + +LINUX_BUILDER_URL = "git@github.com:AFLplusplus/linux-qemu-image-builder.git" +LINUX_BUILDER_DIR = { value = "${TARGET_DIR}/linux_builder", condition = { env_not_set = [ + "LINUX_BUILDER_DIR", +] } } +LINUX_BUILDER_OUT = "${LINUX_BUILDER_DIR}/output" + +[tasks.target_dir] +condition = { files_not_exist = [ + "${TARGET_DIR}", + "${TARGET_DIR}/runtime", + "${TARGET_DIR}/setup", +] } +script_runner = "@shell" +script = ''' +mkdir -p ${TARGET_DIR}/runtime +mkdir -p ${TARGET_DIR}/setup +''' + +[tasks.linux_builder_dir] +condition = { files_not_exist = ["${LINUX_BUILDER_DIR}"] } +script_runner = "@shell" +script = ''' +git clone ${LINUX_BUILDER_URL} ${LINUX_BUILDER_DIR} +''' + +[tasks.target] +dependencies = ["build", "linux_builder_dir"] +script_runner = "@shell" +script = ''' +git -C ${LINUX_BUILDER_DIR} pull + +# Copy setup & runtime fixed files +cp -r ${WORKING_DIR}/setup/* ${LINUX_BUILDER_DIR}/setup/ +cp -r ${WORKING_DIR}/runtime/* ${LINUX_BUILDER_DIR}/runtime/ + +# Copy generated libafl qemu header files to setup +cp ${TARGET_DIR}/${PROFILE_DIR}/include/* ${LINUX_BUILDER_DIR}/setup/ + +${LINUX_BUILDER_DIR}/build.sh +''' + +[tasks.target_update] +dependencies = ["build", "linux_builder_dir"] +script_runner = "@shell" +script = ''' +git -C ${LINUX_BUILDER_DIR} pull + +# Copy setup & runtime fixed files +cp -r ${WORKING_DIR}/setup/* ${LINUX_BUILDER_DIR}/setup/ +cp -r ${WORKING_DIR}/runtime/* ${LINUX_BUILDER_DIR}/runtime/ + +# Copy generated libafl qemu header files to setup +cp ${TARGET_DIR}/${PROFILE_DIR}/include/* ${LINUX_BUILDER_DIR}/setup/ + +${LINUX_BUILDER_DIR}/update.sh +''' + +[tasks.build] +dependencies = ["target_dir"] +command = "cargo" +args = ["build", "--profile", "${PROFILE}", "--target-dir", "${TARGET_DIR}"] + +[tasks.run] +dependencies = ["build"] +script_runner = "@shell" +script = ''' +rm -rf "${WORKING_DIR}/corpus_gen" + +# Find the bios dir of LibAFL QEMU +if [ ! -z "${LIBAFL_QEMU_DIR}" ]; then + LIBAFL_QEMU_BIOS_DIR=${LIBAFL_QEMU_DIR}/build/qemu-bundle/usr/local/share/qemu +else + LIBAFL_QEMU_BIOS_DIR=${LIBAFL_QEMU_CLONE_DIR}/build/qemu-bundle/usr/local/share/qemu +fi + +${TARGET_DIR}/${PROFILE_DIR}/qemu_systemmode_linux_kernel \ + -accel tcg \ + -m 4G \ + -drive if=pflash,format=raw,readonly=on,file="${LINUX_BUILDER_OUT}/OVMF_CODE.fd" \ + -drive if=pflash,format=raw,snapshot=off,file="${LINUX_BUILDER_OUT}/OVMF_VARS.fd" \ + -blockdev filename="${LINUX_BUILDER_OUT}/linux.qcow2",node-name=storage,driver=file \ + -blockdev driver=qcow2,file=storage,node-name=disk \ + -device virtio-scsi-pci,id=scsi0 \ + -device scsi-hd,bus=scsi0.0,drive=disk,id=virtio-disk0,bootindex=1 \ + -L "${LIBAFL_QEMU_BIOS_DIR}" \ + -nographic \ + -monitor null \ + -serial null \ + -snapshot +''' + +[tasks.debug] +dependencies = ["build"] +command = "time" +args = [ + "${TARGET_DIR}/${PROFILE_DIR}/qemu_systemmode_linux_kernel", + "-accel", + "kvm", + "-m", + "4G", + "-drive", + "if=pflash,format=raw,readonly=on,file=${LINUX_BUILDER_OUT}/OVMF_CODE.fd", + "-drive", + "if=pflash,format=raw,snapshot=off,file=${LINUX_BUILDER_OUT}/OVMF_VARS.fd", + "-blockdev", + "filename=${LINUX_BUILDER_OUT}/linux.qcow2,node-name=storage,driver=file", + "-blockdev", + "driver=qcow2,file=storage,node-name=disk", + "-device", + "virtio-scsi-pci,id=scsi0", + "-device", + "scsi-hd,bus=scsi0.0,drive=disk,id=virtio-disk0,bootindex=1", + "-L", + "${LIBAFL_QEMU_DIR}/build/qemu-bundle/usr/local/share/qemu", + "-snapshot", +] + +[tasks.perf] +command = "perf" +args = [ + "record", + "--call-graph", + "dwarf", + "${TARGET_DIR}/${PROFILE_DIR}/qemu_systemmode_linux_kernel", + "-accel", + "tcg", + "-m", + "4G", + "-drive", + "if=pflash,format=raw,readonly=on,file=${LINUX_BUILDER_OUT}/OVMF_CODE.fd", + "-drive", + "if=pflash,format=raw,snapshot=off,file=${LINUX_BUILDER_OUT}/OVMF_VARS.fd", + "-blockdev", + "filename=${LINUX_BUILDER_OUT}/linux.qcow2,node-name=storage,driver=file", + "-blockdev", + "driver=qcow2,file=storage,node-name=disk", + "-device", + "virtio-scsi-pci,id=scsi0", + "-device", + "scsi-hd,bus=scsi0.0,drive=disk,id=virtio-disk0,bootindex=1", + "-L", + "${LIBAFL_QEMU_DIR}/build/qemu-bundle/usr/local/share/qemu", + "-snapshot", + # "-icount", "shift=auto,align=off,sleep=off", + # "-monitor", "null", + # "-serial", "null", + # "-nographic", +] + +[tasks.clean] +clear = true +script_runner = "@shell" +script = ''' +rm -rf ${CARGO_MAKE_CRATE_TARGET_DIRECTORY} +cargo clean +''' diff --git a/fuzzers/full-system/qemu_linux_kernel/README.md b/fuzzers/full-system/qemu_linux_kernel/README.md new file mode 100644 index 0000000000..2ca2e61569 --- /dev/null +++ b/fuzzers/full-system/qemu_linux_kernel/README.md @@ -0,0 +1,33 @@ +# LibAFL QEMU Systemmode for Linux kernel fuzzing + +This folder contains an example linux kernel fuzzer using qemu systemmode. + +## Prerequisite + +TODO + +## Build + +To build the target: +```bash +cargo make target +``` + +To build the fuzzer: +```bash +cargo make build +``` + +It is also possible to update the target if it only changes "runtime" files. +This is equivalent to rebuilding the target, it is only faster since it does not need to rebuild the image from scratch. +Check [The linux builder repository](https://github.com/AFLplusplus/linux-qemu-image-builder.git) for more details on the specifics. +```bash +cargo make target_update +``` + +## Run + +To run the fuzzer: +```bash +cargo make run +``` \ No newline at end of file diff --git a/fuzzers/full-system/qemu_linux_kernel/build.rs b/fuzzers/full-system/qemu_linux_kernel/build.rs new file mode 100644 index 0000000000..05933c4fee --- /dev/null +++ b/fuzzers/full-system/qemu_linux_kernel/build.rs @@ -0,0 +1,5 @@ +use libafl_qemu_build::build_libafl_qemu; + +fn main() { + build_libafl_qemu(); +} diff --git a/fuzzers/full-system/qemu_linux_kernel/corpus/random b/fuzzers/full-system/qemu_linux_kernel/corpus/random new file mode 100644 index 0000000000..25175d51d3 --- /dev/null +++ b/fuzzers/full-system/qemu_linux_kernel/corpus/random @@ -0,0 +1 @@ +ÿy¯»Jv•ŒÅÈ lÅp†àZGÖ…rÆs‚YÏñ‘Ë—CMRÕº}÷S7;IÉo¿7È6ælò1Þ˜1R¯¬ó×Èý^ÎŒp¬ã¯>Gº&_¬ü˜|1½¾;â¥éðÔñrœçžoþ4â¼Æ¯ÍUÑE<`ùº²ºÌLò"Œó6VÆ·kÙ4/³"–ötë÷Êf7ÖF¯°ÀÞŽdþ]Ü®%õ|8•#ýwµåÌNU›ƒnù‹8€û%¼4ÇoÎÿË—– diff --git a/fuzzers/full-system/qemu_linux_kernel/corpus/zero b/fuzzers/full-system/qemu_linux_kernel/corpus/zero new file mode 100644 index 0000000000000000000000000000000000000000..112363ac1917b417ffbd7f376ca786a1e5fa7490 GIT binary patch literal 5 McmZQzU|`?^000jF3jhEB literal 0 HcmV?d00001 diff --git a/fuzzers/full-system/qemu_linux_kernel/runtime/entrypoint.sh b/fuzzers/full-system/qemu_linux_kernel/runtime/entrypoint.sh new file mode 100644 index 0000000000..3d2024e4f7 --- /dev/null +++ b/fuzzers/full-system/qemu_linux_kernel/runtime/entrypoint.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +insmod /setup/harness.ko +/setup/user diff --git a/fuzzers/full-system/qemu_linux_kernel/setup/Makefile b/fuzzers/full-system/qemu_linux_kernel/setup/Makefile new file mode 100644 index 0000000000..a46095abea --- /dev/null +++ b/fuzzers/full-system/qemu_linux_kernel/setup/Makefile @@ -0,0 +1,9 @@ +obj-m += harness.o + +all: + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules + gcc -Wall -Werror -o user user.c + +clean: + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean + rm user \ No newline at end of file diff --git a/fuzzers/full-system/qemu_linux_kernel/setup/harness.c b/fuzzers/full-system/qemu_linux_kernel/setup/harness.c new file mode 100644 index 0000000000..c7d58c78f2 --- /dev/null +++ b/fuzzers/full-system/qemu_linux_kernel/setup/harness.c @@ -0,0 +1,170 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "x509-parser.h" +#include "libafl_qemu.h" + +#define MAX_DEV 1 + +#define BUF_SIZE 4096 + +static int harness_open(struct inode *inode, struct file *file); +static int harness_release(struct inode *inode, struct file *file); + +static const struct file_operations harness_fops = { + .owner = THIS_MODULE, + .open = harness_open, + .release = harness_release, +}; + +struct mychar_device_data { + struct cdev cdev; +}; + +static int dev_major = 0; +static struct class *harness_class = NULL; +static struct mychar_device_data harness_data; + +#define KPROBE_PRE_HANDLER(fname) \ + static int __kprobes fname(struct kprobe *p, struct pt_regs *regs) + +long unsigned int kln_addr = 0; +unsigned long (*kln_pointer)(const char *name) = NULL; + +static struct kprobe kp0, kp1; + +KPROBE_PRE_HANDLER(handler_pre0) { + kln_addr = (--regs->ip); + + return 0; +} + +KPROBE_PRE_HANDLER(handler_pre1) { + return 0; +} + +static int do_register_kprobe(struct kprobe *kp, char *symbol_name, + void *handler) { + int ret; + + kp->symbol_name = symbol_name; + kp->pre_handler = handler; + + ret = register_kprobe(kp); + if (ret < 0) { + pr_err("register_probe() for symbol %s failed, returned %d\n", symbol_name, + ret); + return ret; + } + + pr_info("Planted kprobe for symbol %s at %p\n", symbol_name, kp->addr); + + return ret; +} + +// Find kallsyms_lookup_name +// taken from +// https://github.com/zizzu0/LinuxKernelModules/blob/main/FindKallsymsLookupName.c +static int harness_find_kallsyms_lookup(void) { + int ret; + + ret = do_register_kprobe(&kp0, "kallsyms_lookup_name", handler_pre0); + if (ret < 0) return ret; + + ret = do_register_kprobe(&kp1, "kallsyms_lookup_name", handler_pre1); + if (ret < 0) { + unregister_kprobe(&kp0); + return ret; + } + + unregister_kprobe(&kp0); + unregister_kprobe(&kp1); + + lqprintf("kallsyms_lookup_name address = 0x%lx\n", kln_addr); + + kln_pointer = (unsigned long (*)(const char *name))kln_addr; + + return ret; +} + +static int harness_uevent(const struct device *dev, + struct kobj_uevent_env *env) { + add_uevent_var(env, "DEVMODE=%#o", 0666); + return 0; +} + +static int __init harness_init(void) { + int err; + dev_t dev; + + err = alloc_chrdev_region(&dev, 0, 1, "harness"); + + dev_major = MAJOR(dev); + + harness_class = class_create("harness"); + harness_class->dev_uevent = harness_uevent; + + cdev_init(&harness_data.cdev, &harness_fops); + harness_data.cdev.owner = THIS_MODULE; + + cdev_add(&harness_data.cdev, MKDEV(dev_major, 0), 1); + + device_create(harness_class, NULL, MKDEV(dev_major, 0), NULL, "harness"); + + harness_find_kallsyms_lookup(); + + return 0; +} + +static void __exit harness_exit(void) { + device_destroy(harness_class, MKDEV(dev_major, 0)); + + class_unregister(harness_class); + class_destroy(harness_class); + + unregister_chrdev_region(MKDEV(dev_major, 0), MINORMASK); +} + +static int harness_open(struct inode *inode, struct file *file) { + int ret; + lqprintf("harness: Device open\n"); + + char *data = kzalloc(BUF_SIZE, GFP_KERNEL); + data[0] = 0xff; // init page + + unsigned long x509_fn_addr = kln_pointer("x509_cert_parse"); + lqprintf("harness: x509 fn addr: 0x%lx\n", x509_fn_addr); + + // TODO: better filtering... + libafl_qemu_trace_vaddr_size(x509_fn_addr, 0x1000); + + libafl_qemu_test(); + + u64 buf_size = libafl_qemu_start_virt(data, BUF_SIZE); + + struct x509_certificate *cert_ret = x509_cert_parse(data, buf_size); + + libafl_qemu_end(LIBAFL_QEMU_END_OK); + + return 0; +} + +static int harness_release(struct inode *inode, struct file *file) { + lqprintf("harness: Device close\n"); + return 0; +} + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Slasti Mormanti"); + +module_init(harness_init); +module_exit(harness_exit); diff --git a/fuzzers/full-system/qemu_linux_kernel/setup/setup.sh b/fuzzers/full-system/qemu_linux_kernel/setup/setup.sh new file mode 100644 index 0000000000..56fafcc8b6 --- /dev/null +++ b/fuzzers/full-system/qemu_linux_kernel/setup/setup.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +cd /setup +make clean +make -j +ls /setup \ No newline at end of file diff --git a/fuzzers/full-system/qemu_linux_kernel/setup/user.c b/fuzzers/full-system/qemu_linux_kernel/setup/user.c new file mode 100644 index 0000000000..4d3828f410 --- /dev/null +++ b/fuzzers/full-system/qemu_linux_kernel/setup/user.c @@ -0,0 +1,19 @@ +#include +#include +#include +#include +#include + +int main() { + const char *device = "/dev/harness"; + int fd; + + // Open the device + fd = open(device, O_RDWR); + if (fd == -1) { return 1; } + + // Close the device + if (close(fd) == -1) { return 1; } + + return 0; +} \ No newline at end of file diff --git a/fuzzers/full-system/qemu_linux_kernel/setup/x509-parser.h b/fuzzers/full-system/qemu_linux_kernel/setup/x509-parser.h new file mode 100644 index 0000000000..7d4950aad0 --- /dev/null +++ b/fuzzers/full-system/qemu_linux_kernel/setup/x509-parser.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* X.509 certificate parser + * + * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + */ + +// From https://lore.kernel.org/kvm/20240304065703.GA24373@wunner.de/T/ + +#include +#include +#include + +struct x509_certificate { + struct x509_certificate *next; + struct x509_certificate *signer; /* Certificate that signed this one */ + struct public_key *pub; /* Public key details */ + struct public_key_signature *sig; /* Signature parameters */ + char *issuer; /* Name of certificate issuer */ + char *subject; /* Name of certificate subject */ + struct asymmetric_key_id *id; /* Issuer + Serial number */ + struct asymmetric_key_id *skid; /* Subject + subjectKeyId (optional) */ + time64_t valid_from; + time64_t valid_to; + const void *tbs; /* Signed data */ + unsigned tbs_size; /* Size of signed data */ + unsigned raw_sig_size; /* Size of signature */ + const void *raw_sig; /* Signature data */ + const void *raw_serial; /* Raw serial number in ASN.1 */ + unsigned raw_serial_size; + unsigned raw_issuer_size; + const void *raw_issuer; /* Raw issuer name in ASN.1 */ + const void *raw_subject; /* Raw subject name in ASN.1 */ + unsigned raw_subject_size; + unsigned raw_skid_size; + const void *raw_skid; /* Raw subjectKeyId in ASN.1 */ + unsigned index; + bool seen; /* Infinite recursion prevention */ + bool verified; + bool self_signed; /* T if self-signed (check unsupported_sig too) */ + bool unsupported_sig; /* T if signature uses unsupported crypto */ + bool blacklisted; +}; + +struct x509_certificate *x509_cert_parse(const void *data, size_t datalen); +void x509_free_certificate(struct x509_certificate *cert); \ No newline at end of file diff --git a/fuzzers/full-system/qemu_linux_kernel/src/fuzzer.rs b/fuzzers/full-system/qemu_linux_kernel/src/fuzzer.rs new file mode 100644 index 0000000000..3e28852bed --- /dev/null +++ b/fuzzers/full-system/qemu_linux_kernel/src/fuzzer.rs @@ -0,0 +1,211 @@ +//! A fuzzer using qemu in systemmode for binary-only coverage of linux + +use core::{ptr::addr_of_mut, time::Duration}; +use std::{env, path::PathBuf, process}; + +use libafl::{ + corpus::{Corpus, InMemoryOnDiskCorpus, OnDiskCorpus}, + events::{launcher::Launcher, EventConfig}, + executors::ShadowExecutor, + feedback_or, feedback_or_fast, + feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback}, + fuzzer::{Fuzzer, StdFuzzer}, + inputs::BytesInput, + monitors::MultiMonitor, + mutators::{ + scheduled::{havoc_mutations, StdScheduledMutator}, + I2SRandReplaceBinonly, + }, + observers::{CanTrack, HitcountsMapObserver, TimeObserver, VariableMapObserver}, + schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler}, + stages::{ShadowTracingStage, StdMutationalStage}, + state::{HasCorpus, StdState}, + Error, +}; +use libafl_bolts::{ + core_affinity::Cores, + current_nanos, + ownedref::OwnedMutSlice, + rands::StdRand, + shmem::{ShMemProvider, StdShMemProvider}, + tuples::tuple_list, +}; +use libafl_qemu::{ + emu::Emulator, + executor::QemuExecutor, + modules::{ + cmplog::CmpLogObserver, + edges::{ + edges_map_mut_ptr, StdEdgeCoverageClassicModule, EDGES_MAP_SIZE_MAX, MAX_EDGES_FOUND, + }, + CmpLogModule, + }, + // StdEmulatorDriver +}; + +pub fn fuzz() { + env_logger::init(); + + if let Ok(s) = env::var("FUZZ_SIZE") { + str::parse::(&s).expect("FUZZ_SIZE was not a number"); + }; + // Hardcoded parameters + let timeout = Duration::from_secs(60000); + let broker_port = 1337; + let cores = Cores::from_cmdline("1").unwrap(); + let corpus_dirs = [PathBuf::from("./corpus")]; + let objective_dir = PathBuf::from("./crashes"); + + let mut run_client = |state: Option<_>, mut mgr, _core_id| { + // Initialize QEMU + let args: Vec = env::args().collect(); + + // Choose modules to use + let modules = tuple_list!( + StdEdgeCoverageClassicModule::builder().build(), + CmpLogModule::default(), + ); + + // let driver = StdEmulatorDriver::builder() + // .print_commands(true) + // .build(); + + let emu = Emulator::builder() + .qemu_cli(args) + .modules(modules) + // .driver(driver) + .build()?; + + let devices = emu.list_devices(); + println!("Devices = {:?}", devices); + + // The wrapped harness function, calling out to the LLVM-style harness + let mut harness = + |emulator: &mut Emulator<_, _, _, _, _>, state: &mut _, input: &BytesInput| unsafe { + emulator.run(state, input).unwrap().try_into().unwrap() + }; + + // Create an observation channel using the coverage map + let edges_observer = unsafe { + HitcountsMapObserver::new(VariableMapObserver::from_mut_slice( + "edges", + OwnedMutSlice::from_raw_parts_mut(edges_map_mut_ptr(), EDGES_MAP_SIZE_MAX), + addr_of_mut!(MAX_EDGES_FOUND), + )) + .track_indices() + }; + + // Create an observation channel to keep track of the execution time + let time_observer = TimeObserver::new("time"); + + // Create a cmplog observer + let cmplog_observer = CmpLogObserver::new("cmplog", true); + + // Feedback to rate the interestingness of an input + // This one is composed by two Feedbacks in OR + let mut feedback = feedback_or!( + // New maximization map feedback linked to the edges observer and the feedback state + MaxMapFeedback::new(&edges_observer), + // Time feedback, this one does not need a feedback state + TimeFeedback::new(&time_observer) + ); + + // A feedback to choose if an input is a solution or not + let mut objective = feedback_or_fast!(CrashFeedback::new(), TimeoutFeedback::new()); + + // If not restarting, create a State from scratch + let mut state = state.unwrap_or_else(|| { + StdState::new( + // RNG + StdRand::with_seed(current_nanos()), + // Corpus that will be evolved, we keep it in memory for performance + InMemoryOnDiskCorpus::new("corpus_gen").unwrap(), + // Corpus in which we store solutions (crashes in this example), + // on disk so the user can get them after stopping the fuzzer + OnDiskCorpus::new(objective_dir.clone()).unwrap(), + // States of the feedbacks. + // The feedbacks can report the data that should persist in the State. + &mut feedback, + // Same for objective feedbacks + &mut objective, + ) + .unwrap() + }); + + // A minimization+queue policy to get testcasess from the corpus + let scheduler = + IndexesLenTimeMinimizerScheduler::new(&edges_observer, QueueScheduler::new()); + + // A fuzzer with feedbacks and a corpus scheduler + let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); + + // Create a QEMU in-process executor + let mut executor = QemuExecutor::new( + emu, + &mut harness, + tuple_list!(edges_observer, time_observer), + &mut fuzzer, + &mut state, + &mut mgr, + timeout, + ) + .expect("Failed to create QemuExecutor"); + + // Instead of calling the timeout handler and restart the process, trigger a breakpoint ASAP + executor.break_on_timeout(); + + let mut executor = ShadowExecutor::new(executor, tuple_list!(cmplog_observer)); + + if state.must_load_initial_inputs() { + state + .load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &corpus_dirs) + .unwrap_or_else(|_| { + println!("Failed to load initial corpus at {:?}", &corpus_dirs); + process::exit(0); + }); + println!("We imported {} inputs from disk.", state.corpus().count()); + } + + // a CmpLog-based mutational stage + let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!( + I2SRandReplaceBinonly::new() + ))); + + // Setup an havoc mutator with a mutational stage + let tracing = ShadowTracingStage::new(&mut executor); + let mutator = StdScheduledMutator::new(havoc_mutations()); + let mut stages = tuple_list!(tracing, i2s, StdMutationalStage::new(mutator),); + + match fuzzer.fuzz_loop(&mut stages, &mut executor, &mut state, &mut mgr) { + Ok(_) | Err(Error::ShuttingDown) => Ok(()), + Err(e) => return Err(e), + } + }; + + // The shared memory allocator + let shmem_provider = StdShMemProvider::new().expect("Failed to init shared memory"); + + // The stats reporter for the broker + let monitor = MultiMonitor::new(|s| println!("{s}")); + + // let monitor = SimpleMonitor::new(|s| println!("{s}")); + // let mut mgr = SimpleEventManager::new(monitor); + // run_client(None, mgr, 0); + + // Build and run a Launcher + match Launcher::builder() + .shmem_provider(shmem_provider) + .broker_port(broker_port) + .configuration(EventConfig::from_build_id()) + .monitor(monitor) + .run_client(&mut run_client) + .cores(&cores) + // .stdout_file(Some("/dev/null")) + .build() + .launch() + { + Ok(()) => (), + Err(Error::ShuttingDown) => println!("Fuzzing stopped by user. Good bye."), + Err(err) => panic!("Failed to run launcher: {err:?}"), + } +} diff --git a/fuzzers/full-system/qemu_linux_kernel/src/main.rs b/fuzzers/full-system/qemu_linux_kernel/src/main.rs new file mode 100644 index 0000000000..b2cf41cb60 --- /dev/null +++ b/fuzzers/full-system/qemu_linux_kernel/src/main.rs @@ -0,0 +1,14 @@ +//! A systemmode linux kernel example +//! +#[cfg(all(target_os = "linux"))] +mod fuzzer; + +#[cfg(target_os = "linux")] +pub fn main() { + fuzzer::fuzz(); +} + +#[cfg(not(target_os = "linux"))] +pub fn main() { + panic!("qemu and libafl_qemu is only supported on linux!"); +} diff --git a/fuzzers/full-system/qemu_linux_process/.gitignore b/fuzzers/full-system/qemu_linux_process/.gitignore new file mode 100644 index 0000000000..a16dc44028 --- /dev/null +++ b/fuzzers/full-system/qemu_linux_process/.gitignore @@ -0,0 +1,2 @@ +*.qcow2 +corpus_gen/ diff --git a/fuzzers/full-system/qemu_linux_process/Cargo.toml b/fuzzers/full-system/qemu_linux_process/Cargo.toml new file mode 100644 index 0000000000..f60e43b740 --- /dev/null +++ b/fuzzers/full-system/qemu_linux_process/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "qemu_linux_process" +version = "0.13.2" +authors = ["Romain Malmain "] +edition = "2021" + +[features] +shared = ["libafl_qemu/shared"] + +[profile.release] +incremental = true +debug = true +lto = "fat" +codegen-units = 1 + +[dependencies] +libafl = { path = "../../../../../libafl" } +libafl_bolts = { path = "../../../../../libafl_bolts" } +libafl_qemu = { path = "../../../../../libafl_qemu", features = [ + "x86_64", + "systemmode", + # "paranoid_debug" +] } +libafl_qemu_sys = { path = "../../../../../libafl_qemu/libafl_qemu_sys", features = [ + "x86_64", + "systemmode", + # "paranoid_debug" +] } +env_logger = "*" + +[build-dependencies] +libafl_qemu_build = { path = "../../../../../libafl_qemu/libafl_qemu_build" } diff --git a/fuzzers/full-system/qemu_linux_process/Makefile.toml b/fuzzers/full-system/qemu_linux_process/Makefile.toml new file mode 100644 index 0000000000..8317a1ff1a --- /dev/null +++ b/fuzzers/full-system/qemu_linux_process/Makefile.toml @@ -0,0 +1,202 @@ +env_scripts = [''' +#!@duckscript +profile = get_env PROFILE + +if eq ${profile} "dev" + set_env PROFILE_DIR debug +else + set_env PROFILE_DIR ${profile} +end +''', ''' +#!@duckscript +runs_on_ci = get_env RUN_ON_CI + +if ${runs_on_ci} + cargo_target_dir = get_env CARGO_MAKE_CRATE_TARGET_DIRECTORY + set_env TARGET_DIR ${cargo_target_dir} + set_env KERNEL ${cargo_target_dir}/example.elf +end +'''] + +[env] +PROFILE = { value = "release", condition = { env_not_set = ["PROFILE"] } } +WORKING_DIR = "${CARGO_MAKE_WORKING_DIRECTORY}" +TARGET_DIR = "${CARGO_MAKE_CRATE_TARGET_DIRECTORY}" +LIBAFL_QEMU_CLONE_DIR = { value = "${CARGO_MAKE_CRATE_TARGET_DIRECTORY}/qemu-libafl-bridge", condition = { env_not_set = [ + "LIBAFL_QEMU_DIR", +] } } + +LINUX_BUILDER_URL = "git@github.com:AFLplusplus/linux-qemu-image-builder.git" +LINUX_BUILDER_DIR = { value = "${TARGET_DIR}/linux_builder", condition = { env_not_set = [ + "LINUX_BUILDER_DIR", +] } } +LINUX_BUILDER_OUT = "${LINUX_BUILDER_DIR}/output" + +[tasks.target_dir] +condition = { files_not_exist = [ + "${TARGET_DIR}", + "${TARGET_DIR}/runtime", + "${TARGET_DIR}/setup", +] } +script_runner = "@shell" +script = ''' +mkdir -p ${TARGET_DIR}/runtime +mkdir -p ${TARGET_DIR}/setup +''' + +[tasks.linux_builder_dir] +condition = { files_not_exist = ["${LINUX_BUILDER_DIR}"] } +script_runner = "@shell" +script = ''' +git clone ${LINUX_BUILDER_URL} ${LINUX_BUILDER_DIR} +''' + +[tasks.compile_target] +dependencies = ["target_dir", "linux_builder_dir"] +command = "clang" +args = [ + "-O0", + "-static", + "${WORKING_DIR}/example/harness.c", + "-o", + "${TARGET_DIR}/runtime/harness", + "-I", + "${TARGET_DIR}/${PROFILE_DIR}/include", +] + +[tasks.target] +dependencies = ["build", "compile_target"] +script_runner = "@shell" +script = ''' +git -C ${LINUX_BUILDER_DIR} pull + +# Copy generated harness +cp -r ${TARGET_DIR}/runtime/* ${LINUX_BUILDER_DIR}/runtime/ + +# Copy setup & runtime fixed files +cp -r ${WORKING_DIR}/setup/* ${LINUX_BUILDER_DIR}/setup/ +cp -r ${WORKING_DIR}/runtime/* ${LINUX_BUILDER_DIR}/runtime/ + +${LINUX_BUILDER_DIR}/build.sh +''' + +[tasks.target_update] +dependencies = ["build", "compile_target"] +script_runner = "@shell" +script = ''' +# Copy generated harness +cp -r ${TARGET_DIR}/runtime/* ${LINUX_BUILDER_DIR}/runtime/ + +# Copy setup & runtime fixed files +cp -r ${WORKING_DIR}/runtime/* ${LINUX_BUILDER_DIR}/runtime/ + +${LINUX_BUILDER_DIR}/update.sh +''' + +[tasks.build] +dependencies = ["target_dir"] +command = "cargo" +args = ["build", "--profile", "${PROFILE}", "--target-dir", "${TARGET_DIR}"] + +[tasks.run] +dependencies = ["build"] +script_runner = "@shell" +script = ''' +rm -rf "${WORKING_DIR}/corpus_gen" + +# Find the bios dir of LibAFL QEMU +if [ ! -z "${LIBAFL_QEMU_DIR}" ]; then + LIBAFL_QEMU_BIOS_DIR=${LIBAFL_QEMU_DIR}/build/qemu-bundle/usr/local/share/qemu +else + LIBAFL_QEMU_BIOS_DIR=${LIBAFL_QEMU_CLONE_DIR}/build/qemu-bundle/usr/local/share/qemu +fi + +cp ${LINUX_BUILDER_OUT}/OVMF_CODE.fd ${LINUX_BUILDER_OUT}/OVMF_CODE.fd.clone +cp ${LINUX_BUILDER_OUT}/OVMF_VARS.fd ${LINUX_BUILDER_OUT}/OVMF_VARS.fd.clone +cp ${LINUX_BUILDER_OUT}/linux.qcow2 ${LINUX_BUILDER_OUT}/linux.qcow2.clone + +${TARGET_DIR}/${PROFILE_DIR}/qemu_linux_process \ + -accel tcg \ + -m 4G \ + -drive if=pflash,format=raw,file="${LINUX_BUILDER_OUT}/OVMF_CODE.fd" `# OVMF code pflash` \ + -drive if=pflash,format=raw,file="${LINUX_BUILDER_OUT}/OVMF_VARS.fd" `# OVMF vars pflash` \ + -device virtio-scsi-pci,id=scsi0 `# SCSI bus` \ + -device scsi-hd,bus=scsi0.0,drive=disk,id=virtio-disk0,bootindex=1 \ + -blockdev driver=file,filename="${LINUX_BUILDER_OUT}/linux.qcow2",node-name=storage `# Backend file of "disk"` \ + -blockdev driver=qcow2,file=storage,node-name=disk `# QCOW2 "disk"` \ + -L "${LIBAFL_QEMU_BIOS_DIR}" \ + -nographic \ + -monitor null \ + -serial null + + # -snapshot + #-blockdev driver=syx-cow-cache,file=storage,node-name=storage-syx \ +# gdb --args +''' + +[tasks.debug] +dependencies = ["build"] +command = "time" +args = [ + "${TARGET_DIR}/${PROFILE_DIR}/qemu_linux_process", + "-accel", + "tcg", + "-m", + "4G", + "-drive", + "if=pflash,format=raw,file=${LINUX_BUILDER_OUT}/OVMF_CODE.fd", + "-drive", + "if=pflash,format=raw,file=${LINUX_BUILDER_OUT}/OVMF_VARS.fd", + "-blockdev", + "filename=${LINUX_BUILDER_OUT}/linux.qcow2,node-name=storage,driver=file", + "-blockdev", + "driver=qcow2,file=storage,node-name=disk", + "-device", + "virtio-scsi-pci,id=scsi0", + "-device", + "scsi-hd,bus=scsi0.0,drive=disk,id=virtio-disk0,bootindex=1", + "-L", + "${LIBAFL_QEMU_DIR}/build/qemu-bundle/usr/local/share/qemu", + + #"-snapshot", +] + +[tasks.perf] +command = "perf" +args = [ + "record", + "--call-graph", + "dwarf", + "${TARGET_DIR}/${PROFILE_DIR}/qemu_linux_process", + "-accel", + "tcg", + "-m", + "4G", + "-drive", + "if=pflash,format=raw,readonly=on,file=${LINUX_BUILDER_OUT}/OVMF_CODE.fd", + "-drive", + "if=pflash,format=raw,snapshot=off,file=${LINUX_BUILDER_OUT}/OVMF_VARS.fd", + "-blockdev", + "filename=${LINUX_BUILDER_OUT}/linux.qcow2,node-name=storage,driver=file", + "-blockdev", + "driver=qcow2,file=storage,node-name=disk", + "-device", + "virtio-scsi-pci,id=scsi0", + "-device", + "scsi-hd,bus=scsi0.0,drive=disk,id=virtio-disk0,bootindex=1", + "-L", + "${LIBAFL_QEMU_DIR}/build/qemu-bundle/usr/local/share/qemu", + "-snapshot", + # "-icount", "shift=auto,align=off,sleep=off", + # "-monitor", "null", + # "-serial", "null", + # "-nographic", +] + +[tasks.clean] +clear = true +script_runner = "@shell" +script = ''' +rm -rf ${CARGO_MAKE_CRATE_TARGET_DIRECTORY} +cargo clean +''' diff --git a/fuzzers/full-system/qemu_linux_process/README.md b/fuzzers/full-system/qemu_linux_process/README.md new file mode 100644 index 0000000000..204d73a3b1 --- /dev/null +++ b/fuzzers/full-system/qemu_linux_process/README.md @@ -0,0 +1,34 @@ +# LibAFL QEMU Systemmode for Linux process fuzzing + +This folder contains an example linux process fuzzer using qemu systemmode. +This is demo, most of the time for classic linux process fuzzing, it is better to use a more conventional method. + +## Prerequisite + +TODO + +## Build + +To build the target: +```bash +cargo make target +``` + +To build the fuzzer: +```bash +cargo make build +``` + +It is also possible to update the target if it only changes "runtime" files. +This is equivalent to rebuilding the target, it is only faster since it does not need to rebuild the image from scratch. +Check [The linux builder repository](https://github.com/AFLplusplus/linux-qemu-image-builder.git) for more details on the specifics. +```bash +cargo make target_update +``` + +## Run + +To run the fuzzer: +```bash +cargo make run +``` \ No newline at end of file diff --git a/fuzzers/full-system/qemu_linux_process/build.rs b/fuzzers/full-system/qemu_linux_process/build.rs new file mode 100644 index 0000000000..05933c4fee --- /dev/null +++ b/fuzzers/full-system/qemu_linux_process/build.rs @@ -0,0 +1,5 @@ +use libafl_qemu_build::build_libafl_qemu; + +fn main() { + build_libafl_qemu(); +} diff --git a/fuzzers/full-system/qemu_linux_process/corpus/random b/fuzzers/full-system/qemu_linux_process/corpus/random new file mode 100644 index 0000000000..25175d51d3 --- /dev/null +++ b/fuzzers/full-system/qemu_linux_process/corpus/random @@ -0,0 +1 @@ +ÿy¯»Jv•ŒÅÈ lÅp†àZGÖ…rÆs‚YÏñ‘Ë—CMRÕº}÷S7;IÉo¿7È6ælò1Þ˜1R¯¬ó×Èý^ÎŒp¬ã¯>Gº&_¬ü˜|1½¾;â¥éðÔñrœçžoþ4â¼Æ¯ÍUÑE<`ùº²ºÌLò"Œó6VÆ·kÙ4/³"–ötë÷Êf7ÖF¯°ÀÞŽdþ]Ü®%õ|8•#ýwµåÌNU›ƒnù‹8€û%¼4ÇoÎÿË—– diff --git a/fuzzers/full-system/qemu_linux_process/corpus/zero b/fuzzers/full-system/qemu_linux_process/corpus/zero new file mode 100644 index 0000000000000000000000000000000000000000..112363ac1917b417ffbd7f376ca786a1e5fa7490 GIT binary patch literal 5 McmZQzU|`?^000jF3jhEB literal 0 HcmV?d00001 diff --git a/fuzzers/full-system/qemu_linux_process/example/harness.c b/fuzzers/full-system/qemu_linux_process/example/harness.c new file mode 100644 index 0000000000..fccc5d2b68 --- /dev/null +++ b/fuzzers/full-system/qemu_linux_process/example/harness.c @@ -0,0 +1,44 @@ +// Adapted from +// https://github.com/google/fuzzing/blob/master/tutorial/libFuzzer/fuzz_me.cc +#include +#include +#include +#include + +#include + +bool FuzzMe(const uint8_t *Data, size_t DataSize) { + if (DataSize > 3) { + if (Data[0] == 'F') { + if (Data[1] == 'U') { + if (Data[2] == 'Z') { + if (Data[3] == 'Z') { return true; } + } + } + } + } + + return false; +} + +int main() { + // Prepare some space for the input + uint8_t Data[10] = {0}; + + lqprintf("Fuzzing starts\n"); + + // Start fuzzer here + size_t len = libafl_qemu_start_virt(Data, 10); + + // Call the target + bool ret = FuzzMe(Data, len); + + // Return to fuzzer + if (ret) { + // "Bug" has been triggered + libafl_qemu_end(LIBAFL_QEMU_END_CRASH); + } else { + // Everything went well + libafl_qemu_end(LIBAFL_QEMU_END_OK); + } +} \ No newline at end of file diff --git a/fuzzers/full-system/qemu_linux_process/runtime/entrypoint.sh b/fuzzers/full-system/qemu_linux_process/runtime/entrypoint.sh new file mode 100644 index 0000000000..876c015c63 --- /dev/null +++ b/fuzzers/full-system/qemu_linux_process/runtime/entrypoint.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +/runtime/harness + +# shutdown now \ No newline at end of file diff --git a/fuzzers/full-system/qemu_linux_process/setup/setup.sh b/fuzzers/full-system/qemu_linux_process/setup/setup.sh new file mode 100644 index 0000000000..049b630ebd --- /dev/null +++ b/fuzzers/full-system/qemu_linux_process/setup/setup.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +# Nothing to do \ No newline at end of file diff --git a/fuzzers/full-system/qemu_linux_process/src/fuzzer.rs b/fuzzers/full-system/qemu_linux_process/src/fuzzer.rs new file mode 100644 index 0000000000..e2bb9284e8 --- /dev/null +++ b/fuzzers/full-system/qemu_linux_process/src/fuzzer.rs @@ -0,0 +1,213 @@ +//! A fuzzer using qemu in systemmode for binary-only coverage of linux + +use core::{ptr::addr_of_mut, time::Duration}; +use std::{env, path::PathBuf, process, thread::sleep}; + +use libafl::{ + corpus::{Corpus, InMemoryOnDiskCorpus, OnDiskCorpus}, + events::{launcher::Launcher, EventConfig}, + executors::ShadowExecutor, + feedback_or, feedback_or_fast, + feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback}, + fuzzer::{Fuzzer, StdFuzzer}, + inputs::BytesInput, + monitors::MultiMonitor, + mutators::{ + scheduled::{havoc_mutations, StdScheduledMutator}, + I2SRandReplaceBinonly, + }, + observers::{CanTrack, HitcountsMapObserver, TimeObserver, VariableMapObserver}, + schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler}, + stages::{ShadowTracingStage, StdMutationalStage}, + state::{HasCorpus, StdState}, + Error, +}; +use libafl_bolts::{ + core_affinity::Cores, + current_nanos, + ownedref::OwnedMutSlice, + rands::StdRand, + shmem::{ShMemProvider, StdShMemProvider}, + tuples::tuple_list, +}; +use libafl_qemu::{ + emu::Emulator, + executor::QemuExecutor, + modules::{ + cmplog::CmpLogObserver, + edges::{ + edges_map_mut_ptr, StdEdgeCoverageClassicModule, EDGES_MAP_SIZE_MAX, MAX_EDGES_FOUND, + }, + CmpLogModule, + }, +}; + +pub fn fuzz() { + env_logger::init(); + + if let Ok(s) = env::var("FUZZ_SIZE") { + str::parse::(&s).expect("FUZZ_SIZE was not a number"); + }; + // Hardcoded parameters + let timeout = Duration::from_secs(99999999); + let broker_port = 1338; + let cores = Cores::from_cmdline("1").unwrap(); + let corpus_dirs = [PathBuf::from("./corpus")]; + let objective_dir = PathBuf::from("./crashes"); + + let mut run_client = |state: Option<_>, mut mgr, _core_id| { + // Initialize QEMU + let args: Vec = env::args().collect(); + + // Choose modules to use + let modules = tuple_list!( + StdEdgeCoverageClassicModule::builder().build(), + CmpLogModule::default(), + ); + + let emu = Emulator::builder() + .qemu_cli(args) + .modules(modules) + .build()?; + + println!("Process {} is ready.", process::id()); + + // loop { + // sleep(Duration::from_secs(1)); + // } + + // process::abort(); + + let devices = emu.list_devices(); + println!("Devices = {:?}", devices); + + // The wrapped harness function, calling out to the LLVM-style harness + let mut harness = + |emulator: &mut Emulator<_, _, _, _, _>, state: &mut _, input: &BytesInput| unsafe { + emulator.run(state, input).unwrap().try_into().unwrap() + }; + + // Create an observation channel using the coverage map + let edges_observer = unsafe { + HitcountsMapObserver::new(VariableMapObserver::from_mut_slice( + "edges", + OwnedMutSlice::from_raw_parts_mut(edges_map_mut_ptr(), EDGES_MAP_SIZE_MAX), + addr_of_mut!(MAX_EDGES_FOUND), + )) + .track_indices() + }; + + // Create an observation channel to keep track of the execution time + let time_observer = TimeObserver::new("time"); + + // Create a cmplog observer + let cmplog_observer = CmpLogObserver::new("cmplog", true); + + // Feedback to rate the interestingness of an input + // This one is composed by two Feedbacks in OR + let mut feedback = feedback_or!( + // New maximization map feedback linked to the edges observer and the feedback state + MaxMapFeedback::new(&edges_observer), + // Time feedback, this one does not need a feedback state + TimeFeedback::new(&time_observer) + ); + + // A feedback to choose if an input is a solution or not + let mut objective = feedback_or_fast!(CrashFeedback::new(), TimeoutFeedback::new()); + + // If not restarting, create a State from scratch + let mut state = state.unwrap_or_else(|| { + StdState::new( + // RNG + StdRand::with_seed(current_nanos()), + // Corpus that will be evolved, we keep it in memory for performance + InMemoryOnDiskCorpus::new("corpus_gen").unwrap(), + // Corpus in which we store solutions (crashes in this example), + // on disk so the user can get them after stopping the fuzzer + OnDiskCorpus::new(objective_dir.clone()).unwrap(), + // States of the feedbacks. + // The feedbacks can report the data that should persist in the State. + &mut feedback, + // Same for objective feedbacks + &mut objective, + ) + .unwrap() + }); + + // A minimization+queue policy to get testcasess from the corpus + let scheduler = + IndexesLenTimeMinimizerScheduler::new(&edges_observer, QueueScheduler::new()); + + // A fuzzer with feedbacks and a corpus scheduler + let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); + + // Create a QEMU in-process executor + let mut executor = QemuExecutor::new( + emu, + &mut harness, + tuple_list!(edges_observer, time_observer), + &mut fuzzer, + &mut state, + &mut mgr, + timeout, + ) + .expect("Failed to create QemuExecutor"); + + // Instead of calling the timeout handler and restart the process, trigger a breakpoint ASAP + executor.break_on_timeout(); + + let mut executor = ShadowExecutor::new(executor, tuple_list!(cmplog_observer)); + + if state.must_load_initial_inputs() { + state + .load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &corpus_dirs) + .unwrap_or_else(|_| { + println!("Failed to load initial corpus at {:?}", &corpus_dirs); + process::exit(0); + }); + println!("We imported {} inputs from disk.", state.corpus().count()); + } + + // a CmpLog-based mutational stage + let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!( + I2SRandReplaceBinonly::new() + ))); + + // Setup an havoc mutator with a mutational stage + let tracing = ShadowTracingStage::new(&mut executor); + let mutator = StdScheduledMutator::new(havoc_mutations()); + let mut stages = tuple_list!(tracing, i2s, StdMutationalStage::new(mutator),); + + match fuzzer.fuzz_loop(&mut stages, &mut executor, &mut state, &mut mgr) { + Ok(_) | Err(Error::ShuttingDown) => Ok(()), + Err(e) => return Err(e), + } + }; + + // The shared memory allocator + let shmem_provider = StdShMemProvider::new().expect("Failed to init shared memory"); + + // The stats reporter for the broker + let monitor = MultiMonitor::new(|s| println!("{s}")); + + // let monitor = SimpleMonitor::new(|s| println!("{s}")); + // let mut mgr = SimpleEventManager::new(monitor); + // run_client(None, mgr, 0); + + // Build and run a Launcher + match Launcher::builder() + .shmem_provider(shmem_provider) + .broker_port(broker_port) + .configuration(EventConfig::from_build_id()) + .monitor(monitor) + .run_client(&mut run_client) + .cores(&cores) + // .stdout_file(Some("/dev/null")) + .build() + .launch() + { + Ok(()) => (), + Err(Error::ShuttingDown) => println!("Fuzzing stopped by user. Good bye."), + Err(err) => panic!("Failed to run launcher: {err:?}"), + } +} diff --git a/fuzzers/full-system/qemu_linux_process/src/main.rs b/fuzzers/full-system/qemu_linux_process/src/main.rs new file mode 100644 index 0000000000..b2cf41cb60 --- /dev/null +++ b/fuzzers/full-system/qemu_linux_process/src/main.rs @@ -0,0 +1,14 @@ +//! A systemmode linux kernel example +//! +#[cfg(all(target_os = "linux"))] +mod fuzzer; + +#[cfg(target_os = "linux")] +pub fn main() { + fuzzer::fuzz(); +} + +#[cfg(not(target_os = "linux"))] +pub fn main() { + panic!("qemu and libafl_qemu is only supported on linux!"); +} diff --git a/fuzzers/others/nautilus_sync/.gitignore b/fuzzers/grammar-aware/nautilus_sync/.gitignore similarity index 100% rename from fuzzers/others/nautilus_sync/.gitignore rename to fuzzers/grammar-aware/nautilus_sync/.gitignore diff --git a/fuzzers/others/nautilus_sync/Cargo.toml b/fuzzers/grammar-aware/nautilus_sync/Cargo.toml similarity index 100% rename from fuzzers/others/nautilus_sync/Cargo.toml rename to fuzzers/grammar-aware/nautilus_sync/Cargo.toml diff --git a/fuzzers/others/nautilus_sync/Makefile.toml b/fuzzers/grammar-aware/nautilus_sync/Makefile.toml similarity index 98% rename from fuzzers/others/nautilus_sync/Makefile.toml rename to fuzzers/grammar-aware/nautilus_sync/Makefile.toml index 327e867106..242b92026a 100644 --- a/fuzzers/others/nautilus_sync/Makefile.toml +++ b/fuzzers/grammar-aware/nautilus_sync/Makefile.toml @@ -78,7 +78,7 @@ windows_alias = "unsupported" [tasks.fuzzer_unix] command = "${CARGO_TARGET_DIR}/${PROFILE_DIR}/libafl_cxx" args = [ - "${PROJECT_DIR}/../../libpng/libfuzzer_libpng/harness.cc", + "${PROJECT_DIR}/../../inprocess/libfuzzer_libpng/harness.cc", "${PROJECT_DIR}/libpng-1.6.37/.libs/libpng16.a", "-I", "${PROJECT_DIR}/libpng-1.6.37/", diff --git a/fuzzers/others/nautilus_sync/rust-toolchain b/fuzzers/grammar-aware/nautilus_sync/rust-toolchain similarity index 100% rename from fuzzers/others/nautilus_sync/rust-toolchain rename to fuzzers/grammar-aware/nautilus_sync/rust-toolchain diff --git a/fuzzers/others/nautilus_sync/src/bin/libafl_cc.rs b/fuzzers/grammar-aware/nautilus_sync/src/bin/libafl_cc.rs similarity index 100% rename from fuzzers/others/nautilus_sync/src/bin/libafl_cc.rs rename to fuzzers/grammar-aware/nautilus_sync/src/bin/libafl_cc.rs diff --git a/fuzzers/fuzzbench/fuzzbench_text/src/bin/libafl_cxx.rs b/fuzzers/grammar-aware/nautilus_sync/src/bin/libafl_cxx.rs similarity index 100% rename from fuzzers/fuzzbench/fuzzbench_text/src/bin/libafl_cxx.rs rename to fuzzers/grammar-aware/nautilus_sync/src/bin/libafl_cxx.rs diff --git a/fuzzers/others/nautilus_sync/src/lib.rs b/fuzzers/grammar-aware/nautilus_sync/src/lib.rs similarity index 100% rename from fuzzers/others/nautilus_sync/src/lib.rs rename to fuzzers/grammar-aware/nautilus_sync/src/lib.rs diff --git a/fuzzers/others/cargo_fuzz/Cargo.toml b/fuzzers/inprocess/cargo_fuzz/Cargo.toml similarity index 100% rename from fuzzers/others/cargo_fuzz/Cargo.toml rename to fuzzers/inprocess/cargo_fuzz/Cargo.toml diff --git a/fuzzers/others/cargo_fuzz/Makefile.toml b/fuzzers/inprocess/cargo_fuzz/Makefile.toml similarity index 100% rename from fuzzers/others/cargo_fuzz/Makefile.toml rename to fuzzers/inprocess/cargo_fuzz/Makefile.toml diff --git a/fuzzers/others/cargo_fuzz/README.md b/fuzzers/inprocess/cargo_fuzz/README.md similarity index 100% rename from fuzzers/others/cargo_fuzz/README.md rename to fuzzers/inprocess/cargo_fuzz/README.md diff --git a/fuzzers/others/cargo_fuzz/fuzz/.gitignore b/fuzzers/inprocess/cargo_fuzz/fuzz/.gitignore similarity index 100% rename from fuzzers/others/cargo_fuzz/fuzz/.gitignore rename to fuzzers/inprocess/cargo_fuzz/fuzz/.gitignore diff --git a/fuzzers/others/cargo_fuzz/fuzz/Cargo.toml b/fuzzers/inprocess/cargo_fuzz/fuzz/Cargo.toml similarity index 100% rename from fuzzers/others/cargo_fuzz/fuzz/Cargo.toml rename to fuzzers/inprocess/cargo_fuzz/fuzz/Cargo.toml diff --git a/fuzzers/others/cargo_fuzz/fuzz/fuzz_targets/fuzz_target_1.rs b/fuzzers/inprocess/cargo_fuzz/fuzz/fuzz_targets/fuzz_target_1.rs similarity index 100% rename from fuzzers/others/cargo_fuzz/fuzz/fuzz_targets/fuzz_target_1.rs rename to fuzzers/inprocess/cargo_fuzz/fuzz/fuzz_targets/fuzz_target_1.rs diff --git a/fuzzers/others/cargo_fuzz/src/lib.rs b/fuzzers/inprocess/cargo_fuzz/src/lib.rs similarity index 100% rename from fuzzers/others/cargo_fuzz/src/lib.rs rename to fuzzers/inprocess/cargo_fuzz/src/lib.rs diff --git a/fuzzers/others/dynamic_analysis/Cargo.toml b/fuzzers/inprocess/dynamic_analysis/Cargo.toml similarity index 100% rename from fuzzers/others/dynamic_analysis/Cargo.toml rename to fuzzers/inprocess/dynamic_analysis/Cargo.toml diff --git a/fuzzers/others/dynamic_analysis/Makefile.toml b/fuzzers/inprocess/dynamic_analysis/Makefile.toml similarity index 100% rename from fuzzers/others/dynamic_analysis/Makefile.toml rename to fuzzers/inprocess/dynamic_analysis/Makefile.toml diff --git a/fuzzers/others/dynamic_analysis/README.md b/fuzzers/inprocess/dynamic_analysis/README.md similarity index 100% rename from fuzzers/others/dynamic_analysis/README.md rename to fuzzers/inprocess/dynamic_analysis/README.md diff --git a/fuzzers/others/dynamic_analysis/build.rs b/fuzzers/inprocess/dynamic_analysis/build.rs similarity index 100% rename from fuzzers/others/dynamic_analysis/build.rs rename to fuzzers/inprocess/dynamic_analysis/build.rs diff --git a/fuzzers/others/dynamic_analysis/build.sh b/fuzzers/inprocess/dynamic_analysis/build.sh similarity index 100% rename from fuzzers/others/dynamic_analysis/build.sh rename to fuzzers/inprocess/dynamic_analysis/build.sh diff --git a/fuzzers/others/dynamic_analysis/clean.sh b/fuzzers/inprocess/dynamic_analysis/clean.sh similarity index 100% rename from fuzzers/others/dynamic_analysis/clean.sh rename to fuzzers/inprocess/dynamic_analysis/clean.sh diff --git a/fuzzers/others/dynamic_analysis/cms_transform_fuzzer.cc b/fuzzers/inprocess/dynamic_analysis/cms_transform_fuzzer.cc similarity index 100% rename from fuzzers/others/dynamic_analysis/cms_transform_fuzzer.cc rename to fuzzers/inprocess/dynamic_analysis/cms_transform_fuzzer.cc diff --git a/fuzzers/others/dynamic_analysis/concatenator.py b/fuzzers/inprocess/dynamic_analysis/concatenator.py similarity index 100% rename from fuzzers/others/dynamic_analysis/concatenator.py rename to fuzzers/inprocess/dynamic_analysis/concatenator.py diff --git a/fuzzers/others/dynamic_analysis/corpus/seed b/fuzzers/inprocess/dynamic_analysis/corpus/seed similarity index 100% rename from fuzzers/others/dynamic_analysis/corpus/seed rename to fuzzers/inprocess/dynamic_analysis/corpus/seed diff --git a/fuzzers/others/dynamic_analysis/src/bin/libafl_cc.rs b/fuzzers/inprocess/dynamic_analysis/src/bin/libafl_cc.rs similarity index 100% rename from fuzzers/others/dynamic_analysis/src/bin/libafl_cc.rs rename to fuzzers/inprocess/dynamic_analysis/src/bin/libafl_cc.rs diff --git a/fuzzers/libpng/libfuzzer_libpng/src/bin/libafl_cxx.rs b/fuzzers/inprocess/dynamic_analysis/src/bin/libafl_cxx.rs similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng/src/bin/libafl_cxx.rs rename to fuzzers/inprocess/dynamic_analysis/src/bin/libafl_cxx.rs diff --git a/fuzzers/others/dynamic_analysis/src/lib.rs b/fuzzers/inprocess/dynamic_analysis/src/lib.rs similarity index 100% rename from fuzzers/others/dynamic_analysis/src/lib.rs rename to fuzzers/inprocess/dynamic_analysis/src/lib.rs diff --git a/fuzzers/fuzzbench/fuzzbench/stub_rt.c b/fuzzers/inprocess/dynamic_analysis/stub_rt.c similarity index 100% rename from fuzzers/fuzzbench/fuzzbench/stub_rt.c rename to fuzzers/inprocess/dynamic_analysis/stub_rt.c diff --git a/fuzzers/fuzzbench/fuzzbench_forkserver/.gitignore b/fuzzers/inprocess/fuzzbench/.gitignore similarity index 100% rename from fuzzers/fuzzbench/fuzzbench_forkserver/.gitignore rename to fuzzers/inprocess/fuzzbench/.gitignore diff --git a/fuzzers/fuzzbench/fuzzbench/Cargo.toml b/fuzzers/inprocess/fuzzbench/Cargo.toml similarity index 100% rename from fuzzers/fuzzbench/fuzzbench/Cargo.toml rename to fuzzers/inprocess/fuzzbench/Cargo.toml diff --git a/fuzzers/fuzzbench/fuzzbench/Makefile.toml b/fuzzers/inprocess/fuzzbench/Makefile.toml similarity index 100% rename from fuzzers/fuzzbench/fuzzbench/Makefile.toml rename to fuzzers/inprocess/fuzzbench/Makefile.toml diff --git a/fuzzers/fuzzbench/fuzzbench_qemu/README.md b/fuzzers/inprocess/fuzzbench/README.md similarity index 100% rename from fuzzers/fuzzbench/fuzzbench_qemu/README.md rename to fuzzers/inprocess/fuzzbench/README.md diff --git a/fuzzers/fuzzbench/fuzzbench/fuzz.c b/fuzzers/inprocess/fuzzbench/fuzz.c similarity index 100% rename from fuzzers/fuzzbench/fuzzbench/fuzz.c rename to fuzzers/inprocess/fuzzbench/fuzz.c diff --git a/fuzzers/fuzzbench/fuzzbench/src/bin/libafl_cc.rs b/fuzzers/inprocess/fuzzbench/src/bin/libafl_cc.rs similarity index 100% rename from fuzzers/fuzzbench/fuzzbench/src/bin/libafl_cc.rs rename to fuzzers/inprocess/fuzzbench/src/bin/libafl_cc.rs diff --git a/fuzzers/libpng/libfuzzer_libpng_accounting/src/bin/libafl_cxx.rs b/fuzzers/inprocess/fuzzbench/src/bin/libafl_cxx.rs similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_accounting/src/bin/libafl_cxx.rs rename to fuzzers/inprocess/fuzzbench/src/bin/libafl_cxx.rs diff --git a/fuzzers/fuzzbench/fuzzbench/src/lib.rs b/fuzzers/inprocess/fuzzbench/src/lib.rs similarity index 100% rename from fuzzers/fuzzbench/fuzzbench/src/lib.rs rename to fuzzers/inprocess/fuzzbench/src/lib.rs diff --git a/fuzzers/fuzzbench/fuzzbench_ctx/stub_rt.c b/fuzzers/inprocess/fuzzbench/stub_rt.c similarity index 100% rename from fuzzers/fuzzbench/fuzzbench_ctx/stub_rt.c rename to fuzzers/inprocess/fuzzbench/stub_rt.c diff --git a/fuzzers/fuzzbench/fuzzbench_ctx/Cargo.toml b/fuzzers/inprocess/fuzzbench_ctx/Cargo.toml similarity index 100% rename from fuzzers/fuzzbench/fuzzbench_ctx/Cargo.toml rename to fuzzers/inprocess/fuzzbench_ctx/Cargo.toml diff --git a/fuzzers/fuzzbench/fuzzbench_ctx/Makefile.toml b/fuzzers/inprocess/fuzzbench_ctx/Makefile.toml similarity index 100% rename from fuzzers/fuzzbench/fuzzbench_ctx/Makefile.toml rename to fuzzers/inprocess/fuzzbench_ctx/Makefile.toml diff --git a/fuzzers/fuzzbench/fuzzbench_ctx/fuzz.c b/fuzzers/inprocess/fuzzbench_ctx/fuzz.c similarity index 100% rename from fuzzers/fuzzbench/fuzzbench_ctx/fuzz.c rename to fuzzers/inprocess/fuzzbench_ctx/fuzz.c diff --git a/fuzzers/fuzzbench/fuzzbench_ctx/src/bin/libafl_cc.rs b/fuzzers/inprocess/fuzzbench_ctx/src/bin/libafl_cc.rs similarity index 100% rename from fuzzers/fuzzbench/fuzzbench_ctx/src/bin/libafl_cc.rs rename to fuzzers/inprocess/fuzzbench_ctx/src/bin/libafl_cc.rs diff --git a/fuzzers/libpng/libfuzzer_libpng_centralized/src/bin/libafl_cxx.rs b/fuzzers/inprocess/fuzzbench_ctx/src/bin/libafl_cxx.rs similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_centralized/src/bin/libafl_cxx.rs rename to fuzzers/inprocess/fuzzbench_ctx/src/bin/libafl_cxx.rs diff --git a/fuzzers/fuzzbench/fuzzbench_ctx/src/lib.rs b/fuzzers/inprocess/fuzzbench_ctx/src/lib.rs similarity index 100% rename from fuzzers/fuzzbench/fuzzbench_ctx/src/lib.rs rename to fuzzers/inprocess/fuzzbench_ctx/src/lib.rs diff --git a/fuzzers/others/dynamic_analysis/stub_rt.c b/fuzzers/inprocess/fuzzbench_ctx/stub_rt.c similarity index 100% rename from fuzzers/others/dynamic_analysis/stub_rt.c rename to fuzzers/inprocess/fuzzbench_ctx/stub_rt.c diff --git a/fuzzers/fuzzbench/fuzzbench_text/.gitignore b/fuzzers/inprocess/fuzzbench_text/.gitignore similarity index 100% rename from fuzzers/fuzzbench/fuzzbench_text/.gitignore rename to fuzzers/inprocess/fuzzbench_text/.gitignore diff --git a/fuzzers/fuzzbench/fuzzbench_text/Cargo.toml b/fuzzers/inprocess/fuzzbench_text/Cargo.toml similarity index 100% rename from fuzzers/fuzzbench/fuzzbench_text/Cargo.toml rename to fuzzers/inprocess/fuzzbench_text/Cargo.toml diff --git a/fuzzers/fuzzbench/fuzzbench_text/Makefile.toml b/fuzzers/inprocess/fuzzbench_text/Makefile.toml similarity index 100% rename from fuzzers/fuzzbench/fuzzbench_text/Makefile.toml rename to fuzzers/inprocess/fuzzbench_text/Makefile.toml diff --git a/fuzzers/fuzzbench/fuzzbench_text/README.md b/fuzzers/inprocess/fuzzbench_text/README.md similarity index 100% rename from fuzzers/fuzzbench/fuzzbench_text/README.md rename to fuzzers/inprocess/fuzzbench_text/README.md diff --git a/fuzzers/fuzzbench/fuzzbench_text/fuzz.c b/fuzzers/inprocess/fuzzbench_text/fuzz.c similarity index 100% rename from fuzzers/fuzzbench/fuzzbench_text/fuzz.c rename to fuzzers/inprocess/fuzzbench_text/fuzz.c diff --git a/fuzzers/fuzzbench/fuzzbench_text/src/bin/libafl_cc.rs b/fuzzers/inprocess/fuzzbench_text/src/bin/libafl_cc.rs similarity index 100% rename from fuzzers/fuzzbench/fuzzbench_text/src/bin/libafl_cc.rs rename to fuzzers/inprocess/fuzzbench_text/src/bin/libafl_cc.rs diff --git a/fuzzers/libpng/libfuzzer_libpng_cmin/src/bin/libafl_cxx.rs b/fuzzers/inprocess/fuzzbench_text/src/bin/libafl_cxx.rs similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_cmin/src/bin/libafl_cxx.rs rename to fuzzers/inprocess/fuzzbench_text/src/bin/libafl_cxx.rs diff --git a/fuzzers/fuzzbench/fuzzbench_text/src/lib.rs b/fuzzers/inprocess/fuzzbench_text/src/lib.rs similarity index 100% rename from fuzzers/fuzzbench/fuzzbench_text/src/lib.rs rename to fuzzers/inprocess/fuzzbench_text/src/lib.rs diff --git a/fuzzers/others/libfuzzer_libmozjpeg/.gitignore b/fuzzers/inprocess/libfuzzer_libmozjpeg/.gitignore similarity index 100% rename from fuzzers/others/libfuzzer_libmozjpeg/.gitignore rename to fuzzers/inprocess/libfuzzer_libmozjpeg/.gitignore diff --git a/fuzzers/others/libfuzzer_libmozjpeg/Cargo.toml b/fuzzers/inprocess/libfuzzer_libmozjpeg/Cargo.toml similarity index 100% rename from fuzzers/others/libfuzzer_libmozjpeg/Cargo.toml rename to fuzzers/inprocess/libfuzzer_libmozjpeg/Cargo.toml diff --git a/fuzzers/others/libfuzzer_libmozjpeg/Makefile.toml b/fuzzers/inprocess/libfuzzer_libmozjpeg/Makefile.toml similarity index 100% rename from fuzzers/others/libfuzzer_libmozjpeg/Makefile.toml rename to fuzzers/inprocess/libfuzzer_libmozjpeg/Makefile.toml diff --git a/fuzzers/others/libfuzzer_libmozjpeg/README.md b/fuzzers/inprocess/libfuzzer_libmozjpeg/README.md similarity index 100% rename from fuzzers/others/libfuzzer_libmozjpeg/README.md rename to fuzzers/inprocess/libfuzzer_libmozjpeg/README.md diff --git a/fuzzers/others/libfuzzer_libmozjpeg/build.rs b/fuzzers/inprocess/libfuzzer_libmozjpeg/build.rs similarity index 100% rename from fuzzers/others/libfuzzer_libmozjpeg/build.rs rename to fuzzers/inprocess/libfuzzer_libmozjpeg/build.rs diff --git a/fuzzers/others/libfuzzer_libmozjpeg/corpus/blank.jpg b/fuzzers/inprocess/libfuzzer_libmozjpeg/corpus/blank.jpg similarity index 100% rename from fuzzers/others/libfuzzer_libmozjpeg/corpus/blank.jpg rename to fuzzers/inprocess/libfuzzer_libmozjpeg/corpus/blank.jpg diff --git a/fuzzers/others/libfuzzer_libmozjpeg/harness.cc b/fuzzers/inprocess/libfuzzer_libmozjpeg/harness.cc similarity index 100% rename from fuzzers/others/libfuzzer_libmozjpeg/harness.cc rename to fuzzers/inprocess/libfuzzer_libmozjpeg/harness.cc diff --git a/fuzzers/others/libfuzzer_libmozjpeg/hook_allocs.c b/fuzzers/inprocess/libfuzzer_libmozjpeg/hook_allocs.c similarity index 100% rename from fuzzers/others/libfuzzer_libmozjpeg/hook_allocs.c rename to fuzzers/inprocess/libfuzzer_libmozjpeg/hook_allocs.c diff --git a/fuzzers/others/libfuzzer_libmozjpeg/jpeg.dict b/fuzzers/inprocess/libfuzzer_libmozjpeg/jpeg.dict similarity index 100% rename from fuzzers/others/libfuzzer_libmozjpeg/jpeg.dict rename to fuzzers/inprocess/libfuzzer_libmozjpeg/jpeg.dict diff --git a/fuzzers/others/libfuzzer_libmozjpeg/src/bin/libafl_cc.rs b/fuzzers/inprocess/libfuzzer_libmozjpeg/src/bin/libafl_cc.rs similarity index 100% rename from fuzzers/others/libfuzzer_libmozjpeg/src/bin/libafl_cc.rs rename to fuzzers/inprocess/libfuzzer_libmozjpeg/src/bin/libafl_cc.rs diff --git a/fuzzers/libpng/libfuzzer_libpng_launcher/src/bin/libafl_cxx.rs b/fuzzers/inprocess/libfuzzer_libmozjpeg/src/bin/libafl_cxx.rs similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_launcher/src/bin/libafl_cxx.rs rename to fuzzers/inprocess/libfuzzer_libmozjpeg/src/bin/libafl_cxx.rs diff --git a/fuzzers/others/libfuzzer_libmozjpeg/src/lib.rs b/fuzzers/inprocess/libfuzzer_libmozjpeg/src/lib.rs similarity index 100% rename from fuzzers/others/libfuzzer_libmozjpeg/src/lib.rs rename to fuzzers/inprocess/libfuzzer_libmozjpeg/src/lib.rs diff --git a/fuzzers/libpng/libfuzzer_libpng/.gitignore b/fuzzers/inprocess/libfuzzer_libpng/.gitignore similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng/.gitignore rename to fuzzers/inprocess/libfuzzer_libpng/.gitignore diff --git a/fuzzers/libpng/libfuzzer_libpng/Cargo.toml b/fuzzers/inprocess/libfuzzer_libpng/Cargo.toml similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng/Cargo.toml rename to fuzzers/inprocess/libfuzzer_libpng/Cargo.toml diff --git a/fuzzers/libpng/libfuzzer_libpng/Makefile.toml b/fuzzers/inprocess/libfuzzer_libpng/Makefile.toml similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng/Makefile.toml rename to fuzzers/inprocess/libfuzzer_libpng/Makefile.toml diff --git a/fuzzers/libpng/libfuzzer_libpng/README.md b/fuzzers/inprocess/libfuzzer_libpng/README.md similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng/README.md rename to fuzzers/inprocess/libfuzzer_libpng/README.md diff --git a/fuzzers/libpng/libfuzzer_libpng_cmin/corpus/not_kitty.png b/fuzzers/inprocess/libfuzzer_libpng/corpus/not_kitty.png similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_cmin/corpus/not_kitty.png rename to fuzzers/inprocess/libfuzzer_libpng/corpus/not_kitty.png diff --git a/fuzzers/libpng/libfuzzer_libpng_cmin/corpus/not_kitty_alpha.png b/fuzzers/inprocess/libfuzzer_libpng/corpus/not_kitty_alpha.png similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_cmin/corpus/not_kitty_alpha.png rename to fuzzers/inprocess/libfuzzer_libpng/corpus/not_kitty_alpha.png diff --git a/fuzzers/libpng/libfuzzer_libpng_cmin/corpus/not_kitty_gamma.png b/fuzzers/inprocess/libfuzzer_libpng/corpus/not_kitty_gamma.png similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_cmin/corpus/not_kitty_gamma.png rename to fuzzers/inprocess/libfuzzer_libpng/corpus/not_kitty_gamma.png diff --git a/fuzzers/libpng/libfuzzer_libpng_cmin/corpus/not_kitty_icc.png b/fuzzers/inprocess/libfuzzer_libpng/corpus/not_kitty_icc.png similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_cmin/corpus/not_kitty_icc.png rename to fuzzers/inprocess/libfuzzer_libpng/corpus/not_kitty_icc.png diff --git a/fuzzers/libpng/libfuzzer_libpng/harness.cc b/fuzzers/inprocess/libfuzzer_libpng/harness.cc similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng/harness.cc rename to fuzzers/inprocess/libfuzzer_libpng/harness.cc diff --git a/fuzzers/libpng/libfuzzer_libpng/src/bin/libafl_cc.rs b/fuzzers/inprocess/libfuzzer_libpng/src/bin/libafl_cc.rs similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng/src/bin/libafl_cc.rs rename to fuzzers/inprocess/libfuzzer_libpng/src/bin/libafl_cc.rs diff --git a/fuzzers/libpng/libfuzzer_libpng_norestart/src/bin/libafl_cxx.rs b/fuzzers/inprocess/libfuzzer_libpng/src/bin/libafl_cxx.rs similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_norestart/src/bin/libafl_cxx.rs rename to fuzzers/inprocess/libfuzzer_libpng/src/bin/libafl_cxx.rs diff --git a/fuzzers/libpng/libfuzzer_libpng/src/lib.rs b/fuzzers/inprocess/libfuzzer_libpng/src/lib.rs similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng/src/lib.rs rename to fuzzers/inprocess/libfuzzer_libpng/src/lib.rs diff --git a/fuzzers/libpng/libfuzzer_libpng_accounting/.gitignore b/fuzzers/inprocess/libfuzzer_libpng_accounting/.gitignore similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_accounting/.gitignore rename to fuzzers/inprocess/libfuzzer_libpng_accounting/.gitignore diff --git a/fuzzers/libpng/libfuzzer_libpng_accounting/Cargo.toml b/fuzzers/inprocess/libfuzzer_libpng_accounting/Cargo.toml similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_accounting/Cargo.toml rename to fuzzers/inprocess/libfuzzer_libpng_accounting/Cargo.toml diff --git a/fuzzers/libpng/libfuzzer_libpng_accounting/Makefile.toml b/fuzzers/inprocess/libfuzzer_libpng_accounting/Makefile.toml similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_accounting/Makefile.toml rename to fuzzers/inprocess/libfuzzer_libpng_accounting/Makefile.toml diff --git a/fuzzers/libpng/libfuzzer_libpng_accounting/README.md b/fuzzers/inprocess/libfuzzer_libpng_accounting/README.md similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_accounting/README.md rename to fuzzers/inprocess/libfuzzer_libpng_accounting/README.md diff --git a/fuzzers/libpng/libfuzzer_libpng_launcher/corpus/not_kitty.png b/fuzzers/inprocess/libfuzzer_libpng_accounting/corpus/not_kitty.png similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_launcher/corpus/not_kitty.png rename to fuzzers/inprocess/libfuzzer_libpng_accounting/corpus/not_kitty.png diff --git a/fuzzers/libpng/libfuzzer_libpng_launcher/corpus/not_kitty_alpha.png b/fuzzers/inprocess/libfuzzer_libpng_accounting/corpus/not_kitty_alpha.png similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_launcher/corpus/not_kitty_alpha.png rename to fuzzers/inprocess/libfuzzer_libpng_accounting/corpus/not_kitty_alpha.png diff --git a/fuzzers/libpng/libfuzzer_libpng_launcher/corpus/not_kitty_gamma.png b/fuzzers/inprocess/libfuzzer_libpng_accounting/corpus/not_kitty_gamma.png similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_launcher/corpus/not_kitty_gamma.png rename to fuzzers/inprocess/libfuzzer_libpng_accounting/corpus/not_kitty_gamma.png diff --git a/fuzzers/libpng/libfuzzer_libpng_launcher/corpus/not_kitty_icc.png b/fuzzers/inprocess/libfuzzer_libpng_accounting/corpus/not_kitty_icc.png similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_launcher/corpus/not_kitty_icc.png rename to fuzzers/inprocess/libfuzzer_libpng_accounting/corpus/not_kitty_icc.png diff --git a/fuzzers/libpng/libfuzzer_libpng_accounting/harness.cc b/fuzzers/inprocess/libfuzzer_libpng_accounting/harness.cc similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_accounting/harness.cc rename to fuzzers/inprocess/libfuzzer_libpng_accounting/harness.cc diff --git a/fuzzers/libpng/libfuzzer_libpng_accounting/src/bin/libafl_cc.rs b/fuzzers/inprocess/libfuzzer_libpng_accounting/src/bin/libafl_cc.rs similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_accounting/src/bin/libafl_cc.rs rename to fuzzers/inprocess/libfuzzer_libpng_accounting/src/bin/libafl_cc.rs diff --git a/fuzzers/libpng/libfuzzer_libpng_tcp_manager/src/bin/libafl_cxx.rs b/fuzzers/inprocess/libfuzzer_libpng_accounting/src/bin/libafl_cxx.rs similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_tcp_manager/src/bin/libafl_cxx.rs rename to fuzzers/inprocess/libfuzzer_libpng_accounting/src/bin/libafl_cxx.rs diff --git a/fuzzers/libpng/libfuzzer_libpng_accounting/src/lib.rs b/fuzzers/inprocess/libfuzzer_libpng_accounting/src/lib.rs similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_accounting/src/lib.rs rename to fuzzers/inprocess/libfuzzer_libpng_accounting/src/lib.rs diff --git a/fuzzers/libpng/libfuzzer_libpng_centralized/.gitignore b/fuzzers/inprocess/libfuzzer_libpng_centralized/.gitignore similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_centralized/.gitignore rename to fuzzers/inprocess/libfuzzer_libpng_centralized/.gitignore diff --git a/fuzzers/libpng/libfuzzer_libpng_centralized/Cargo.toml b/fuzzers/inprocess/libfuzzer_libpng_centralized/Cargo.toml similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_centralized/Cargo.toml rename to fuzzers/inprocess/libfuzzer_libpng_centralized/Cargo.toml diff --git a/fuzzers/libpng/libfuzzer_libpng_centralized/Makefile.toml b/fuzzers/inprocess/libfuzzer_libpng_centralized/Makefile.toml similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_centralized/Makefile.toml rename to fuzzers/inprocess/libfuzzer_libpng_centralized/Makefile.toml diff --git a/fuzzers/libpng/libfuzzer_libpng_centralized/README.md b/fuzzers/inprocess/libfuzzer_libpng_centralized/README.md similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_centralized/README.md rename to fuzzers/inprocess/libfuzzer_libpng_centralized/README.md diff --git a/fuzzers/libpng/libfuzzer_libpng_norestart/seeds/not_kitty.png b/fuzzers/inprocess/libfuzzer_libpng_centralized/corpus/not_kitty.png similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_norestart/seeds/not_kitty.png rename to fuzzers/inprocess/libfuzzer_libpng_centralized/corpus/not_kitty.png diff --git a/fuzzers/libpng/libfuzzer_libpng_norestart/seeds/not_kitty_alpha.png b/fuzzers/inprocess/libfuzzer_libpng_centralized/corpus/not_kitty_alpha.png similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_norestart/seeds/not_kitty_alpha.png rename to fuzzers/inprocess/libfuzzer_libpng_centralized/corpus/not_kitty_alpha.png diff --git a/fuzzers/libpng/libfuzzer_libpng_norestart/seeds/not_kitty_gamma.png b/fuzzers/inprocess/libfuzzer_libpng_centralized/corpus/not_kitty_gamma.png similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_norestart/seeds/not_kitty_gamma.png rename to fuzzers/inprocess/libfuzzer_libpng_centralized/corpus/not_kitty_gamma.png diff --git a/fuzzers/libpng/libfuzzer_libpng_norestart/seeds/not_kitty_icc.png b/fuzzers/inprocess/libfuzzer_libpng_centralized/corpus/not_kitty_icc.png similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_norestart/seeds/not_kitty_icc.png rename to fuzzers/inprocess/libfuzzer_libpng_centralized/corpus/not_kitty_icc.png diff --git a/fuzzers/libpng/libfuzzer_libpng_centralized/harness.cc b/fuzzers/inprocess/libfuzzer_libpng_centralized/harness.cc similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_centralized/harness.cc rename to fuzzers/inprocess/libfuzzer_libpng_centralized/harness.cc diff --git a/fuzzers/libpng/libfuzzer_libpng_centralized/src/bin/libafl_cc.rs b/fuzzers/inprocess/libfuzzer_libpng_centralized/src/bin/libafl_cc.rs similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_centralized/src/bin/libafl_cc.rs rename to fuzzers/inprocess/libfuzzer_libpng_centralized/src/bin/libafl_cc.rs diff --git a/fuzzers/nyx/nyx_libxml2_parallel/src/bin/libafl_cxx.rs b/fuzzers/inprocess/libfuzzer_libpng_centralized/src/bin/libafl_cxx.rs similarity index 100% rename from fuzzers/nyx/nyx_libxml2_parallel/src/bin/libafl_cxx.rs rename to fuzzers/inprocess/libfuzzer_libpng_centralized/src/bin/libafl_cxx.rs diff --git a/fuzzers/libpng/libfuzzer_libpng_centralized/src/lib.rs b/fuzzers/inprocess/libfuzzer_libpng_centralized/src/lib.rs similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_centralized/src/lib.rs rename to fuzzers/inprocess/libfuzzer_libpng_centralized/src/lib.rs diff --git a/fuzzers/libpng/libfuzzer_libpng_cmin/.gitignore b/fuzzers/inprocess/libfuzzer_libpng_cmin/.gitignore similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_cmin/.gitignore rename to fuzzers/inprocess/libfuzzer_libpng_cmin/.gitignore diff --git a/fuzzers/libpng/libfuzzer_libpng_cmin/Cargo.toml b/fuzzers/inprocess/libfuzzer_libpng_cmin/Cargo.toml similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_cmin/Cargo.toml rename to fuzzers/inprocess/libfuzzer_libpng_cmin/Cargo.toml diff --git a/fuzzers/libpng/libfuzzer_libpng_cmin/Makefile.toml b/fuzzers/inprocess/libfuzzer_libpng_cmin/Makefile.toml similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_cmin/Makefile.toml rename to fuzzers/inprocess/libfuzzer_libpng_cmin/Makefile.toml diff --git a/fuzzers/libpng/libfuzzer_libpng_cmin/README.md b/fuzzers/inprocess/libfuzzer_libpng_cmin/README.md similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_cmin/README.md rename to fuzzers/inprocess/libfuzzer_libpng_cmin/README.md diff --git a/fuzzers/libpng/libfuzzer_libpng_tcp_manager/corpus/not_kitty.png b/fuzzers/inprocess/libfuzzer_libpng_cmin/corpus/not_kitty.png similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_tcp_manager/corpus/not_kitty.png rename to fuzzers/inprocess/libfuzzer_libpng_cmin/corpus/not_kitty.png diff --git a/fuzzers/libpng/libfuzzer_libpng_tcp_manager/corpus/not_kitty_alpha.png b/fuzzers/inprocess/libfuzzer_libpng_cmin/corpus/not_kitty_alpha.png similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_tcp_manager/corpus/not_kitty_alpha.png rename to fuzzers/inprocess/libfuzzer_libpng_cmin/corpus/not_kitty_alpha.png diff --git a/fuzzers/libpng/libfuzzer_libpng_tcp_manager/corpus/not_kitty_gamma.png b/fuzzers/inprocess/libfuzzer_libpng_cmin/corpus/not_kitty_gamma.png similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_tcp_manager/corpus/not_kitty_gamma.png rename to fuzzers/inprocess/libfuzzer_libpng_cmin/corpus/not_kitty_gamma.png diff --git a/fuzzers/libpng/libfuzzer_libpng_tcp_manager/corpus/not_kitty_icc.png b/fuzzers/inprocess/libfuzzer_libpng_cmin/corpus/not_kitty_icc.png similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_tcp_manager/corpus/not_kitty_icc.png rename to fuzzers/inprocess/libfuzzer_libpng_cmin/corpus/not_kitty_icc.png diff --git a/fuzzers/libpng/libfuzzer_libpng_cmin/harness.cc b/fuzzers/inprocess/libfuzzer_libpng_cmin/harness.cc similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_cmin/harness.cc rename to fuzzers/inprocess/libfuzzer_libpng_cmin/harness.cc diff --git a/fuzzers/libpng/libfuzzer_libpng_cmin/src/bin/libafl_cc.rs b/fuzzers/inprocess/libfuzzer_libpng_cmin/src/bin/libafl_cc.rs similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_cmin/src/bin/libafl_cc.rs rename to fuzzers/inprocess/libfuzzer_libpng_cmin/src/bin/libafl_cc.rs diff --git a/fuzzers/nyx/nyx_libxml2_standalone/src/bin/libafl_cxx.rs b/fuzzers/inprocess/libfuzzer_libpng_cmin/src/bin/libafl_cxx.rs similarity index 100% rename from fuzzers/nyx/nyx_libxml2_standalone/src/bin/libafl_cxx.rs rename to fuzzers/inprocess/libfuzzer_libpng_cmin/src/bin/libafl_cxx.rs diff --git a/fuzzers/libpng/libfuzzer_libpng_cmin/src/lib.rs b/fuzzers/inprocess/libfuzzer_libpng_cmin/src/lib.rs similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_cmin/src/lib.rs rename to fuzzers/inprocess/libfuzzer_libpng_cmin/src/lib.rs diff --git a/fuzzers/libpng/libfuzzer_libpng_launcher/.gitignore b/fuzzers/inprocess/libfuzzer_libpng_launcher/.gitignore similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_launcher/.gitignore rename to fuzzers/inprocess/libfuzzer_libpng_launcher/.gitignore diff --git a/fuzzers/libpng/libfuzzer_libpng_launcher/Cargo.toml b/fuzzers/inprocess/libfuzzer_libpng_launcher/Cargo.toml similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_launcher/Cargo.toml rename to fuzzers/inprocess/libfuzzer_libpng_launcher/Cargo.toml diff --git a/fuzzers/libpng/libfuzzer_libpng_launcher/Makefile.toml b/fuzzers/inprocess/libfuzzer_libpng_launcher/Makefile.toml similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_launcher/Makefile.toml rename to fuzzers/inprocess/libfuzzer_libpng_launcher/Makefile.toml diff --git a/fuzzers/libpng/libfuzzer_libpng_launcher/README.md b/fuzzers/inprocess/libfuzzer_libpng_launcher/README.md similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_launcher/README.md rename to fuzzers/inprocess/libfuzzer_libpng_launcher/README.md diff --git a/fuzzers/qemu/qemu_cmin/corpus/not_kitty.png b/fuzzers/inprocess/libfuzzer_libpng_launcher/corpus/not_kitty.png similarity index 100% rename from fuzzers/qemu/qemu_cmin/corpus/not_kitty.png rename to fuzzers/inprocess/libfuzzer_libpng_launcher/corpus/not_kitty.png diff --git a/fuzzers/qemu/qemu_cmin/corpus/not_kitty_alpha.png b/fuzzers/inprocess/libfuzzer_libpng_launcher/corpus/not_kitty_alpha.png similarity index 100% rename from fuzzers/qemu/qemu_cmin/corpus/not_kitty_alpha.png rename to fuzzers/inprocess/libfuzzer_libpng_launcher/corpus/not_kitty_alpha.png diff --git a/fuzzers/qemu/qemu_cmin/corpus/not_kitty_gamma.png b/fuzzers/inprocess/libfuzzer_libpng_launcher/corpus/not_kitty_gamma.png similarity index 100% rename from fuzzers/qemu/qemu_cmin/corpus/not_kitty_gamma.png rename to fuzzers/inprocess/libfuzzer_libpng_launcher/corpus/not_kitty_gamma.png diff --git a/fuzzers/qemu/qemu_cmin/corpus/not_kitty_icc.png b/fuzzers/inprocess/libfuzzer_libpng_launcher/corpus/not_kitty_icc.png similarity index 100% rename from fuzzers/qemu/qemu_cmin/corpus/not_kitty_icc.png rename to fuzzers/inprocess/libfuzzer_libpng_launcher/corpus/not_kitty_icc.png diff --git a/fuzzers/libpng/libfuzzer_libpng_launcher/harness.cc b/fuzzers/inprocess/libfuzzer_libpng_launcher/harness.cc similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_launcher/harness.cc rename to fuzzers/inprocess/libfuzzer_libpng_launcher/harness.cc diff --git a/fuzzers/libpng/libfuzzer_libpng_launcher/src/bin/libafl_ar.rs b/fuzzers/inprocess/libfuzzer_libpng_launcher/src/bin/libafl_ar.rs similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_launcher/src/bin/libafl_ar.rs rename to fuzzers/inprocess/libfuzzer_libpng_launcher/src/bin/libafl_ar.rs diff --git a/fuzzers/libpng/libfuzzer_libpng_launcher/src/bin/libafl_cc.rs b/fuzzers/inprocess/libfuzzer_libpng_launcher/src/bin/libafl_cc.rs similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_launcher/src/bin/libafl_cc.rs rename to fuzzers/inprocess/libfuzzer_libpng_launcher/src/bin/libafl_cc.rs diff --git a/fuzzers/others/dynamic_analysis/src/bin/libafl_cxx.rs b/fuzzers/inprocess/libfuzzer_libpng_launcher/src/bin/libafl_cxx.rs similarity index 100% rename from fuzzers/others/dynamic_analysis/src/bin/libafl_cxx.rs rename to fuzzers/inprocess/libfuzzer_libpng_launcher/src/bin/libafl_cxx.rs diff --git a/fuzzers/libpng/libfuzzer_libpng_launcher/src/bin/libafl_libtool.rs b/fuzzers/inprocess/libfuzzer_libpng_launcher/src/bin/libafl_libtool.rs similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_launcher/src/bin/libafl_libtool.rs rename to fuzzers/inprocess/libfuzzer_libpng_launcher/src/bin/libafl_libtool.rs diff --git a/fuzzers/libpng/libfuzzer_libpng_launcher/src/lib.rs b/fuzzers/inprocess/libfuzzer_libpng_launcher/src/lib.rs similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_launcher/src/lib.rs rename to fuzzers/inprocess/libfuzzer_libpng_launcher/src/lib.rs diff --git a/fuzzers/libpng/libfuzzer_libpng_norestart/.gitignore b/fuzzers/inprocess/libfuzzer_libpng_norestart/.gitignore similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_norestart/.gitignore rename to fuzzers/inprocess/libfuzzer_libpng_norestart/.gitignore diff --git a/fuzzers/libpng/libfuzzer_libpng_norestart/Cargo.toml b/fuzzers/inprocess/libfuzzer_libpng_norestart/Cargo.toml similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_norestart/Cargo.toml rename to fuzzers/inprocess/libfuzzer_libpng_norestart/Cargo.toml diff --git a/fuzzers/libpng/libfuzzer_libpng_norestart/Makefile.toml b/fuzzers/inprocess/libfuzzer_libpng_norestart/Makefile.toml similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_norestart/Makefile.toml rename to fuzzers/inprocess/libfuzzer_libpng_norestart/Makefile.toml diff --git a/fuzzers/libpng/libfuzzer_libpng_norestart/README.md b/fuzzers/inprocess/libfuzzer_libpng_norestart/README.md similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_norestart/README.md rename to fuzzers/inprocess/libfuzzer_libpng_norestart/README.md diff --git a/fuzzers/libpng/libfuzzer_libpng_norestart/harness.cc b/fuzzers/inprocess/libfuzzer_libpng_norestart/harness.cc similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_norestart/harness.cc rename to fuzzers/inprocess/libfuzzer_libpng_norestart/harness.cc diff --git a/fuzzers/qemu/qemu_coverage/corpus/not_kitty.png b/fuzzers/inprocess/libfuzzer_libpng_norestart/seeds/not_kitty.png similarity index 100% rename from fuzzers/qemu/qemu_coverage/corpus/not_kitty.png rename to fuzzers/inprocess/libfuzzer_libpng_norestart/seeds/not_kitty.png diff --git a/fuzzers/qemu/qemu_coverage/corpus/not_kitty_alpha.png b/fuzzers/inprocess/libfuzzer_libpng_norestart/seeds/not_kitty_alpha.png similarity index 100% rename from fuzzers/qemu/qemu_coverage/corpus/not_kitty_alpha.png rename to fuzzers/inprocess/libfuzzer_libpng_norestart/seeds/not_kitty_alpha.png diff --git a/fuzzers/qemu/qemu_coverage/corpus/not_kitty_gamma.png b/fuzzers/inprocess/libfuzzer_libpng_norestart/seeds/not_kitty_gamma.png similarity index 100% rename from fuzzers/qemu/qemu_coverage/corpus/not_kitty_gamma.png rename to fuzzers/inprocess/libfuzzer_libpng_norestart/seeds/not_kitty_gamma.png diff --git a/fuzzers/qemu/qemu_coverage/corpus/not_kitty_icc.png b/fuzzers/inprocess/libfuzzer_libpng_norestart/seeds/not_kitty_icc.png similarity index 100% rename from fuzzers/qemu/qemu_coverage/corpus/not_kitty_icc.png rename to fuzzers/inprocess/libfuzzer_libpng_norestart/seeds/not_kitty_icc.png diff --git a/fuzzers/libpng/libfuzzer_libpng_norestart/src/bin/libafl_cc.rs b/fuzzers/inprocess/libfuzzer_libpng_norestart/src/bin/libafl_cc.rs similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_norestart/src/bin/libafl_cc.rs rename to fuzzers/inprocess/libfuzzer_libpng_norestart/src/bin/libafl_cc.rs diff --git a/fuzzers/others/libfuzzer_libmozjpeg/src/bin/libafl_cxx.rs b/fuzzers/inprocess/libfuzzer_libpng_norestart/src/bin/libafl_cxx.rs similarity index 100% rename from fuzzers/others/libfuzzer_libmozjpeg/src/bin/libafl_cxx.rs rename to fuzzers/inprocess/libfuzzer_libpng_norestart/src/bin/libafl_cxx.rs diff --git a/fuzzers/libpng/libfuzzer_libpng_norestart/src/lib.rs b/fuzzers/inprocess/libfuzzer_libpng_norestart/src/lib.rs similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_norestart/src/lib.rs rename to fuzzers/inprocess/libfuzzer_libpng_norestart/src/lib.rs diff --git a/fuzzers/libpng/libfuzzer_libpng_tcp_manager/.gitignore b/fuzzers/inprocess/libfuzzer_libpng_tcp_manager/.gitignore similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_tcp_manager/.gitignore rename to fuzzers/inprocess/libfuzzer_libpng_tcp_manager/.gitignore diff --git a/fuzzers/libpng/libfuzzer_libpng_tcp_manager/Cargo.toml b/fuzzers/inprocess/libfuzzer_libpng_tcp_manager/Cargo.toml similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_tcp_manager/Cargo.toml rename to fuzzers/inprocess/libfuzzer_libpng_tcp_manager/Cargo.toml diff --git a/fuzzers/libpng/libfuzzer_libpng_tcp_manager/Makefile.toml b/fuzzers/inprocess/libfuzzer_libpng_tcp_manager/Makefile.toml similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_tcp_manager/Makefile.toml rename to fuzzers/inprocess/libfuzzer_libpng_tcp_manager/Makefile.toml diff --git a/fuzzers/libpng/libfuzzer_libpng_tcp_manager/README.md b/fuzzers/inprocess/libfuzzer_libpng_tcp_manager/README.md similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_tcp_manager/README.md rename to fuzzers/inprocess/libfuzzer_libpng_tcp_manager/README.md diff --git a/fuzzers/qemu/qemu_launcher/corpus/not_kitty.png b/fuzzers/inprocess/libfuzzer_libpng_tcp_manager/corpus/not_kitty.png similarity index 100% rename from fuzzers/qemu/qemu_launcher/corpus/not_kitty.png rename to fuzzers/inprocess/libfuzzer_libpng_tcp_manager/corpus/not_kitty.png diff --git a/fuzzers/qemu/qemu_launcher/corpus/not_kitty_alpha.png b/fuzzers/inprocess/libfuzzer_libpng_tcp_manager/corpus/not_kitty_alpha.png similarity index 100% rename from fuzzers/qemu/qemu_launcher/corpus/not_kitty_alpha.png rename to fuzzers/inprocess/libfuzzer_libpng_tcp_manager/corpus/not_kitty_alpha.png diff --git a/fuzzers/qemu/qemu_launcher/corpus/not_kitty_gamma.png b/fuzzers/inprocess/libfuzzer_libpng_tcp_manager/corpus/not_kitty_gamma.png similarity index 100% rename from fuzzers/qemu/qemu_launcher/corpus/not_kitty_gamma.png rename to fuzzers/inprocess/libfuzzer_libpng_tcp_manager/corpus/not_kitty_gamma.png diff --git a/fuzzers/qemu/qemu_launcher/corpus/not_kitty_icc.png b/fuzzers/inprocess/libfuzzer_libpng_tcp_manager/corpus/not_kitty_icc.png similarity index 100% rename from fuzzers/qemu/qemu_launcher/corpus/not_kitty_icc.png rename to fuzzers/inprocess/libfuzzer_libpng_tcp_manager/corpus/not_kitty_icc.png diff --git a/fuzzers/libpng/libfuzzer_libpng_tcp_manager/harness.cc b/fuzzers/inprocess/libfuzzer_libpng_tcp_manager/harness.cc similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_tcp_manager/harness.cc rename to fuzzers/inprocess/libfuzzer_libpng_tcp_manager/harness.cc diff --git a/fuzzers/libpng/libfuzzer_libpng_tcp_manager/src/bin/libafl_cc.rs b/fuzzers/inprocess/libfuzzer_libpng_tcp_manager/src/bin/libafl_cc.rs similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_tcp_manager/src/bin/libafl_cc.rs rename to fuzzers/inprocess/libfuzzer_libpng_tcp_manager/src/bin/libafl_cc.rs diff --git a/fuzzers/others/nautilus_sync/src/bin/libafl_cxx.rs b/fuzzers/inprocess/libfuzzer_libpng_tcp_manager/src/bin/libafl_cxx.rs similarity index 100% rename from fuzzers/others/nautilus_sync/src/bin/libafl_cxx.rs rename to fuzzers/inprocess/libfuzzer_libpng_tcp_manager/src/bin/libafl_cxx.rs diff --git a/fuzzers/libpng/libfuzzer_libpng_tcp_manager/src/lib.rs b/fuzzers/inprocess/libfuzzer_libpng_tcp_manager/src/lib.rs similarity index 100% rename from fuzzers/libpng/libfuzzer_libpng_tcp_manager/src/lib.rs rename to fuzzers/inprocess/libfuzzer_libpng_tcp_manager/src/lib.rs diff --git a/fuzzers/stb/libfuzzer_stb_image/.gitignore b/fuzzers/inprocess/libfuzzer_stb_image/.gitignore similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image/.gitignore rename to fuzzers/inprocess/libfuzzer_stb_image/.gitignore diff --git a/fuzzers/stb/libfuzzer_stb_image/Cargo.toml b/fuzzers/inprocess/libfuzzer_stb_image/Cargo.toml similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image/Cargo.toml rename to fuzzers/inprocess/libfuzzer_stb_image/Cargo.toml diff --git a/fuzzers/stb/libfuzzer_stb_image/Makefile.toml b/fuzzers/inprocess/libfuzzer_stb_image/Makefile.toml similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image/Makefile.toml rename to fuzzers/inprocess/libfuzzer_stb_image/Makefile.toml diff --git a/fuzzers/stb/libfuzzer_stb_image/README.md b/fuzzers/inprocess/libfuzzer_stb_image/README.md similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image/README.md rename to fuzzers/inprocess/libfuzzer_stb_image/README.md diff --git a/fuzzers/stb/libfuzzer_stb_image/build.rs b/fuzzers/inprocess/libfuzzer_stb_image/build.rs similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image/build.rs rename to fuzzers/inprocess/libfuzzer_stb_image/build.rs diff --git a/fuzzers/stb/libfuzzer_stb_image/corpus/not_kitty.png b/fuzzers/inprocess/libfuzzer_stb_image/corpus/not_kitty.png similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image/corpus/not_kitty.png rename to fuzzers/inprocess/libfuzzer_stb_image/corpus/not_kitty.png diff --git a/fuzzers/stb/libfuzzer_stb_image/corpus/not_kitty_alpha.png b/fuzzers/inprocess/libfuzzer_stb_image/corpus/not_kitty_alpha.png similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image/corpus/not_kitty_alpha.png rename to fuzzers/inprocess/libfuzzer_stb_image/corpus/not_kitty_alpha.png diff --git a/fuzzers/stb/libfuzzer_stb_image/corpus/not_kitty_gamma.png b/fuzzers/inprocess/libfuzzer_stb_image/corpus/not_kitty_gamma.png similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image/corpus/not_kitty_gamma.png rename to fuzzers/inprocess/libfuzzer_stb_image/corpus/not_kitty_gamma.png diff --git a/fuzzers/stb/libfuzzer_stb_image/corpus/not_kitty_icc.png b/fuzzers/inprocess/libfuzzer_stb_image/corpus/not_kitty_icc.png similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image/corpus/not_kitty_icc.png rename to fuzzers/inprocess/libfuzzer_stb_image/corpus/not_kitty_icc.png diff --git a/fuzzers/stb/libfuzzer_stb_image/harness.c b/fuzzers/inprocess/libfuzzer_stb_image/harness.c similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image/harness.c rename to fuzzers/inprocess/libfuzzer_stb_image/harness.c diff --git a/fuzzers/stb/libfuzzer_stb_image/src/main.rs b/fuzzers/inprocess/libfuzzer_stb_image/src/main.rs similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image/src/main.rs rename to fuzzers/inprocess/libfuzzer_stb_image/src/main.rs diff --git a/fuzzers/stb/libfuzzer_stb_image/stb_image.h b/fuzzers/inprocess/libfuzzer_stb_image/stb_image.h similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image/stb_image.h rename to fuzzers/inprocess/libfuzzer_stb_image/stb_image.h diff --git a/fuzzers/stb/libfuzzer_stb_image_concolic/Makefile.toml b/fuzzers/inprocess/libfuzzer_stb_image_concolic/Makefile.toml similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image_concolic/Makefile.toml rename to fuzzers/inprocess/libfuzzer_stb_image_concolic/Makefile.toml diff --git a/fuzzers/stb/libfuzzer_stb_image_concolic/README.md b/fuzzers/inprocess/libfuzzer_stb_image_concolic/README.md similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image_concolic/README.md rename to fuzzers/inprocess/libfuzzer_stb_image_concolic/README.md diff --git a/fuzzers/stb/libfuzzer_stb_image_concolic/fuzzer/.gitignore b/fuzzers/inprocess/libfuzzer_stb_image_concolic/fuzzer/.gitignore similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image_concolic/fuzzer/.gitignore rename to fuzzers/inprocess/libfuzzer_stb_image_concolic/fuzzer/.gitignore diff --git a/fuzzers/stb/libfuzzer_stb_image_concolic/fuzzer/Cargo.toml b/fuzzers/inprocess/libfuzzer_stb_image_concolic/fuzzer/Cargo.toml similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image_concolic/fuzzer/Cargo.toml rename to fuzzers/inprocess/libfuzzer_stb_image_concolic/fuzzer/Cargo.toml diff --git a/fuzzers/stb/libfuzzer_stb_image_concolic/fuzzer/build.rs b/fuzzers/inprocess/libfuzzer_stb_image_concolic/fuzzer/build.rs similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image_concolic/fuzzer/build.rs rename to fuzzers/inprocess/libfuzzer_stb_image_concolic/fuzzer/build.rs diff --git a/fuzzers/stb/libfuzzer_stb_image_concolic/fuzzer/corpus/not_kitty.png b/fuzzers/inprocess/libfuzzer_stb_image_concolic/fuzzer/corpus/not_kitty.png similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image_concolic/fuzzer/corpus/not_kitty.png rename to fuzzers/inprocess/libfuzzer_stb_image_concolic/fuzzer/corpus/not_kitty.png diff --git a/fuzzers/stb/libfuzzer_stb_image_concolic/fuzzer/corpus/not_kitty_alpha.png b/fuzzers/inprocess/libfuzzer_stb_image_concolic/fuzzer/corpus/not_kitty_alpha.png similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image_concolic/fuzzer/corpus/not_kitty_alpha.png rename to fuzzers/inprocess/libfuzzer_stb_image_concolic/fuzzer/corpus/not_kitty_alpha.png diff --git a/fuzzers/stb/libfuzzer_stb_image_concolic/fuzzer/corpus/not_kitty_gamma.png b/fuzzers/inprocess/libfuzzer_stb_image_concolic/fuzzer/corpus/not_kitty_gamma.png similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image_concolic/fuzzer/corpus/not_kitty_gamma.png rename to fuzzers/inprocess/libfuzzer_stb_image_concolic/fuzzer/corpus/not_kitty_gamma.png diff --git a/fuzzers/stb/libfuzzer_stb_image_concolic/fuzzer/corpus/not_kitty_icc.png b/fuzzers/inprocess/libfuzzer_stb_image_concolic/fuzzer/corpus/not_kitty_icc.png similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image_concolic/fuzzer/corpus/not_kitty_icc.png rename to fuzzers/inprocess/libfuzzer_stb_image_concolic/fuzzer/corpus/not_kitty_icc.png diff --git a/fuzzers/stb/libfuzzer_stb_image_concolic/fuzzer/harness.c b/fuzzers/inprocess/libfuzzer_stb_image_concolic/fuzzer/harness.c similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image_concolic/fuzzer/harness.c rename to fuzzers/inprocess/libfuzzer_stb_image_concolic/fuzzer/harness.c diff --git a/fuzzers/stb/libfuzzer_stb_image_concolic/fuzzer/harness_symcc.c b/fuzzers/inprocess/libfuzzer_stb_image_concolic/fuzzer/harness_symcc.c similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image_concolic/fuzzer/harness_symcc.c rename to fuzzers/inprocess/libfuzzer_stb_image_concolic/fuzzer/harness_symcc.c diff --git a/fuzzers/stb/libfuzzer_stb_image_concolic/fuzzer/src/main.rs b/fuzzers/inprocess/libfuzzer_stb_image_concolic/fuzzer/src/main.rs similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image_concolic/fuzzer/src/main.rs rename to fuzzers/inprocess/libfuzzer_stb_image_concolic/fuzzer/src/main.rs diff --git a/fuzzers/stb/libfuzzer_stb_image_concolic/fuzzer/stb_image.h b/fuzzers/inprocess/libfuzzer_stb_image_concolic/fuzzer/stb_image.h similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image_concolic/fuzzer/stb_image.h rename to fuzzers/inprocess/libfuzzer_stb_image_concolic/fuzzer/stb_image.h diff --git a/fuzzers/stb/libfuzzer_stb_image_concolic/runtime/Cargo.toml b/fuzzers/inprocess/libfuzzer_stb_image_concolic/runtime/Cargo.toml similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image_concolic/runtime/Cargo.toml rename to fuzzers/inprocess/libfuzzer_stb_image_concolic/runtime/Cargo.toml diff --git a/fuzzers/stb/libfuzzer_stb_image_concolic/runtime/src/lib.rs b/fuzzers/inprocess/libfuzzer_stb_image_concolic/runtime/src/lib.rs similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image_concolic/runtime/src/lib.rs rename to fuzzers/inprocess/libfuzzer_stb_image_concolic/runtime/src/lib.rs diff --git a/fuzzers/stb/libfuzzer_stb_image_sugar/.gitignore b/fuzzers/inprocess/libfuzzer_stb_image_sugar/.gitignore similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image_sugar/.gitignore rename to fuzzers/inprocess/libfuzzer_stb_image_sugar/.gitignore diff --git a/fuzzers/stb/libfuzzer_stb_image_sugar/Cargo.toml b/fuzzers/inprocess/libfuzzer_stb_image_sugar/Cargo.toml similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image_sugar/Cargo.toml rename to fuzzers/inprocess/libfuzzer_stb_image_sugar/Cargo.toml diff --git a/fuzzers/stb/libfuzzer_stb_image_sugar/Makefile.toml b/fuzzers/inprocess/libfuzzer_stb_image_sugar/Makefile.toml similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image_sugar/Makefile.toml rename to fuzzers/inprocess/libfuzzer_stb_image_sugar/Makefile.toml diff --git a/fuzzers/stb/libfuzzer_stb_image_sugar/README.md b/fuzzers/inprocess/libfuzzer_stb_image_sugar/README.md similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image_sugar/README.md rename to fuzzers/inprocess/libfuzzer_stb_image_sugar/README.md diff --git a/fuzzers/stb/libfuzzer_stb_image_sugar/build.rs b/fuzzers/inprocess/libfuzzer_stb_image_sugar/build.rs similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image_sugar/build.rs rename to fuzzers/inprocess/libfuzzer_stb_image_sugar/build.rs diff --git a/fuzzers/stb/libfuzzer_stb_image_sugar/corpus/not_kitty.png b/fuzzers/inprocess/libfuzzer_stb_image_sugar/corpus/not_kitty.png similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image_sugar/corpus/not_kitty.png rename to fuzzers/inprocess/libfuzzer_stb_image_sugar/corpus/not_kitty.png diff --git a/fuzzers/stb/libfuzzer_stb_image_sugar/corpus/not_kitty_alpha.png b/fuzzers/inprocess/libfuzzer_stb_image_sugar/corpus/not_kitty_alpha.png similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image_sugar/corpus/not_kitty_alpha.png rename to fuzzers/inprocess/libfuzzer_stb_image_sugar/corpus/not_kitty_alpha.png diff --git a/fuzzers/stb/libfuzzer_stb_image_sugar/corpus/not_kitty_gamma.png b/fuzzers/inprocess/libfuzzer_stb_image_sugar/corpus/not_kitty_gamma.png similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image_sugar/corpus/not_kitty_gamma.png rename to fuzzers/inprocess/libfuzzer_stb_image_sugar/corpus/not_kitty_gamma.png diff --git a/fuzzers/stb/libfuzzer_stb_image_sugar/corpus/not_kitty_icc.png b/fuzzers/inprocess/libfuzzer_stb_image_sugar/corpus/not_kitty_icc.png similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image_sugar/corpus/not_kitty_icc.png rename to fuzzers/inprocess/libfuzzer_stb_image_sugar/corpus/not_kitty_icc.png diff --git a/fuzzers/stb/libfuzzer_stb_image_sugar/harness.c b/fuzzers/inprocess/libfuzzer_stb_image_sugar/harness.c similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image_sugar/harness.c rename to fuzzers/inprocess/libfuzzer_stb_image_sugar/harness.c diff --git a/fuzzers/stb/libfuzzer_stb_image_sugar/src/main.rs b/fuzzers/inprocess/libfuzzer_stb_image_sugar/src/main.rs similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image_sugar/src/main.rs rename to fuzzers/inprocess/libfuzzer_stb_image_sugar/src/main.rs diff --git a/fuzzers/stb/libfuzzer_stb_image_sugar/stb_image.h b/fuzzers/inprocess/libfuzzer_stb_image_sugar/stb_image.h similarity index 100% rename from fuzzers/stb/libfuzzer_stb_image_sugar/stb_image.h rename to fuzzers/inprocess/libfuzzer_stb_image_sugar/stb_image.h diff --git a/fuzzers/others/libfuzzer_windows_asan/.gitignore b/fuzzers/inprocess/libfuzzer_windows_asan/.gitignore similarity index 100% rename from fuzzers/others/libfuzzer_windows_asan/.gitignore rename to fuzzers/inprocess/libfuzzer_windows_asan/.gitignore diff --git a/fuzzers/others/libfuzzer_windows_asan/Cargo.toml b/fuzzers/inprocess/libfuzzer_windows_asan/Cargo.toml similarity index 100% rename from fuzzers/others/libfuzzer_windows_asan/Cargo.toml rename to fuzzers/inprocess/libfuzzer_windows_asan/Cargo.toml diff --git a/fuzzers/others/libfuzzer_windows_asan/Makefile.toml b/fuzzers/inprocess/libfuzzer_windows_asan/Makefile.toml similarity index 100% rename from fuzzers/others/libfuzzer_windows_asan/Makefile.toml rename to fuzzers/inprocess/libfuzzer_windows_asan/Makefile.toml diff --git a/fuzzers/others/libfuzzer_windows_asan/README.md b/fuzzers/inprocess/libfuzzer_windows_asan/README.md similarity index 100% rename from fuzzers/others/libfuzzer_windows_asan/README.md rename to fuzzers/inprocess/libfuzzer_windows_asan/README.md diff --git a/fuzzers/others/libfuzzer_windows_asan/corpus/hello_world b/fuzzers/inprocess/libfuzzer_windows_asan/corpus/hello_world similarity index 100% rename from fuzzers/others/libfuzzer_windows_asan/corpus/hello_world rename to fuzzers/inprocess/libfuzzer_windows_asan/corpus/hello_world diff --git a/fuzzers/others/libfuzzer_windows_asan/harness.cpp b/fuzzers/inprocess/libfuzzer_windows_asan/harness.cpp similarity index 100% rename from fuzzers/others/libfuzzer_windows_asan/harness.cpp rename to fuzzers/inprocess/libfuzzer_windows_asan/harness.cpp diff --git a/fuzzers/others/libfuzzer_windows_asan/src/bin/libafl_cc.rs b/fuzzers/inprocess/libfuzzer_windows_asan/src/bin/libafl_cc.rs similarity index 100% rename from fuzzers/others/libfuzzer_windows_asan/src/bin/libafl_cc.rs rename to fuzzers/inprocess/libfuzzer_windows_asan/src/bin/libafl_cc.rs diff --git a/fuzzers/others/libfuzzer_windows_asan/src/bin/libafl_cxx.rs b/fuzzers/inprocess/libfuzzer_windows_asan/src/bin/libafl_cxx.rs similarity index 100% rename from fuzzers/others/libfuzzer_windows_asan/src/bin/libafl_cxx.rs rename to fuzzers/inprocess/libfuzzer_windows_asan/src/bin/libafl_cxx.rs diff --git a/fuzzers/others/libfuzzer_windows_asan/src/lib.rs b/fuzzers/inprocess/libfuzzer_windows_asan/src/lib.rs similarity index 100% rename from fuzzers/others/libfuzzer_windows_asan/src/lib.rs rename to fuzzers/inprocess/libfuzzer_windows_asan/src/lib.rs diff --git a/fuzzers/others/push_harness/.gitignore b/fuzzers/inprocess/push_harness/.gitignore similarity index 100% rename from fuzzers/others/push_harness/.gitignore rename to fuzzers/inprocess/push_harness/.gitignore diff --git a/fuzzers/others/push_harness/Cargo.toml b/fuzzers/inprocess/push_harness/Cargo.toml similarity index 100% rename from fuzzers/others/push_harness/Cargo.toml rename to fuzzers/inprocess/push_harness/Cargo.toml diff --git a/fuzzers/others/push_harness/README.md b/fuzzers/inprocess/push_harness/README.md similarity index 100% rename from fuzzers/others/push_harness/README.md rename to fuzzers/inprocess/push_harness/README.md diff --git a/fuzzers/others/push_harness/src/main.rs b/fuzzers/inprocess/push_harness/src/main.rs similarity index 100% rename from fuzzers/others/push_harness/src/main.rs rename to fuzzers/inprocess/push_harness/src/main.rs diff --git a/fuzzers/others/push_stage_harness/.gitignore b/fuzzers/inprocess/push_stage_harness/.gitignore similarity index 100% rename from fuzzers/others/push_stage_harness/.gitignore rename to fuzzers/inprocess/push_stage_harness/.gitignore diff --git a/fuzzers/others/push_stage_harness/Cargo.toml b/fuzzers/inprocess/push_stage_harness/Cargo.toml similarity index 100% rename from fuzzers/others/push_stage_harness/Cargo.toml rename to fuzzers/inprocess/push_stage_harness/Cargo.toml diff --git a/fuzzers/others/push_stage_harness/README.md b/fuzzers/inprocess/push_stage_harness/README.md similarity index 100% rename from fuzzers/others/push_stage_harness/README.md rename to fuzzers/inprocess/push_stage_harness/README.md diff --git a/fuzzers/others/push_stage_harness/src/main.rs b/fuzzers/inprocess/push_stage_harness/src/main.rs similarity index 100% rename from fuzzers/others/push_stage_harness/src/main.rs rename to fuzzers/inprocess/push_stage_harness/src/main.rs diff --git a/fuzzers/others/sqlite_centralized_multi_machine/Cargo.toml b/fuzzers/inprocess/sqlite_centralized_multi_machine/Cargo.toml similarity index 100% rename from fuzzers/others/sqlite_centralized_multi_machine/Cargo.toml rename to fuzzers/inprocess/sqlite_centralized_multi_machine/Cargo.toml diff --git a/fuzzers/others/sqlite_centralized_multi_machine/README.md b/fuzzers/inprocess/sqlite_centralized_multi_machine/README.md similarity index 100% rename from fuzzers/others/sqlite_centralized_multi_machine/README.md rename to fuzzers/inprocess/sqlite_centralized_multi_machine/README.md diff --git a/fuzzers/others/sqlite_centralized_multi_machine/build.sh b/fuzzers/inprocess/sqlite_centralized_multi_machine/build.sh similarity index 100% rename from fuzzers/others/sqlite_centralized_multi_machine/build.sh rename to fuzzers/inprocess/sqlite_centralized_multi_machine/build.sh diff --git a/fuzzers/others/sqlite_centralized_multi_machine/run_child.sh b/fuzzers/inprocess/sqlite_centralized_multi_machine/run_child.sh similarity index 100% rename from fuzzers/others/sqlite_centralized_multi_machine/run_child.sh rename to fuzzers/inprocess/sqlite_centralized_multi_machine/run_child.sh diff --git a/fuzzers/others/sqlite_centralized_multi_machine/run_parent.sh b/fuzzers/inprocess/sqlite_centralized_multi_machine/run_parent.sh similarity index 100% rename from fuzzers/others/sqlite_centralized_multi_machine/run_parent.sh rename to fuzzers/inprocess/sqlite_centralized_multi_machine/run_parent.sh diff --git a/fuzzers/others/sqlite_centralized_multi_machine/src/bin/libafl_cc.rs b/fuzzers/inprocess/sqlite_centralized_multi_machine/src/bin/libafl_cc.rs similarity index 100% rename from fuzzers/others/sqlite_centralized_multi_machine/src/bin/libafl_cc.rs rename to fuzzers/inprocess/sqlite_centralized_multi_machine/src/bin/libafl_cc.rs diff --git a/fuzzers/others/sqlite_centralized_multi_machine/src/bin/libafl_cxx.rs b/fuzzers/inprocess/sqlite_centralized_multi_machine/src/bin/libafl_cxx.rs similarity index 100% rename from fuzzers/others/sqlite_centralized_multi_machine/src/bin/libafl_cxx.rs rename to fuzzers/inprocess/sqlite_centralized_multi_machine/src/bin/libafl_cxx.rs diff --git a/fuzzers/others/sqlite_centralized_multi_machine/src/lib.rs b/fuzzers/inprocess/sqlite_centralized_multi_machine/src/lib.rs similarity index 100% rename from fuzzers/others/sqlite_centralized_multi_machine/src/lib.rs rename to fuzzers/inprocess/sqlite_centralized_multi_machine/src/lib.rs diff --git a/fuzzers/others/tutorial/Cargo.toml b/fuzzers/inprocess/tutorial/Cargo.toml similarity index 100% rename from fuzzers/others/tutorial/Cargo.toml rename to fuzzers/inprocess/tutorial/Cargo.toml diff --git a/fuzzers/others/tutorial/rust-toolchain b/fuzzers/inprocess/tutorial/rust-toolchain similarity index 100% rename from fuzzers/others/tutorial/rust-toolchain rename to fuzzers/inprocess/tutorial/rust-toolchain diff --git a/fuzzers/others/tutorial/src/bin/libafl_cc.rs b/fuzzers/inprocess/tutorial/src/bin/libafl_cc.rs similarity index 100% rename from fuzzers/others/tutorial/src/bin/libafl_cc.rs rename to fuzzers/inprocess/tutorial/src/bin/libafl_cc.rs diff --git a/fuzzers/others/tutorial/src/bin/libafl_cxx.rs b/fuzzers/inprocess/tutorial/src/bin/libafl_cxx.rs similarity index 100% rename from fuzzers/others/tutorial/src/bin/libafl_cxx.rs rename to fuzzers/inprocess/tutorial/src/bin/libafl_cxx.rs diff --git a/fuzzers/others/tutorial/src/input.rs b/fuzzers/inprocess/tutorial/src/input.rs similarity index 100% rename from fuzzers/others/tutorial/src/input.rs rename to fuzzers/inprocess/tutorial/src/input.rs diff --git a/fuzzers/others/tutorial/src/lib.rs b/fuzzers/inprocess/tutorial/src/lib.rs similarity index 100% rename from fuzzers/others/tutorial/src/lib.rs rename to fuzzers/inprocess/tutorial/src/lib.rs diff --git a/fuzzers/others/tutorial/src/metadata.rs b/fuzzers/inprocess/tutorial/src/metadata.rs similarity index 100% rename from fuzzers/others/tutorial/src/metadata.rs rename to fuzzers/inprocess/tutorial/src/metadata.rs diff --git a/fuzzers/others/tutorial/src/mutator.rs b/fuzzers/inprocess/tutorial/src/mutator.rs similarity index 100% rename from fuzzers/others/tutorial/src/mutator.rs rename to fuzzers/inprocess/tutorial/src/mutator.rs diff --git a/fuzzers/others/tutorial/target.c b/fuzzers/inprocess/tutorial/target.c similarity index 100% rename from fuzzers/others/tutorial/target.c rename to fuzzers/inprocess/tutorial/target.c diff --git a/libafl/src/common/nautilus/grammartec/context.rs b/libafl/src/common/nautilus/grammartec/context.rs index 35fcd22610..4e4d7e9453 100644 --- a/libafl/src/common/nautilus/grammartec/context.rs +++ b/libafl/src/common/nautilus/grammartec/context.rs @@ -63,12 +63,12 @@ impl Context { #[must_use] pub fn get_nt(&self, r: &RuleIdOrCustom) -> NTermId { - return self.get_rule(r.id()).nonterm(); + self.get_rule(r.id()).nonterm() } #[must_use] pub fn get_num_children(&self, r: &RuleIdOrCustom) -> usize { - return self.get_rule(r.id()).number_of_nonterms(); + self.get_rule(r.id()).number_of_nonterms() } pub fn add_rule(&mut self, nt: &str, format: &[u8]) -> RuleId { @@ -115,10 +115,10 @@ impl Context { #[must_use] pub fn nt_id(&self, nt: &str) -> NTermId { - return *self + *self .names_to_nt_id .get(nt) - .expect(&("no such nonterminal: ".to_owned() + nt)); + .expect(&("no such nonterminal: ".to_owned() + nt)) } #[must_use] diff --git a/libafl/src/common/nautilus/grammartec/rule.rs b/libafl/src/common/nautilus/grammartec/rule.rs index 74baf72cc5..7df06852b0 100644 --- a/libafl/src/common/nautilus/grammartec/rule.rs +++ b/libafl/src/common/nautilus/grammartec/rule.rs @@ -166,11 +166,11 @@ impl Rule { nterms: &[String], script: PyObject, ) -> Self { - return Self::Script(ScriptRule { + Self::Script(ScriptRule { nonterm: ctx.aquire_nt_id(nonterm), nonterms: nterms.iter().map(|s| ctx.aquire_nt_id(s)).collect(), script, - }); + }) } pub fn from_regex(ctx: &mut Context, nonterm: &str, regex: &str) -> Self { @@ -260,7 +260,7 @@ impl Rule { // RegExp Changed from (\{[^}\\]+\})|((?:[^{\\]|\\\{|\\\}|\\\\)+) because of problems with \\ (\\ was not matched and therefore thrown away) }); - return tokenizer + tokenizer .captures_iter(format) .map(|cap| { if let Some(sub) = cap.get(1) { @@ -276,7 +276,7 @@ impl Rule { unreachable!() } }) - .collect::>(); + .collect::>() } #[must_use] diff --git a/libafl/src/common/nautilus/grammartec/tree.rs b/libafl/src/common/nautilus/grammartec/tree.rs index 71ecc53cd4..d88a6701eb 100644 --- a/libafl/src/common/nautilus/grammartec/tree.rs +++ b/libafl/src/common/nautilus/grammartec/tree.rs @@ -258,11 +258,11 @@ impl Tree { ) -> TreeMutation<'a> { let old_size = self.subtree_size(n); let new_size = other.subtree_size(other_node); - return TreeMutation { + TreeMutation { prefix: self.slice(0.into(), n), repl: other.slice(other_node, other_node + new_size), postfix: self.slice(n + old_size, self.rules.len().into()), - }; + } } fn calc_subtree_sizes_and_parents(&mut self, ctx: &Context) { @@ -455,7 +455,7 @@ impl<'a> TreeLike for TreeMutation<'a> { } fn get_rule<'c>(&self, n: NodeId, ctx: &'c Context) -> &'c Rule { - return ctx.get_rule(self.get_rule_id(n)); + ctx.get_rule(self.get_rule_id(n)) } fn get_custom_rule_data(&self, n: NodeId) -> &[u8] { self.get_at(n).data() diff --git a/libafl/src/corpus/inmemory.rs b/libafl/src/corpus/inmemory.rs index 319c675e12..d880caa1da 100644 --- a/libafl/src/corpus/inmemory.rs +++ b/libafl/src/corpus/inmemory.rs @@ -261,7 +261,7 @@ where { /// Insert a testcase assigning a `CorpusId` to it pub fn insert(&mut self, testcase: RefCell>) -> CorpusId { - self._insert(testcase, false) + self.insert_inner(testcase, false) } #[must_use] @@ -272,12 +272,12 @@ where /// Insert a testcase assigning a `CorpusId` to it pub fn insert_disabled(&mut self, testcase: RefCell>) -> CorpusId { - self._insert(testcase, true) + self.insert_inner(testcase, true) } /// Insert a testcase assigning a `CorpusId` to it #[cfg(not(feature = "corpus_btreemap"))] - fn _insert(&mut self, testcase: RefCell>, is_disabled: bool) -> CorpusId { + fn insert_inner(&mut self, testcase: RefCell>, is_disabled: bool) -> CorpusId { let id = CorpusId::from(self.progressive_id); self.progressive_id += 1; let corpus = if is_disabled { @@ -309,7 +309,7 @@ where /// Insert a testcase assigning a `CorpusId` to it #[cfg(feature = "corpus_btreemap")] - fn _insert(&mut self, testcase: RefCell>, is_disabled: bool) -> CorpusId { + fn insert_inner(&mut self, testcase: RefCell>, is_disabled: bool) -> CorpusId { let id = CorpusId::from(self.progressive_id); self.progressive_id += 1; let corpus = if is_disabled { diff --git a/libafl/src/events/events_hooks/mod.rs b/libafl/src/events/events_hooks/mod.rs index 532198e100..b34b1810f6 100644 --- a/libafl/src/events/events_hooks/mod.rs +++ b/libafl/src/events/events_hooks/mod.rs @@ -6,12 +6,6 @@ use libafl_bolts::ClientId; use crate::{events::Event, state::State, Error}; -/// node hook, for multi-machine fuzzing -// #[cfg(feature = "multi_machine")] -// pub mod multi_machine; -// #[cfg(feature = "multi_machine")] -// pub use multi_machine::*; - /// The `broker_hooks` that are run before and after the event manager calls `handle_in_client` pub trait EventManagerHook where diff --git a/libafl/src/events/launcher.rs b/libafl/src/events/launcher.rs index a3bc04c6ab..13081d3b1c 100644 --- a/libafl/src/events/launcher.rs +++ b/libafl/src/events/launcher.rs @@ -746,12 +746,12 @@ where } } - #[cfg(feature = "multi_machine")] // Create this after forks, to avoid problems with tokio runtime // # Safety // The `multi_machine_receiver_hook` needs messages to outlive the receiver. // The underlying memory region for incoming messages lives longer than the async thread processing them. + #[cfg(feature = "multi_machine")] let TcpMultiMachineHooks { sender: multi_machine_sender_hook, receiver: multi_machine_receiver_hook, diff --git a/libafl/src/events/llmp/mgr.rs b/libafl/src/events/llmp/mgr.rs index 5591885202..07a44dafd4 100644 --- a/libafl/src/events/llmp/mgr.rs +++ b/libafl/src/events/llmp/mgr.rs @@ -1,5 +1,5 @@ -/// An [`EventManager`] that forwards all events to other attached fuzzers on shared maps or via tcp, -/// using low-level message passing, [`llmp`]. +//! An [`crate::events::EventManager`] that forwards all events to other attached fuzzers on shared maps or via tcp, +//! using low-level message passing, [`libafl_bolts::llmp`]. #[cfg(feature = "std")] use alloc::string::ToString; diff --git a/libafl/src/events/tcp.rs b/libafl/src/events/tcp.rs index 78ecee71d1..c363ce4e36 100644 --- a/libafl/src/events/tcp.rs +++ b/libafl/src/events/tcp.rs @@ -113,8 +113,9 @@ where } /// Run in the broker until all clients exit + // TODO: remove allow(clippy::needless_return) when clippy is fixed #[tokio::main(flavor = "current_thread")] - #[allow(clippy::too_many_lines)] + #[allow(clippy::too_many_lines, clippy::needless_return)] pub async fn broker_loop(&mut self) -> Result<(), Error> { let (tx_bc, rx) = broadcast::channel(65536); let (tx, mut rx_mpsc) = mpsc::channel(65536); diff --git a/libafl/src/executors/command.rs b/libafl/src/executors/command.rs index 72a87d05c8..5cab98c64e 100644 --- a/libafl/src/executors/command.rs +++ b/libafl/src/executors/command.rs @@ -582,7 +582,6 @@ impl CommandExecutorBuilder { /// MyExecutor.into_executor(()) /// } /// ``` - #[cfg(all(feature = "std", any(unix, doc)))] pub trait CommandConfigurator: Sized { /// Get the stdout diff --git a/libafl/src/executors/hooks/inprocess_fork.rs b/libafl/src/executors/hooks/inprocess_fork.rs index b8a5e8db69..2602aa1d43 100644 --- a/libafl/src/executors/hooks/inprocess_fork.rs +++ b/libafl/src/executors/hooks/inprocess_fork.rs @@ -131,7 +131,6 @@ impl InProcessForkExecutorGlobalData { } /// a static variable storing the global state - pub(crate) static mut FORK_EXECUTOR_GLOBAL_DATA: InProcessForkExecutorGlobalData = InProcessForkExecutorGlobalData { executor_ptr: null(), diff --git a/libafl/src/executors/hooks/unix.rs b/libafl/src/executors/hooks/unix.rs index d9072760fc..2a5c2355c6 100644 --- a/libafl/src/executors/hooks/unix.rs +++ b/libafl/src/executors/hooks/unix.rs @@ -29,7 +29,7 @@ pub mod unix_signal_handler { data: *mut InProcessExecutorHandlerData, ); - /// A handler that does nothing. + // A handler that does nothing. /*pub fn nop_handler( _signal: Signal, _info: &mut siginfo_t, diff --git a/libafl/src/executors/inprocess/stateful.rs b/libafl/src/executors/inprocess/stateful.rs index 7d458e351f..969716f5aa 100644 --- a/libafl/src/executors/inprocess/stateful.rs +++ b/libafl/src/executors/inprocess/stateful.rs @@ -46,7 +46,7 @@ pub type OwnedInProcessExecutor = StatefulGenericInProcessExecutor< #[allow(dead_code)] pub struct StatefulGenericInProcessExecutor where - H: FnMut(&mut ES, &S::Input) -> ExitKind + ?Sized, + H: FnMut(&mut ES, &mut S, &S::Input) -> ExitKind + ?Sized, HB: BorrowMut, HT: ExecutorHooksTuple, OT: ObserversTuple, @@ -63,7 +63,7 @@ where impl Debug for StatefulGenericInProcessExecutor where - H: FnMut(&mut ES, &S::Input) -> ExitKind + ?Sized, + H: FnMut(&mut ES, &mut S, &S::Input) -> ExitKind + ?Sized, HB: BorrowMut, HT: ExecutorHooksTuple, OT: ObserversTuple + Debug, @@ -79,7 +79,7 @@ where impl UsesState for StatefulGenericInProcessExecutor where - H: FnMut(&mut ES, &S::Input) -> ExitKind + ?Sized, + H: FnMut(&mut ES, &mut S, &S::Input) -> ExitKind + ?Sized, HB: BorrowMut, HT: ExecutorHooksTuple, OT: ObserversTuple, @@ -90,7 +90,7 @@ where impl UsesObservers for StatefulGenericInProcessExecutor where - H: FnMut(&mut ES, &S::Input) -> ExitKind + ?Sized, + H: FnMut(&mut ES, &mut S, &S::Input) -> ExitKind + ?Sized, HB: BorrowMut, HT: ExecutorHooksTuple, OT: ObserversTuple, @@ -103,7 +103,7 @@ impl Executor for StatefulGenericInProcessExecutor where EM: UsesState, - H: FnMut(&mut ES, &S::Input) -> ExitKind + ?Sized, + H: FnMut(&mut ES, &mut S, &S::Input) -> ExitKind + ?Sized, HB: BorrowMut, HT: ExecutorHooksTuple, OT: ObserversTuple, @@ -125,7 +125,7 @@ where } self.inner.hooks.pre_exec_all(state, input); - let ret = self.harness_fn.borrow_mut()(&mut self.exposed_executor_state, input); + let ret = self.harness_fn.borrow_mut()(&mut self.exposed_executor_state, state, input); self.inner.hooks.post_exec_all(state, input); self.inner.leave_target(fuzzer, state, mgr, input); @@ -135,7 +135,7 @@ where impl HasObservers for StatefulGenericInProcessExecutor where - H: FnMut(&mut ES, &S::Input) -> ExitKind + ?Sized, + H: FnMut(&mut ES, &mut S, &S::Input) -> ExitKind + ?Sized, HB: BorrowMut, HT: ExecutorHooksTuple, OT: ObserversTuple, @@ -154,7 +154,7 @@ where impl<'a, H, OT, S, ES> StatefulInProcessExecutor<'a, H, OT, S, ES> where - H: FnMut(&mut ES, &::Input) -> ExitKind + ?Sized, + H: FnMut(&mut ES, &mut S, &::Input) -> ExitKind + ?Sized, OT: ObserversTuple, S: HasExecutions + HasSolutions + HasCorpus + State, { @@ -265,7 +265,7 @@ where impl StatefulGenericInProcessExecutor where - H: FnMut(&mut ES, &S::Input) -> ExitKind + ?Sized, + H: FnMut(&mut ES, &mut S, &S::Input) -> ExitKind + ?Sized, HB: BorrowMut, HT: ExecutorHooksTuple, OT: ObserversTuple, @@ -284,7 +284,7 @@ where impl StatefulGenericInProcessExecutor where - H: FnMut(&mut ES, &S::Input) -> ExitKind + ?Sized, + H: FnMut(&mut ES, &mut S, &S::Input) -> ExitKind + ?Sized, HB: BorrowMut, HT: ExecutorHooksTuple, OT: ObserversTuple, @@ -414,7 +414,7 @@ where impl HasInProcessHooks for StatefulGenericInProcessExecutor where - H: FnMut(&mut ES, &::Input) -> ExitKind + ?Sized, + H: FnMut(&mut ES, &mut S, &::Input) -> ExitKind + ?Sized, HB: BorrowMut, HT: ExecutorHooksTuple, OT: ObserversTuple, diff --git a/libafl/src/executors/inprocess_fork/mod.rs b/libafl/src/executors/inprocess_fork/mod.rs index 6dfc875726..b072ead8af 100644 --- a/libafl/src/executors/inprocess_fork/mod.rs +++ b/libafl/src/executors/inprocess_fork/mod.rs @@ -271,7 +271,6 @@ where } /// signal hooks and `panic_hooks` for the child process - pub mod child_signal_handlers { use alloc::boxed::Box; use core::ptr::addr_of_mut; diff --git a/libafl/src/mutators/token_mutations.rs b/libafl/src/mutators/token_mutations.rs index fa39fda243..8355ed92a2 100644 --- a/libafl/src/mutators/token_mutations.rs +++ b/libafl/src/mutators/token_mutations.rs @@ -604,6 +604,213 @@ impl I2SRandReplace { } } +// A `I2SRandReplaceBinonly` [`Mutator`] replaces a random matching input-2-state comparison operand with the other. +/// It needs a valid [`CmpValuesMetadata`] in the state. +/// This version has been designed for binary-only fuzzing, for which cmp sized can be larger than necessary. +#[derive(Debug, Default)] +pub struct I2SRandReplaceBinonly; + +fn random_slice_size(state: &mut S) -> usize +where + S: HasRand, +{ + let sz_log = SZ.ilog2() as usize; + let res = state.rand_mut().below_incl(sz_log); + 2_usize.pow(res as u32) +} + +impl Mutator for I2SRandReplaceBinonly +where + S: UsesInput + HasMetadata + HasRand + HasMaxSize, + I: HasMutatorBytes, +{ + #[allow(clippy::too_many_lines)] + fn mutate(&mut self, state: &mut S, input: &mut I) -> Result { + let size = input.bytes().len(); + if size == 0 { + return Ok(MutationResult::Skipped); + } + + let cmps_len = { + let Some(meta) = state.metadata_map().get::() else { + return Ok(MutationResult::Skipped); + }; + log::trace!("meta: {:x?}", meta); + if meta.list.is_empty() { + return Ok(MutationResult::Skipped); + } + meta.list.len() + }; + let idx = state.rand_mut().below(cmps_len); + + let off = state.rand_mut().below(size); + let len = input.bytes().len(); + let bytes = input.bytes_mut(); + + let meta = state.metadata_map().get::().unwrap(); + let cmp_values = &meta.list[idx]; + + // TODO: do not use from_ne_bytes, it's for host not for target!! we should use a from_target_ne_bytes.... + + let mut result = MutationResult::Skipped; + match cmp_values.clone() { + CmpValues::U8(v) => { + for byte in bytes.iter_mut().take(len).skip(off) { + if *byte == v.0 { + *byte = v.1; + result = MutationResult::Mutated; + break; + } else if *byte == v.1 { + *byte = v.0; + result = MutationResult::Mutated; + break; + } + } + } + CmpValues::U16(v) => { + let cmp_size = random_slice_size::<{ size_of::() }, S>(state); + + if len >= cmp_size { + for i in off..len - (cmp_size - 1) { + let mut val_bytes = [0; size_of::()]; + val_bytes[..cmp_size].copy_from_slice(&bytes[i..i + cmp_size]); + let val = u16::from_ne_bytes(val_bytes); + + if val == v.0 { + let new_bytes = &v.1.to_ne_bytes()[..cmp_size]; + bytes[i..i + cmp_size].copy_from_slice(new_bytes); + result = MutationResult::Mutated; + break; + } else if val == v.1 { + let new_bytes = &v.0.to_ne_bytes()[..cmp_size]; + bytes[i..i + cmp_size].copy_from_slice(new_bytes); + result = MutationResult::Mutated; + break; + } else if val.swap_bytes() == v.0 { + let new_bytes = v.1.swap_bytes().to_ne_bytes(); + bytes[i..i + cmp_size].copy_from_slice(&new_bytes[..cmp_size]); + result = MutationResult::Mutated; + break; + } else if val.swap_bytes() == v.1 { + let new_bytes = v.0.swap_bytes().to_ne_bytes(); + bytes[i..i + cmp_size].copy_from_slice(&new_bytes[..cmp_size]); + result = MutationResult::Mutated; + break; + } + } + } + } + CmpValues::U32(v) => { + let cmp_size = random_slice_size::<{ size_of::() }, S>(state); + if len >= cmp_size { + for i in off..len - (cmp_size - 1) { + let mut val_bytes = [0; size_of::()]; + val_bytes[..cmp_size].copy_from_slice(&bytes[i..i + cmp_size]); + let val = u32::from_ne_bytes(val_bytes); + + if val == v.0 { + let new_bytes = &v.1.to_ne_bytes()[..cmp_size]; + bytes[i..i + cmp_size].copy_from_slice(new_bytes); + result = MutationResult::Mutated; + break; + } else if val == v.1 { + let new_bytes = &v.0.to_ne_bytes()[..cmp_size]; + bytes[i..i + cmp_size].copy_from_slice(new_bytes); + result = MutationResult::Mutated; + break; + } else if val.swap_bytes() == v.0 { + let new_bytes = v.1.swap_bytes().to_ne_bytes(); + bytes[i..i + cmp_size].copy_from_slice(&new_bytes[..cmp_size]); + result = MutationResult::Mutated; + break; + } else if val.swap_bytes() == v.1 { + let new_bytes = v.0.swap_bytes().to_ne_bytes(); + bytes[i..i + cmp_size].copy_from_slice(&new_bytes[..cmp_size]); + result = MutationResult::Mutated; + break; + } + } + } + } + CmpValues::U64(v) => { + let cmp_size = random_slice_size::<{ size_of::() }, S>(state); + + if len >= cmp_size { + for i in off..(len - (cmp_size - 1)) { + let mut val_bytes = [0; size_of::()]; + val_bytes[..cmp_size].copy_from_slice(&bytes[i..i + cmp_size]); + let val = u64::from_ne_bytes(val_bytes); + + if val == v.0 { + let new_bytes = &v.1.to_ne_bytes()[..cmp_size]; + bytes[i..i + cmp_size].copy_from_slice(new_bytes); + result = MutationResult::Mutated; + break; + } else if val == v.1 { + let new_bytes = &v.0.to_ne_bytes()[..cmp_size]; + bytes[i..i + cmp_size].copy_from_slice(new_bytes); + result = MutationResult::Mutated; + break; + } else if val.swap_bytes() == v.0 { + let new_bytes = v.1.swap_bytes().to_ne_bytes(); + bytes[i..i + cmp_size].copy_from_slice(&new_bytes[..cmp_size]); + result = MutationResult::Mutated; + break; + } else if val.swap_bytes() == v.1 { + let new_bytes = v.0.swap_bytes().to_ne_bytes(); + bytes[i..i + cmp_size].copy_from_slice(&new_bytes[..cmp_size]); + result = MutationResult::Mutated; + break; + } + } + } + } + CmpValues::Bytes(v) => { + 'outer: for i in off..len { + let mut size = core::cmp::min(v.0.len(), len - i); + while size != 0 { + if v.0.as_slice()[0..size] == input.bytes()[i..i + size] { + unsafe { + buffer_copy(input.bytes_mut(), v.1.as_slice(), 0, i, size); + } + result = MutationResult::Mutated; + break 'outer; + } + size -= 1; + } + size = core::cmp::min(v.1.len(), len - i); + while size != 0 { + if v.1.as_slice()[0..size] == input.bytes()[i..i + size] { + unsafe { + buffer_copy(input.bytes_mut(), v.0.as_slice(), 0, i, size); + } + result = MutationResult::Mutated; + break 'outer; + } + size -= 1; + } + } + } + } + + Ok(result) + } +} + +impl Named for I2SRandReplaceBinonly { + fn name(&self) -> &Cow<'static, str> { + static NAME: Cow<'static, str> = Cow::Borrowed("I2SRandReplace"); + &NAME + } +} + +impl I2SRandReplaceBinonly { + /// Creates a new `I2SRandReplace` struct. + #[must_use] + pub fn new() -> Self { + Self + } +} const CMP_ATTTRIBUTE_IS_EQUAL: u8 = 1; const CMP_ATTRIBUTE_IS_GREATER: u8 = 2; const CMP_ATTRIBUTE_IS_LESSER: u8 = 4; diff --git a/libafl_bolts/src/lib.rs b/libafl_bolts/src/lib.rs index 014e911af0..0f25b0976c 100644 --- a/libafl_bolts/src/lib.rs +++ b/libafl_bolts/src/lib.rs @@ -335,12 +335,14 @@ impl Error { { Error::Serialize(arg.into(), ErrorBacktrace::new()) } + #[cfg(feature = "gzip")] /// Compression error #[must_use] pub fn compression() -> Self { Error::Compression(ErrorBacktrace::new()) } + /// Optional val was supposed to be set, but isn't. #[must_use] pub fn empty_optional(arg: S) -> Self @@ -349,6 +351,7 @@ impl Error { { Error::EmptyOptional(arg.into(), ErrorBacktrace::new()) } + /// Key not in Map #[must_use] pub fn key_not_found(arg: S) -> Self @@ -357,6 +360,7 @@ impl Error { { Error::KeyNotFound(arg.into(), ErrorBacktrace::new()) } + /// No elements in the current item #[must_use] pub fn empty(arg: S) -> Self @@ -365,6 +369,7 @@ impl Error { { Error::Empty(arg.into(), ErrorBacktrace::new()) } + /// End of iteration #[must_use] pub fn iterator_end(arg: S) -> Self @@ -373,6 +378,7 @@ impl Error { { Error::IteratorEnd(arg.into(), ErrorBacktrace::new()) } + /// This is not supported (yet) #[must_use] pub fn not_implemented(arg: S) -> Self @@ -381,6 +387,7 @@ impl Error { { Error::NotImplemented(arg.into(), ErrorBacktrace::new()) } + /// You're holding it wrong #[must_use] pub fn illegal_state(arg: S) -> Self @@ -389,6 +396,7 @@ impl Error { { Error::IllegalState(arg.into(), ErrorBacktrace::new()) } + /// The argument passed to this method or function is not valid #[must_use] pub fn illegal_argument(arg: S) -> Self @@ -397,11 +405,13 @@ impl Error { { Error::IllegalArgument(arg.into(), ErrorBacktrace::new()) } + /// Shutting down, not really an error. #[must_use] pub fn shutting_down() -> Self { Error::ShuttingDown } + /// This operation is not supported on the current architecture or platform #[must_use] pub fn unsupported(arg: S) -> Self @@ -410,6 +420,7 @@ impl Error { { Error::Unsupported(arg.into(), ErrorBacktrace::new()) } + /// OS error with additional message #[cfg(feature = "std")] #[must_use] @@ -419,6 +430,7 @@ impl Error { { Error::OsError(err, msg.into(), ErrorBacktrace::new()) } + /// OS error from [`io::Error::last_os_error`] with additional message #[cfg(feature = "std")] #[must_use] @@ -432,6 +444,7 @@ impl Error { ErrorBacktrace::new(), ) } + /// Something else happened #[must_use] pub fn unknown(arg: S) -> Self @@ -440,6 +453,7 @@ impl Error { { Error::Unknown(arg.into(), ErrorBacktrace::new()) } + /// Error with corpora #[must_use] pub fn invalid_corpus(arg: S) -> Self diff --git a/libafl_bolts/src/llmp.rs b/libafl_bolts/src/llmp.rs index 4f366bde69..af7f1402b1 100644 --- a/libafl_bolts/src/llmp.rs +++ b/libafl_bolts/src/llmp.rs @@ -571,7 +571,7 @@ unsafe fn llmp_next_msg_ptr_checked( let msg_begin_min = (page as *const u8).add(size_of::()); // We still need space for this msg (alloc_size). let msg_begin_max = (page as *const u8).add(map_size - alloc_size); - let next = _llmp_next_msg_ptr(last_msg); + let next = llmp_next_msg_ptr(last_msg); let next_ptr = next as *const u8; if next_ptr >= msg_begin_min && next_ptr <= msg_begin_max { Ok(next) @@ -590,8 +590,8 @@ unsafe fn llmp_next_msg_ptr_checked( /// Will dereference the `last_msg` ptr #[inline] #[allow(clippy::cast_ptr_alignment)] -unsafe fn _llmp_next_msg_ptr(last_msg: *const LlmpMsg) -> *mut LlmpMsg { - /* DBG("_llmp_next_msg_ptr %p %lu + %lu\n", last_msg, last_msg->buf_len_padded, sizeof(llmp_message)); */ +unsafe fn llmp_next_msg_ptr(last_msg: *const LlmpMsg) -> *mut LlmpMsg { + /* DBG("llmp_next_msg_ptr %p %lu + %lu\n", last_msg, last_msg->buf_len_padded, sizeof(llmp_message)); */ (last_msg as *mut u8) .add(size_of::()) .add((*last_msg).buf_len_padded as usize) as *mut LlmpMsg @@ -1243,7 +1243,7 @@ where (*ret).buf_len_padded = buf_len_padded as u64; (*page).size_used += size_of::() + buf_len_padded; - (*_llmp_next_msg_ptr(ret)).tag = LLMP_TAG_UNSET; + (*llmp_next_msg_ptr(ret)).tag = LLMP_TAG_UNSET; (*ret).tag = LLMP_TAG_UNINITIALIZED; self.has_unsent_message = true; @@ -1494,7 +1494,7 @@ where (*page).size_used -= old_len_padded as usize; (*page).size_used += buf_len_padded; - (*_llmp_next_msg_ptr(msg)).tag = LLMP_TAG_UNSET; + (*llmp_next_msg_ptr(msg)).tag = LLMP_TAG_UNSET; Ok(()) } diff --git a/libafl_bolts/src/rands/mod.rs b/libafl_bolts/src/rands/mod.rs index 9f261cc2b6..404655bb13 100644 --- a/libafl_bolts/src/rands/mod.rs +++ b/libafl_bolts/src/rands/mod.rs @@ -129,6 +129,12 @@ pub trait Rand: Debug + Serialize + DeserializeOwned { fast_bound(self.next(), upper_bound_excl) } + /// Gets a value below the given bound (inclusive) + #[inline] + fn below_incl(&mut self, upper_bound_incl: usize) -> usize { + self.below(upper_bound_incl + 1) + } + /// Gets a value between the given lower bound (inclusive) and upper bound (inclusive) #[inline] fn between(&mut self, lower_bound_incl: usize, upper_bound_incl: usize) -> usize { diff --git a/libafl_frida/src/asan/asan_rt.rs b/libafl_frida/src/asan/asan_rt.rs index aff797862f..12cdb21190 100644 --- a/libafl_frida/src/asan/asan_rt.rs +++ b/libafl_frida/src/asan/asan_rt.rs @@ -345,7 +345,7 @@ impl AsanRuntime { log::info!("registering thread with stack {stack_start:x}:{stack_end:x}"); } - /// Get the maximum stack size for the current stack + // /// Get the maximum stack size for the current stack // #[must_use] // #[cfg(target_vendor = "apple")] // fn max_stack_size() -> usize { diff --git a/libafl_frida/src/asan/hook_funcs.rs b/libafl_frida/src/asan/hook_funcs.rs index c5b1f2efee..7cd575cdf4 100644 --- a/libafl_frida/src/asan/hook_funcs.rs +++ b/libafl_frida/src/asan/hook_funcs.rs @@ -1,3 +1,5 @@ +#![allow(clippy::used_underscore_items)] + //! The allocator hooks for address sanitizer. use std::ffi::c_void; diff --git a/libafl_qemu/build_linux.rs b/libafl_qemu/build_linux.rs index a400351675..a0c98982bb 100644 --- a/libafl_qemu/build_linux.rs +++ b/libafl_qemu/build_linux.rs @@ -45,9 +45,16 @@ pub fn build() { let qemu_asan = cfg!(all(feature = "build_libqasan", not(feature = "hexagon"))); let libafl_qemu_hdr_name = "libafl_qemu.h"; + let libafl_qemu_arch_hdr_name = "libafl_qemu_arch.h"; + let libafl_qemu_defs_hdr_name = "libafl_qemu_defs.h"; + let libafl_qemu_impl_hdr_name = "libafl_qemu_impl.h"; let libafl_runtime_dir = src_dir.join("runtime"); + let libafl_qemu_hdr = libafl_runtime_dir.join(libafl_qemu_hdr_name); + let libafl_qemu_arch_hdr = libafl_runtime_dir.join(libafl_qemu_arch_hdr_name); + let libafl_qemu_defs_hdr = libafl_runtime_dir.join(libafl_qemu_defs_hdr_name); + let libafl_qemu_impl_hdr = libafl_runtime_dir.join(libafl_qemu_impl_hdr_name); let libafl_runtime_testfile = out_dir.join("runtime_test.c"); fs::write(&libafl_runtime_testfile, LIBAFL_QEMU_RUNTIME_TEST).expect("Could not write runtime test file"); @@ -119,6 +126,25 @@ pub fn build() { ) .expect("Could not copy libafl_qemu.h to out directory."); + fs::copy( + + libafl_qemu_arch_hdr.clone(), + include_dir.join(libafl_qemu_arch_hdr_name), + ) + .expect("Could not copy libafl_qemu_arch.h to out directory."); + + fs::copy( + libafl_qemu_defs_hdr.clone(), + include_dir.join(libafl_qemu_defs_hdr_name), + ) + .expect("Could not copy libafl_qemu_defs.h to out directory."); + + fs::copy( + libafl_qemu_impl_hdr.clone(), + include_dir.join(libafl_qemu_impl_hdr_name), + ) + .expect("Could not copy libafl_qemu_impl.h to out directory."); + bindgen::Builder::default() .derive_debug(true) .derive_default(true) diff --git a/libafl_qemu/libafl_qemu_build/src/build.rs b/libafl_qemu/libafl_qemu_build/src/build.rs index d4e67b75ad..2b24d46e42 100644 --- a/libafl_qemu/libafl_qemu_build/src/build.rs +++ b/libafl_qemu/libafl_qemu_build/src/build.rs @@ -11,7 +11,7 @@ use crate::cargo_add_rpath; pub const QEMU_URL: &str = "https://github.com/AFLplusplus/qemu-libafl-bridge"; pub const QEMU_DIRNAME: &str = "qemu-libafl-bridge"; -pub const QEMU_REVISION: &str = "ee43af7f80d1117857e58b0b7ef556652d5893d5"; +pub const QEMU_REVISION: &str = "d6637939526f453c69f4c6bfe4635feb5dc5c0be"; #[allow(clippy::module_name_repetitions)] pub struct BuildResult { @@ -90,8 +90,11 @@ fn configure_qemu( .arg(format!("--cxx={}", linker_interceptor_plus_plus.display())) .arg("--as-shared-lib") .arg(format!("--target-list={cpu_target}-{target_suffix}")) + .arg("--disable-bsd-user") // .arg("--disable-capstone") - .arg("--disable-bsd-user"); + .arg("--disable-docs") + .arg("--disable-tests") + .arg("--disable-tools"); if cfg!(feature = "paranoid_debug") { cmd.arg("--enable-debug") @@ -137,13 +140,14 @@ fn configure_qemu( .arg("--disable-gio") .arg("--disable-glusterfs") .arg("--disable-gnutls") - .arg("--disable-gtk") - .arg("--disable-guest-agent") - .arg("--disable-guest-agent-msi") + // .arg("--disable-gtk") + // .arg("--disable-guest-agent") + // .arg("--disable-guest-agent-msi") .arg("--disable-hvf") .arg("--disable-iconv") .arg("--disable-jack") .arg("--disable-keyring") + // .arg("--disable-kvm") .arg("--disable-libdaxctl") .arg("--disable-libiscsi") .arg("--disable-libnfs") @@ -213,8 +217,7 @@ fn configure_qemu( .arg("--disable-xen") .arg("--disable-xen-pci-passthrough") .arg("--disable-xkbcommon") - .arg("--disable-zstd") - .arg("--disable-tests"); + .arg("--disable-zstd"); } cmd diff --git a/libafl_qemu/libafl_qemu_build/src/lib.rs b/libafl_qemu/libafl_qemu_build/src/lib.rs index 72d44c2619..0095defef7 100644 --- a/libafl_qemu/libafl_qemu_build/src/lib.rs +++ b/libafl_qemu/libafl_qemu_build/src/lib.rs @@ -1,8 +1,8 @@ #![forbid(unexpected_cfgs)] #![allow(clippy::missing_panics_doc)] -#[rustversion::nightly] -use std::io::{BufRead, BufReader}; +// #[rustversion::nightly] +// use std::io::{BufRead, BufReader}; use std::{ collections::hash_map, env, fs, @@ -14,10 +14,10 @@ use std::{ ptr::addr_of_mut, }; -#[rustversion::nightly] -use regex::Regex; -#[rustversion::nightly] -use rustc_version::Version; +//#[rustversion::nightly] +//use regex::Regex; +//#[rustversion::nightly] +//use rustc_version::Version; use which::which; mod bindings; @@ -318,111 +318,113 @@ pub fn store_generated_content_if_different( } } -#[rustversion::nightly] -fn parse_stub( - stub_bindings_file: &Path, - current_rustc_version: &Version, -) -> (bool, bool, Option>) { - let semver_re = Regex::new(r"/\* (.*) \*/").unwrap(); - let qemu_hash_re = Regex::new(r"/\* qemu git hash: (.*) \*/").unwrap(); - - if let Ok(stub_file) = File::open(stub_bindings_file) { - let mut stub_rdr = BufReader::new(stub_file); - - let mut first_line = String::new(); // rustc version - let mut second_line = String::new(); // qemu hash - let mut stub_content = Vec::::new(); - - assert!( - stub_rdr - .read_line(&mut first_line) - .expect("Could not read first line") - > 0, - "Error while reading first line." - ); - - assert!( - stub_rdr - .read_line(&mut second_line) - .expect("Could not read second line") - > 0, - "Error while reading second line." - ); - - if let Some((_, [version_str])) = semver_re - .captures_iter(&first_line) - .next() - .map(|caps| caps.extract()) - { - // The first line matches the regex - - if let Some((_, [qemu_hash_str])) = qemu_hash_re - .captures_iter(&second_line) - .next() - .map(|caps| caps.extract()) - { - // The second line matches the regex - - if let Ok(version) = Version::parse(version_str) { - // The first line contains a version - - stub_rdr - .read_to_end(&mut stub_content) - .expect("could not read stub content"); - - return ( - (current_rustc_version > &version) || (qemu_hash_str != QEMU_REVISION), - false, - Some(stub_content), - ); - } - } - } - - stub_rdr.seek(SeekFrom::Start(0)).unwrap(); - stub_rdr - .read_to_end(&mut stub_content) - .expect("could not read stub content"); - - (true, true, Some(stub_content)) - } else { - // No stub file stored - (true, true, None) - } -} +//#[rustversion::nightly] +//fn parse_stub( +// stub_bindings_file: &Path, +// current_rustc_version: &Version, +//) -> (bool, bool, Option>) { +// let semver_re = Regex::new(r"/\* (.*) \*/").unwrap(); +// let qemu_hash_re = Regex::new(r"/\* qemu git hash: (.*) \*/").unwrap(); +// +// if let Ok(stub_file) = File::open(stub_bindings_file) { +// let mut stub_rdr = BufReader::new(stub_file); +// +// let mut first_line = String::new(); // rustc version +// let mut second_line = String::new(); // qemu hash +// let mut stub_content = Vec::::new(); +// +// assert!( +// stub_rdr +// .read_line(&mut first_line) +// .expect("Could not read first line") +// > 0, +// "Error while reading first line." +// ); +// +// assert!( +// stub_rdr +// .read_line(&mut second_line) +// .expect("Could not read second line") +// > 0, +// "Error while reading second line." +// ); +// +// if let Some((_, [version_str])) = semver_re +// .captures_iter(&first_line) +// .next() +// .map(|caps| caps.extract()) +// { +// // The first line matches the regex +// +// if let Some((_, [qemu_hash_str])) = qemu_hash_re +// .captures_iter(&second_line) +// .next() +// .map(|caps| caps.extract()) +// { +// // The second line matches the regex +// +// if let Ok(version) = Version::parse(version_str) { +// // The first line contains a version +// +// stub_rdr +// .read_to_end(&mut stub_content) +// .expect("could not read stub content"); +// +// return ( +// (current_rustc_version > &version) || (qemu_hash_str != QEMU_REVISION), +// false, +// Some(stub_content), +// ); +// } +// } +// } +// +// stub_rdr.seek(SeekFrom::Start(0)).unwrap(); +// stub_rdr +// .read_to_end(&mut stub_content) +// .expect("could not read stub content"); +// +// (true, true, Some(stub_content)) +// } else { +// // No stub file stored +// (true, true, None) +// } +//} #[rustversion::nightly] +#[allow(unused)] pub fn maybe_generate_stub_bindings( cpu_target: &str, emulation_mode: &str, stub_bindings_file: &Path, bindings_file: &Path, ) { - if env::var("CARGO_CFG_DOC").is_ok() && cpu_target == "x86_64" && emulation_mode == "usermode" { + if env::var("LIBAFL_QEMU_GEN_STUBS").is_ok() + && cpu_target == "x86_64" + && emulation_mode == "usermode" + { let current_rustc_version = rustc_version::version().expect("Could not get current rustc version"); // We only try to store the stub if the current rustc version is strictly bigger than the one used to generate // the versioned stub or the qemu hash differs. - let (try_generate, force_regeneration, stub_content) = - parse_stub(stub_bindings_file, ¤t_rustc_version); + // let (try_generate, force_regeneration, stub_content) = + // parse_stub(stub_bindings_file, ¤t_rustc_version); let header = format!("/* {current_rustc_version} */"); - if try_generate { - store_generated_content_if_different( - stub_bindings_file, - fs::read(bindings_file) - .expect("Could not read generated bindings file") - .as_slice(), - stub_content, - vec![ - header.as_str(), - format!("/* qemu git hash: {QEMU_REVISION} */").as_str(), - ], - force_regeneration, - ); - } + store_generated_content_if_different( + stub_bindings_file, + fs::read(bindings_file) + .expect("Could not read generated bindings file") + .as_slice(), + None, + vec![ + header.as_str(), + format!("/* qemu git hash: {QEMU_REVISION} */").as_str(), + ], + false, + ); } else if env::var("CARGO_CFG_DOC").is_ok() { println!("cargo:warning=Bindings regeneration has been skipped. Please rerun with x86_64 with usermode to trigger the bindings regeneration."); } diff --git a/libafl_qemu/libafl_qemu_sys/src/x86_64_stub_bindings.rs b/libafl_qemu/libafl_qemu_sys/src/x86_64_stub_bindings.rs index e5566e77db..dd6a3d4010 100644 --- a/libafl_qemu/libafl_qemu_sys/src/x86_64_stub_bindings.rs +++ b/libafl_qemu/libafl_qemu_sys/src/x86_64_stub_bindings.rs @@ -1,5 +1,5 @@ -/* 1.82.0-nightly */ -/* qemu git hash: ec91486cedfd9e636be0063d88bd6e7eaff74915 */ +/* 1.83.0-nightly */ +/* qemu git hash: d6637939526f453c69f4c6bfe4635feb5dc5c0be */ /* automatically generated by rust-bindgen 0.69.4 */ #[repr(C)] @@ -13317,6 +13317,7 @@ extern "C" { pub const libafl_exit_reason_kind_INTERNAL: libafl_exit_reason_kind = libafl_exit_reason_kind(0); pub const libafl_exit_reason_kind_BREAKPOINT: libafl_exit_reason_kind = libafl_exit_reason_kind(1); pub const libafl_exit_reason_kind_SYNC_EXIT: libafl_exit_reason_kind = libafl_exit_reason_kind(2); +pub const libafl_exit_reason_kind_TIMEOUT: libafl_exit_reason_kind = libafl_exit_reason_kind(3); impl ::std::ops::BitOr for libafl_exit_reason_kind { type Output = Self; #[inline] @@ -13347,53 +13348,6 @@ impl ::std::ops::BitAndAssign for libafl_exit_reason_kind { #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct libafl_exit_reason_kind(pub ::std::os::raw::c_uint); #[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct libafl_exit_reason_breakpoint { - pub addr: target_ulong, -} -#[test] -fn bindgen_test_layout_libafl_exit_reason_breakpoint() { - const UNINIT: ::std::mem::MaybeUninit = - ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(libafl_exit_reason_breakpoint)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(libafl_exit_reason_breakpoint)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(libafl_exit_reason_breakpoint), - "::", - stringify!(addr) - ) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct libafl_exit_reason_sync_exit {} -#[test] -fn bindgen_test_layout_libafl_exit_reason_sync_exit() { - assert_eq!( - ::std::mem::size_of::(), - 0usize, - concat!("Size of: ", stringify!(libafl_exit_reason_sync_exit)) - ); - assert_eq!( - ::std::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(libafl_exit_reason_sync_exit)) - ); -} -#[repr(C)] #[derive(Debug, Copy, Clone)] pub struct libafl_exit_reason_internal { pub cause: ShutdownCause, @@ -13445,6 +13399,69 @@ impl Default for libafl_exit_reason_internal { } } #[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct libafl_exit_reason_breakpoint { + pub addr: target_ulong, +} +#[test] +fn bindgen_test_layout_libafl_exit_reason_breakpoint() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 8usize, + concat!("Size of: ", stringify!(libafl_exit_reason_breakpoint)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(libafl_exit_reason_breakpoint)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(libafl_exit_reason_breakpoint), + "::", + stringify!(addr) + ) + ); +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct libafl_exit_reason_sync_exit {} +#[test] +fn bindgen_test_layout_libafl_exit_reason_sync_exit() { + assert_eq!( + ::std::mem::size_of::(), + 0usize, + concat!("Size of: ", stringify!(libafl_exit_reason_sync_exit)) + ); + assert_eq!( + ::std::mem::align_of::(), + 1usize, + concat!("Alignment of ", stringify!(libafl_exit_reason_sync_exit)) + ); +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct libafl_exit_reason_timeout {} +#[test] +fn bindgen_test_layout_libafl_exit_reason_timeout() { + assert_eq!( + ::std::mem::size_of::(), + 0usize, + concat!("Size of: ", stringify!(libafl_exit_reason_timeout)) + ); + assert_eq!( + ::std::mem::align_of::(), + 1usize, + concat!("Alignment of ", stringify!(libafl_exit_reason_timeout)) + ); +} +#[repr(C)] #[derive(Copy, Clone)] pub struct libafl_exit_reason { pub kind: libafl_exit_reason_kind, @@ -13458,6 +13475,7 @@ pub union libafl_exit_reason__bindgen_ty_1 { pub internal: libafl_exit_reason_internal, pub breakpoint: libafl_exit_reason_breakpoint, pub sync_exit: libafl_exit_reason_sync_exit, + pub timeout: libafl_exit_reason_timeout, } #[test] fn bindgen_test_layout_libafl_exit_reason__bindgen_ty_1() { @@ -13507,6 +13525,16 @@ fn bindgen_test_layout_libafl_exit_reason__bindgen_ty_1() { stringify!(sync_exit) ) ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).timeout) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(libafl_exit_reason__bindgen_ty_1), + "::", + stringify!(timeout) + ) + ); } impl Default for libafl_exit_reason__bindgen_ty_1 { fn default() -> Self { @@ -13616,10 +13644,10 @@ extern "C" { ); } extern "C" { - pub fn libafl_exit_request_sync_backdoor(cpu: *mut CPUState, pc: target_ulong); + pub fn libafl_exit_request_breakpoint(cpu: *mut CPUState, pc: target_ulong); } extern "C" { - pub fn libafl_exit_request_breakpoint(cpu: *mut CPUState, pc: target_ulong); + pub fn libafl_exit_request_sync_backdoor(cpu: *mut CPUState, pc: target_ulong); } extern "C" { pub fn libafl_get_exit_reason() -> *mut libafl_exit_reason; diff --git a/libafl_qemu/runtime/libafl_qemu.h b/libafl_qemu/runtime/libafl_qemu.h index 071708f702..ace7259f91 100644 --- a/libafl_qemu/runtime/libafl_qemu.h +++ b/libafl_qemu/runtime/libafl_qemu.h @@ -1,6 +1,11 @@ #ifndef LIBAFL_QEMU_H #define LIBAFL_QEMU_H +#include "libafl_qemu_defs.h" +#include "libafl_qemu_arch.h" + +#define LIBAFL_QEMU_PRINTF_MAX_SIZE 4096 + /** * LibAFL QEMU header file. * @@ -11,253 +16,40 @@ * the commands. */ -/* === The private part starts here === */ - -/* This part should not be useful for most people. Callable commands are - * available at the end of this file. */ - -#define STRINGIFY(s) #s -#define XSTRINGIFY(s) STRINGIFY(s) - -// Target Specific imports / definitions -#ifdef _WIN32 - #include - #include - -typedef UINT64 libafl_word; - #define LIBAFL_CALLING_CONVENTION __fastcall - -#else - #include - - #if defined(__x86_64__) || defined(__aarch64__) - typedef uint64_t libafl_word; - #define LIBAFL_CALLING_CONVENTION __attribute__(()) - #endif - - #ifdef __arm__ - typedef uint32_t libafl_word; - #define LIBAFL_CALLING_CONVENTION __attribute__(()) - #endif -#endif - -#define LIBAFL_SYNC_EXIT_OPCODE 0x66f23a0f -#define LIBAFL_BACKDOOR_OPCODE 0x44f23a0f - -#define LIBAFL_QEMU_HDR_VERSION_NUMBER 0111 // TODO: find a nice way to set it. - -typedef enum LibaflQemuCommand { - LIBAFL_QEMU_COMMAND_START_VIRT = 0, - LIBAFL_QEMU_COMMAND_START_PHYS = 1, - LIBAFL_QEMU_COMMAND_INPUT_VIRT = 2, - LIBAFL_QEMU_COMMAND_INPUT_PHYS = 3, - LIBAFL_QEMU_COMMAND_END = 4, - LIBAFL_QEMU_COMMAND_SAVE = 5, - LIBAFL_QEMU_COMMAND_LOAD = 6, - LIBAFL_QEMU_COMMAND_VERSION = 7, - LIBAFL_QEMU_COMMAND_VADDR_FILTER_ALLOW = 8, -} LibaflExit; - -typedef enum LibaflQemuEndStatus { +enum LibaflQemuEndStatus { LIBAFL_QEMU_END_UNKNOWN = 0, LIBAFL_QEMU_END_OK = 1, LIBAFL_QEMU_END_CRASH = 2, -} LibaflExitEndParams; +}; -#ifdef _WIN32 - #define LIBAFL_DEFINE_FUNCTIONS(name, _opcode) \ - #ifdef __cplusplus \ - extern "C" { \ - #endif \ - libafl_word LIBAFL_CALLING_CONVENTION _libafl_##name##_call0(libafl_word action); \ - libafl_word LIBAFL_CALLING_CONVENTION _libafl_##name##_call1(libafl_word action, \ - ##name## libafl_word arg1); \ - libafl_word LIBAFL_CALLING_CONVENTION _libafl_##name##_call2(libafl_word action, \ - libafl_word arg1, \ - libafl_word arg2); \ - #ifdef __cplusplus \ - } \ - #endif -#else +libafl_word libafl_qemu_start_virt(void *buf_vaddr, libafl_word max_len); - #if defined(__x86_64__) - #define LIBAFL_DEFINE_FUNCTIONS(name, opcode) \ - libafl_word LIBAFL_CALLING_CONVENTION _libafl_##name##_call0( \ - libafl_word action) { \ - libafl_word ret; \ - __asm__ volatile ( \ - "mov %1, %%rax\n" \ - ".4byte " XSTRINGIFY(opcode) "\n" \ - "mov %%rax, %0\n" \ - : "=g"(ret) \ - : "g"(action) \ - : "%rax" \ - ); \ - return ret; \ - } \ - \ - libafl_word LIBAFL_CALLING_CONVENTION _libafl_##name##_call1( \ - libafl_word action, libafl_word arg1) { \ - libafl_word ret; \ - __asm__ volatile ( \ - "mov %1, %%rax\n" \ - "mov %2, %%rdi\n" \ - ".4byte " XSTRINGIFY(opcode) "\n" \ - "mov %%rax, %0\n" \ - : "=g"(ret) \ - : "g"(action), "g"(arg1) \ - : "%rax", "%rdi" \ - ); \ - return ret; \ - } \ - \ - libafl_word LIBAFL_CALLING_CONVENTION _libafl_##name##_call2( \ - libafl_word action, libafl_word arg1, libafl_word arg2) { \ - libafl_word ret; \ - __asm__ volatile ( \ - "mov %1, %%rax\n" \ - "mov %2, %%rdi\n" \ - "mov %3, %%rsi\n" \ - ".4byte " XSTRINGIFY(opcode) "\n" \ - "mov %%rax, %0\n" \ - : "=g"(ret) \ - : "g"(action), "g"(arg1), "g"(arg2) \ - : "%rax", "%rdi", "%rsi" \ - ); \ - return ret; \ - } +libafl_word libafl_qemu_start_phys(void *buf_paddr, libafl_word max_len); - #elif defined(__arm__) - #define LIBAFL_DEFINE_FUNCTIONS(name, opcode) \ - libafl_word LIBAFL_CALLING_CONVENTION _libafl_##name##_call0( \ - libafl_word action) { \ - libafl_word ret; \ - __asm__ volatile ( \ - "mov r0, %1\n" \ - ".word " XSTRINGIFY(opcode) "\n" \ - "mov %0, r0\n" \ - : "=r"(ret) \ - : "r"(action) \ - : "r0" \ - ); \ - return ret; \ - } \ - \ - libafl_word LIBAFL_CALLING_CONVENTION _libafl_##name##_call1( \ - libafl_word action, libafl_word arg1) { \ - libafl_word ret; \ - __asm__ volatile ( \ - "mov r0, %1\n" \ - "mov r1, %2\n" \ - ".word " XSTRINGIFY(opcode) "\n" \ - "mov %0, r0\n" \ - : "=r"(ret) \ - : "r"(action), "r"(arg1) \ - : "r0", "r1" \ - ); \ - return ret; \ - } \ - \ - libafl_word LIBAFL_CALLING_CONVENTION _libafl_##name##_call2( \ - libafl_word action, libafl_word arg1, libafl_word arg2) { \ - libafl_word ret; \ - __asm__ volatile ( \ - "mov r0, %1\n" \ - "mov r1, %2\n" \ - "mov r2, %3\n" \ - ".word " XSTRINGIFY(opcode) "\n" \ - "mov %0, r0\n" \ - : "=r"(ret) \ - : "r"(action), "r"(arg1), "r"(arg2) \ - : "r0", "r1", "r2" \ - ); \ - return ret; \ - } +libafl_word libafl_qemu_input_virt(void *buf_vaddr, libafl_word max_len); - #elif defined(__aarch64__) - #define LIBAFL_DEFINE_FUNCTIONS(name, opcode) \ - libafl_word LIBAFL_CALLING_CONVENTION _libafl_##name##_call0( \ - libafl_word action) { \ - libafl_word ret; \ - __asm__ volatile ( \ - "mov x0, %1\n" \ - ".word " XSTRINGIFY(opcode) "\n" \ - "mov %0, x0\n" \ - : "=r"(ret) \ - : "r"(action) \ - : "x0" \ - ); \ - return ret; \ - } \ - \ - libafl_word LIBAFL_CALLING_CONVENTION _libafl_##name##_call1( \ - libafl_word action, libafl_word arg1) { \ - libafl_word ret; \ - __asm__ volatile ( \ - "mov x0, %1\n" \ - "mov x1, %2\n" \ - ".word " XSTRINGIFY(opcode) "\n" \ - "mov %0, x0\n" \ - : "=r"(ret) \ - : "r"(action), "r"(arg1) \ - : "x0", "x1" \ - ); \ - return ret; \ - } \ - \ - libafl_word LIBAFL_CALLING_CONVENTION _libafl_##name##_call2( \ - libafl_word action, libafl_word arg1, libafl_word arg2) { \ - libafl_word ret; \ - __asm__ volatile ( \ - "mov x0, %1\n" \ - "mov x1, %2\n" \ - "mov x2, %3\n" \ - ".word " XSTRINGIFY(opcode) "\n" \ - "mov %0, x0\n" \ - : "=r"(ret) \ - : "r"(action), "r"(arg1), "r"(arg2) \ - : "x0", "x1", "x2" \ - ); \ - return ret; \ - } - #else - #warning "LibAFL QEMU Runtime does not support your architecture yet, please leave an issue." - #endif - -#endif - -// Generates sync exit functions -LIBAFL_DEFINE_FUNCTIONS(sync_exit, LIBAFL_SYNC_EXIT_OPCODE) - -// Generates backdoor functions -LIBAFL_DEFINE_FUNCTIONS(backdoor, LIBAFL_BACKDOOR_OPCODE) - -/* === The private part ends here === */ - -/* === The public part starts here === */ - -/* LibAFL QEMU Commands */ - -#define LIBAFL_QEMU_START_VIRT(buf_vaddr, max_len) \ - _libafl_sync_exit_call2(LIBAFL_QEMU_COMMAND_START_VIRT, buf_vaddr, max_len) - -#define LIBAFL_QEMU_START_PHYS(buf_paddr, max_len) \ - _libafl_sync_exit_call2(LIBAFL_QEMU_COMMAND_START_PHYS, buf_paddr, max_len) - -#define LIBAFL_QEMU_INPUT_VIRT(buf_vaddr, max_len) \ - _libafl_sync_exit_call2(LIBAFL_QEMU_COMMAND_INPUT_VIRT, buf_vaddr, max_len) - -#define LIBAFL_QEMU_INPUT_PHYS(buf_paddr, max_len) \ - _libafl_sync_exit_call2(LIBAFL_QEMU_COMMAND_INPUT_PHYS, buf_paddr, max_len) - -#define LIBAFL_QEMU_END(status) _libafl_sync_exit_call1(LIBAFL_QEMU_COMMAND_END, status) - -#define LIBAFL_QEMU_SAVE() _libafl_sync_exit_call0(LIBAFL_QEMU_COMMAND_SAVE) - -#define LIBAFL_QEMU_LOAD() _libafl_sync_exit_call0(LIBAFL_QEMU_COMMAND_LOAD) - -#define LIBAFL_QEMU_VERSION() _libafl_sync_exit_call0(LIBAFL_QEMU_COMMAND_VERSION) - -/* === The public part ends here === */ +libafl_word libafl_qemu_input_phys(void *buf_paddr, libafl_word max_len); + +void libafl_qemu_end(enum LibaflQemuEndStatus status); + +void libafl_qemu_save(void); + +void libafl_qemu_load(void); + +libafl_word libafl_qemu_version(void); + +void libafl_qemu_page_current_allow(void); + +void libafl_qemu_internal_error(void); + +void __attribute__((format(printf, 1, 2))) lqprintf(const char *fmt, ...); + +void libafl_qemu_test(void); + +void libafl_qemu_trace_vaddr_range(libafl_word start, libafl_word end); + +void libafl_qemu_trace_vaddr_size(libafl_word start, libafl_word size); + +#include "libafl_qemu_impl.h" #endif diff --git a/libafl_qemu/runtime/libafl_qemu_arch.h b/libafl_qemu/runtime/libafl_qemu_arch.h new file mode 100644 index 0000000000..1d4ba21200 --- /dev/null +++ b/libafl_qemu/runtime/libafl_qemu_arch.h @@ -0,0 +1,248 @@ +#ifndef LIBAFL_QEMU_ARCH +#define LIBAFL_QEMU_ARCH + +// TODO: slit this in subfiles? + +#include "libafl_qemu_defs.h" + +/* Arch-specific definitions + * + * Each architecture should define: + * - [type] libafl_word: native word on the target architecture (often the size of a register) + * - [macro] define STDIO_SUPPORT: if defined, more commands will be supported. + * - [macro] LIBAFL_CALLING_CONVENTION: the calling convention to follow for the architecture. it should be the same as the one use in libafl qemu. + * - [function] snprintf: the standard POSIX snprintf definition. + * - [function] va_{start,arg,end}: standard functions to handle variadic functions + */ + +// Target Specific imports / definitions +#if defined(_WIN32) + // Windows + #include + #include + + typedef UINT64 libafl_word; + #define LIBAFL_CALLING_CONVENTION __fastcall + #define STDIO_SUPPORT +#elif defined(__linux__) + // Linux + #ifdef __KERNEL__ + // Linux kernel + #include + + #if defined(__x86_64__) || defined(__aarch64__) + typedef __u64 libafl_word; + #define LIBAFL_CALLING_CONVENTION __attribute__(()) + #endif + + #ifdef __arm__ + typedef __u32 libafl_word; + #define LIBAFL_CALLING_CONVENTION __attribute__(()) + #endif + #else + // Linux userland + #include + #include + #include + + #define noinline __attribute__((noinline)) + + #if defined(__x86_64__) || defined(__aarch64__) + typedef uint64_t libafl_word; + #define LIBAFL_CALLING_CONVENTION __attribute__(()) + #endif + + #ifdef __arm__ + typedef uint32_t libafl_word; + #define LIBAFL_CALLING_CONVENTION __attribute__(()) + #endif + #endif + + #define STDIO_SUPPORT +#else + // Other + #include + #include + + #define noinline __attribute__((noinline)) + + #if defined(__x86_64__) || defined(__aarch64__) + typedef uint64_t libafl_word; + #define LIBAFL_CALLING_CONVENTION __attribute__(()) + #endif + + #ifdef __arm__ + typedef uint32_t libafl_word; + #define LIBAFL_CALLING_CONVENTION __attribute__(()) + #endif +#endif +#endif + +#ifdef _WIN32 + #define LIBAFL_DEFINE_FUNCTIONS(name, _opcode) \ + #ifdef __cplusplus \ + extern "C" { \ + #endif \ + libafl_word LIBAFL_CALLING_CONVENTION _libafl_##name##_call0(libafl_word action); \ + libafl_word LIBAFL_CALLING_CONVENTION _libafl_##name##_call1(libafl_word action, \ + ##name## libafl_word arg1); \ + libafl_word LIBAFL_CALLING_CONVENTION _libafl_##name##_call2(libafl_word action, \ + libafl_word arg1, \ + libafl_word arg2); \ + #ifdef __cplusplus \ + } \ + #endif +#else + #if defined(__x86_64__) + #define LIBAFL_DEFINE_FUNCTIONS(name, opcode) \ + libafl_word LIBAFL_CALLING_CONVENTION _libafl_##name##_call0( \ + libafl_word action) { \ + libafl_word ret; \ + __asm__ volatile ( \ + "mov %1, %%rax\n" \ + ".4byte " XSTRINGIFY(opcode) "\n" \ + "mov %%rax, %0\n" \ + : "=g"(ret) \ + : "g"(action) \ + : "%rax" \ + ); \ + return ret; \ + } \ + \ + libafl_word LIBAFL_CALLING_CONVENTION _libafl_##name##_call1( \ + libafl_word action, libafl_word arg1) { \ + libafl_word ret; \ + __asm__ volatile ( \ + "mov %1, %%rax\n" \ + "mov %2, %%rdi\n" \ + ".4byte " XSTRINGIFY(opcode) "\n" \ + "mov %%rax, %0\n" \ + : "=g"(ret) \ + : "g"(action), "g"(arg1) \ + : "%rax", "%rdi" \ + ); \ + return ret; \ + } \ + \ + libafl_word LIBAFL_CALLING_CONVENTION _libafl_##name##_call2( \ + libafl_word action, libafl_word arg1, libafl_word arg2) { \ + libafl_word ret; \ + __asm__ volatile ( \ + "mov %1, %%rax\n" \ + "mov %2, %%rdi\n" \ + "mov %3, %%rsi\n" \ + ".4byte " XSTRINGIFY(opcode) "\n" \ + "mov %%rax, %0\n" \ + : "=g"(ret) \ + : "g"(action), "g"(arg1), "g"(arg2) \ + : "%rax", "%rdi", "%rsi" \ + ); \ + return ret; \ + } + + #elif defined(__arm__) + #define LIBAFL_DEFINE_FUNCTIONS(name, opcode) \ + libafl_word LIBAFL_CALLING_CONVENTION _libafl_##name##_call0( \ + libafl_word action) { \ + libafl_word ret; \ + __asm__ volatile ( \ + "mov r0, %1\n" \ + ".word " XSTRINGIFY(opcode) "\n" \ + "mov %0, r0\n" \ + : "=r"(ret) \ + : "r"(action) \ + : "r0" \ + ); \ + return ret; \ + } \ + \ + libafl_word LIBAFL_CALLING_CONVENTION _libafl_##name##_call1( \ + libafl_word action, libafl_word arg1) { \ + libafl_word ret; \ + __asm__ volatile ( \ + "mov r0, %1\n" \ + "mov r1, %2\n" \ + ".word " XSTRINGIFY(opcode) "\n" \ + "mov %0, r0\n" \ + : "=r"(ret) \ + : "r"(action), "r"(arg1) \ + : "r0", "r1" \ + ); \ + return ret; \ + } \ + \ + libafl_word LIBAFL_CALLING_CONVENTION _libafl_##name##_call2( \ + libafl_word action, libafl_word arg1, libafl_word arg2) { \ + libafl_word ret; \ + __asm__ volatile ( \ + "mov r0, %1\n" \ + "mov r1, %2\n" \ + "mov r2, %3\n" \ + ".word " XSTRINGIFY(opcode) "\n" \ + "mov %0, r0\n" \ + : "=r"(ret) \ + : "r"(action), "r"(arg1), "r"(arg2) \ + : "r0", "r1", "r2" \ + ); \ + return ret; \ + } + + #elif defined(__aarch64__) + #define LIBAFL_DEFINE_FUNCTIONS(name, opcode) \ + libafl_word LIBAFL_CALLING_CONVENTION _libafl_##name##_call0( \ + libafl_word action) { \ + libafl_word ret; \ + __asm__ volatile ( \ + "mov x0, %1\n" \ + ".word " XSTRINGIFY(opcode) "\n" \ + "mov %0, x0\n" \ + : "=r"(ret) \ + : "r"(action) \ + : "x0" \ + ); \ + return ret; \ + } \ + \ + libafl_word LIBAFL_CALLING_CONVENTION _libafl_##name##_call1( \ + libafl_word action, libafl_word arg1) { \ + libafl_word ret; \ + __asm__ volatile ( \ + "mov x0, %1\n" \ + "mov x1, %2\n" \ + ".word " XSTRINGIFY(opcode) "\n" \ + "mov %0, x0\n" \ + : "=r"(ret) \ + : "r"(action), "r"(arg1) \ + : "x0", "x1" \ + ); \ + return ret; \ + } \ + \ + libafl_word LIBAFL_CALLING_CONVENTION _libafl_##name##_call2( \ + libafl_word action, libafl_word arg1, libafl_word arg2) { \ + libafl_word ret; \ + __asm__ volatile ( \ + "mov x0, %1\n" \ + "mov x1, %2\n" \ + "mov x2, %3\n" \ + ".word " XSTRINGIFY(opcode) "\n" \ + "mov %0, x0\n" \ + : "=r"(ret) \ + : "r"(action), "r"(arg1), "r"(arg2) \ + : "x0", "x1", "x2" \ + ); \ + return ret; \ + } + #else + #warning "LibAFL QEMU Runtime does not support your architecture yet, please leave an issue." + #endif + +// Generates sync exit functions +LIBAFL_DEFINE_FUNCTIONS(sync_exit, LIBAFL_SYNC_EXIT_OPCODE) + +// Generates backdoor functions +LIBAFL_DEFINE_FUNCTIONS(backdoor, LIBAFL_BACKDOOR_OPCODE) + +STATIC_CHECKS + +#endif diff --git a/libafl_qemu/runtime/libafl_qemu_defs.h b/libafl_qemu/runtime/libafl_qemu_defs.h new file mode 100644 index 0000000000..2866cadaac --- /dev/null +++ b/libafl_qemu/runtime/libafl_qemu_defs.h @@ -0,0 +1,37 @@ +#ifndef LIBAFL_QEMU_DEFS +#define LIBAFL_QEMU_DEFS + +#define LIBAFL_STRINGIFY(s) #s +#define XSTRINGIFY(s) LIBAFL_STRINGIFY(s) + +#if __STDC_VERSION__ >= 201112L + #define STATIC_CHECKS \ + _Static_assert(sizeof(void *) <= sizeof(libafl_word), \ + "pointer type should not be larger and libafl_word"); +#else + #define STATIC_CHECKS +#endif + +#define LIBAFL_SYNC_EXIT_OPCODE 0x66f23a0f +#define LIBAFL_BACKDOOR_OPCODE 0x44f23a0f + +#define LIBAFL_QEMU_TEST_VALUE 0xcafebabe + +#define LIBAFL_QEMU_HDR_VERSION_NUMBER 0111 // TODO: find a nice way to set it. + +typedef enum LibaflQemuCommand { + LIBAFL_QEMU_COMMAND_START_VIRT = 0, + LIBAFL_QEMU_COMMAND_START_PHYS = 1, + LIBAFL_QEMU_COMMAND_INPUT_VIRT = 2, + LIBAFL_QEMU_COMMAND_INPUT_PHYS = 3, + LIBAFL_QEMU_COMMAND_END = 4, + LIBAFL_QEMU_COMMAND_SAVE = 5, + LIBAFL_QEMU_COMMAND_LOAD = 6, + LIBAFL_QEMU_COMMAND_VERSION = 7, + LIBAFL_QEMU_COMMAND_VADDR_FILTER_ALLOW = 8, + LIBAFL_QEMU_COMMAND_INTERNAL_ERROR = 9, + LIBAFL_QEMU_COMMAND_LQPRINTF = 10, + LIBAFL_QEMU_COMMAND_TEST = 11, +} LibaflExit; + +#endif diff --git a/libafl_qemu/runtime/libafl_qemu_impl.h b/libafl_qemu/runtime/libafl_qemu_impl.h new file mode 100644 index 0000000000..21773b40c2 --- /dev/null +++ b/libafl_qemu/runtime/libafl_qemu_impl.h @@ -0,0 +1,84 @@ +#ifndef LIBAFL_QEMU_IMPL +#define LIBAFL_QEMU_IMPL + +#include "libafl_qemu.h" + +static char _lqprintf_buffer[LIBAFL_QEMU_PRINTF_MAX_SIZE] = {0}; + +noinline libafl_word libafl_qemu_start_virt(void *buf_vaddr, + libafl_word max_len) { + return _libafl_sync_exit_call2(LIBAFL_QEMU_COMMAND_START_VIRT, + (libafl_word)buf_vaddr, max_len); +} + +noinline libafl_word libafl_qemu_start_phys(void *buf_paddr, + libafl_word max_len) { + return _libafl_sync_exit_call2(LIBAFL_QEMU_COMMAND_START_PHYS, + (libafl_word)buf_paddr, max_len); +} + +noinline libafl_word libafl_qemu_input_virt(void *buf_vaddr, + libafl_word max_len) { + return _libafl_sync_exit_call2(LIBAFL_QEMU_COMMAND_INPUT_VIRT, + (libafl_word)buf_vaddr, max_len); +} + +noinline libafl_word libafl_qemu_input_phys(void *buf_paddr, + libafl_word max_len) { + return _libafl_sync_exit_call2(LIBAFL_QEMU_COMMAND_INPUT_PHYS, + (libafl_word)buf_paddr, max_len); +} + +noinline void libafl_qemu_end(enum LibaflQemuEndStatus status) { + _libafl_sync_exit_call1(LIBAFL_QEMU_COMMAND_END, status); +} + +noinline void libafl_qemu_save(void) { + _libafl_sync_exit_call0(LIBAFL_QEMU_COMMAND_SAVE); +} + +noinline void libafl_qemu_load(void) { + _libafl_sync_exit_call0(LIBAFL_QEMU_COMMAND_LOAD); +} + +noinline libafl_word libafl_qemu_version(void) { + return _libafl_sync_exit_call0(LIBAFL_QEMU_COMMAND_VERSION); +} + +noinline void libafl_qemu_internal_error(void) { + _libafl_sync_exit_call0(LIBAFL_QEMU_COMMAND_INTERNAL_ERROR); +} + +#ifdef STDIO_SUPPORT +noinline void lqprintf(const char *fmt, ...) { + va_list args; + va_start(args, fmt); + int res = vsnprintf(_lqprintf_buffer, LIBAFL_QEMU_PRINTF_MAX_SIZE, fmt, args); + va_end(args); + + if (res >= LIBAFL_QEMU_PRINTF_MAX_SIZE) { + // buffer is not big enough, either recompile the target with more + // space or print less things + libafl_qemu_internal_error(); + } + + _libafl_sync_exit_call2(LIBAFL_QEMU_COMMAND_LQPRINTF, + (libafl_word)_lqprintf_buffer, res); +} +#endif + +noinline void libafl_qemu_test(void) { + _libafl_sync_exit_call1(LIBAFL_QEMU_COMMAND_TEST, LIBAFL_QEMU_TEST_VALUE); +} + +noinline void libafl_qemu_trace_vaddr_range(libafl_word start, + libafl_word end) { + _libafl_sync_exit_call2(LIBAFL_QEMU_COMMAND_VADDR_FILTER_ALLOW, start, end); +} + +noinline void libafl_qemu_trace_vaddr_size(libafl_word start, + libafl_word size) { + libafl_qemu_trace_vaddr_range(start, start + size); +} + +#endif \ No newline at end of file diff --git a/libafl_qemu/runtime/libafl_qemu_stub_bindings.rs b/libafl_qemu/runtime/libafl_qemu_stub_bindings.rs index 7b9ad5e84e..911468761e 100644 --- a/libafl_qemu/runtime/libafl_qemu_stub_bindings.rs +++ b/libafl_qemu/runtime/libafl_qemu_stub_bindings.rs @@ -1,8 +1,12 @@ -/* 1.82.0-nightly */ -/* qemu git hash: 8f61fadbec181bfcbd305ba92a86a41376a476f7 */ +/* 1.83.0-nightly */ +/* qemu git hash: d6637939526f453c69f4c6bfe4635feb5dc5c0be */ /* automatically generated by rust-bindgen 0.69.4 */ -pub const _STDINT_H: u32 = 1; +pub const LIBAFL_SYNC_EXIT_OPCODE: u32 = 1727150607; +pub const LIBAFL_BACKDOOR_OPCODE: u32 = 1156725263; +pub const LIBAFL_QEMU_TEST_VALUE: i64 = -2401053089206453570; +pub const LIBAFL_QEMU_HDR_VERSION_NUMBER: u32 = 73; +pub const _STDIO_H: u32 = 1; pub const _FEATURES_H: u32 = 1; pub const _DEFAULT_SOURCE: u32 = 1; pub const __GLIBC_USE_ISOC23: u32 = 0; @@ -59,6 +63,48 @@ pub const __STATFS_MATCHES_STATFS64: u32 = 1; pub const __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64: u32 = 1; pub const __FD_SETSIZE: u32 = 1024; pub const _BITS_TIME64_H: u32 = 1; +pub const _____fpos_t_defined: u32 = 1; +pub const ____mbstate_t_defined: u32 = 1; +pub const _____fpos64_t_defined: u32 = 1; +pub const ____FILE_defined: u32 = 1; +pub const __FILE_defined: u32 = 1; +pub const __struct_FILE_defined: u32 = 1; +pub const _IO_EOF_SEEN: u32 = 16; +pub const _IO_ERR_SEEN: u32 = 32; +pub const _IO_USER_LOCK: u32 = 32768; +pub const __cookie_io_functions_t_defined: u32 = 1; +pub const _IOFBF: u32 = 0; +pub const _IOLBF: u32 = 1; +pub const _IONBF: u32 = 2; +pub const BUFSIZ: u32 = 8192; +pub const EOF: i32 = -1; +pub const SEEK_SET: u32 = 0; +pub const SEEK_CUR: u32 = 1; +pub const SEEK_END: u32 = 2; +pub const P_tmpdir: &[u8; 5] = b"/tmp\0"; +pub const L_tmpnam: u32 = 20; +pub const TMP_MAX: u32 = 238328; +pub const _BITS_STDIO_LIM_H: u32 = 1; +pub const FILENAME_MAX: u32 = 4096; +pub const L_ctermid: u32 = 9; +pub const FOPEN_MAX: u32 = 16; +pub const __HAVE_FLOAT128: u32 = 0; +pub const __HAVE_DISTINCT_FLOAT128: u32 = 0; +pub const __HAVE_FLOAT64X: u32 = 1; +pub const __HAVE_FLOAT64X_LONG_DOUBLE: u32 = 1; +pub const __HAVE_FLOAT16: u32 = 0; +pub const __HAVE_FLOAT32: u32 = 1; +pub const __HAVE_FLOAT64: u32 = 1; +pub const __HAVE_FLOAT32X: u32 = 1; +pub const __HAVE_FLOAT128X: u32 = 0; +pub const __HAVE_DISTINCT_FLOAT16: u32 = 0; +pub const __HAVE_DISTINCT_FLOAT32: u32 = 0; +pub const __HAVE_DISTINCT_FLOAT64: u32 = 0; +pub const __HAVE_DISTINCT_FLOAT32X: u32 = 0; +pub const __HAVE_DISTINCT_FLOAT64X: u32 = 0; +pub const __HAVE_DISTINCT_FLOAT128X: u32 = 0; +pub const __HAVE_FLOATN_NOT_TYPEDEF: u32 = 0; +pub const _STDINT_H: u32 = 1; pub const _BITS_WCHAR_H: u32 = 1; pub const _BITS_STDINT_INTN_H: u32 = 1; pub const _BITS_STDINT_UINTN_H: u32 = 1; @@ -100,9 +146,56 @@ pub const SIG_ATOMIC_MAX: u32 = 2147483647; pub const SIZE_MAX: i32 = -1; pub const WINT_MIN: u32 = 0; pub const WINT_MAX: u32 = 4294967295; -pub const LIBAFL_SYNC_EXIT_OPCODE: u32 = 1727150607; -pub const LIBAFL_BACKDOOR_OPCODE: u32 = 1156725263; -pub const LIBAFL_QEMU_HDR_VERSION_NUMBER: u32 = 73; +pub const LIBAFL_QEMU_PRINTF_MAX_SIZE: u32 = 4096; +pub const LibaflQemuCommand_LIBAFL_QEMU_COMMAND_START_VIRT: LibaflQemuCommand = + LibaflQemuCommand(0); +pub const LibaflQemuCommand_LIBAFL_QEMU_COMMAND_START_PHYS: LibaflQemuCommand = + LibaflQemuCommand(1); +pub const LibaflQemuCommand_LIBAFL_QEMU_COMMAND_INPUT_VIRT: LibaflQemuCommand = + LibaflQemuCommand(2); +pub const LibaflQemuCommand_LIBAFL_QEMU_COMMAND_INPUT_PHYS: LibaflQemuCommand = + LibaflQemuCommand(3); +pub const LibaflQemuCommand_LIBAFL_QEMU_COMMAND_END: LibaflQemuCommand = LibaflQemuCommand(4); +pub const LibaflQemuCommand_LIBAFL_QEMU_COMMAND_SAVE: LibaflQemuCommand = LibaflQemuCommand(5); +pub const LibaflQemuCommand_LIBAFL_QEMU_COMMAND_LOAD: LibaflQemuCommand = LibaflQemuCommand(6); +pub const LibaflQemuCommand_LIBAFL_QEMU_COMMAND_VERSION: LibaflQemuCommand = LibaflQemuCommand(7); +pub const LibaflQemuCommand_LIBAFL_QEMU_COMMAND_VADDR_FILTER_ALLOW: LibaflQemuCommand = + LibaflQemuCommand(8); +pub const LibaflQemuCommand_LIBAFL_QEMU_COMMAND_INTERNAL_ERROR: LibaflQemuCommand = + LibaflQemuCommand(9); +pub const LibaflQemuCommand_LIBAFL_QEMU_COMMAND_LQPRINTF: LibaflQemuCommand = LibaflQemuCommand(10); +pub const LibaflQemuCommand_LIBAFL_QEMU_COMMAND_TEST: LibaflQemuCommand = LibaflQemuCommand(11); +impl ::std::ops::BitOr for LibaflQemuCommand { + type Output = Self; + #[inline] + fn bitor(self, other: Self) -> Self { + LibaflQemuCommand(self.0 | other.0) + } +} +impl ::std::ops::BitOrAssign for LibaflQemuCommand { + #[inline] + fn bitor_assign(&mut self, rhs: LibaflQemuCommand) { + self.0 |= rhs.0; + } +} +impl ::std::ops::BitAnd for LibaflQemuCommand { + type Output = Self; + #[inline] + fn bitand(self, other: Self) -> Self { + LibaflQemuCommand(self.0 & other.0) + } +} +impl ::std::ops::BitAndAssign for LibaflQemuCommand { + #[inline] + fn bitand_assign(&mut self, rhs: LibaflQemuCommand) { + self.0 &= rhs.0; + } +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct LibaflQemuCommand(pub ::std::os::raw::c_uint); +pub use self::LibaflQemuCommand as LibaflExit; +pub type __gnuc_va_list = __builtin_va_list; pub type __u_char = ::std::os::raw::c_uchar; pub type __u_short = ::std::os::raw::c_ushort; pub type __u_int = ::std::os::raw::c_uint; @@ -195,6 +288,1171 @@ pub type __caddr_t = *mut ::std::os::raw::c_char; pub type __intptr_t = ::std::os::raw::c_long; pub type __socklen_t = ::std::os::raw::c_uint; pub type __sig_atomic_t = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct __mbstate_t { + pub __count: ::std::os::raw::c_int, + pub __value: __mbstate_t__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union __mbstate_t__bindgen_ty_1 { + pub __wch: ::std::os::raw::c_uint, + pub __wchb: [::std::os::raw::c_char; 4usize], +} +#[test] +fn bindgen_test_layout___mbstate_t__bindgen_ty_1() { + const UNINIT: ::std::mem::MaybeUninit<__mbstate_t__bindgen_ty_1> = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<__mbstate_t__bindgen_ty_1>(), + 4usize, + concat!("Size of: ", stringify!(__mbstate_t__bindgen_ty_1)) + ); + assert_eq!( + ::std::mem::align_of::<__mbstate_t__bindgen_ty_1>(), + 4usize, + concat!("Alignment of ", stringify!(__mbstate_t__bindgen_ty_1)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__wch) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__mbstate_t__bindgen_ty_1), + "::", + stringify!(__wch) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__wchb) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__mbstate_t__bindgen_ty_1), + "::", + stringify!(__wchb) + ) + ); +} +impl Default for __mbstate_t__bindgen_ty_1 { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +impl ::std::fmt::Debug for __mbstate_t__bindgen_ty_1 { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + write!(f, "__mbstate_t__bindgen_ty_1 {{ union }}") + } +} +#[test] +fn bindgen_test_layout___mbstate_t() { + const UNINIT: ::std::mem::MaybeUninit<__mbstate_t> = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<__mbstate_t>(), + 8usize, + concat!("Size of: ", stringify!(__mbstate_t)) + ); + assert_eq!( + ::std::mem::align_of::<__mbstate_t>(), + 4usize, + concat!("Alignment of ", stringify!(__mbstate_t)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__count) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__mbstate_t), + "::", + stringify!(__count) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__value) as usize - ptr as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(__mbstate_t), + "::", + stringify!(__value) + ) + ); +} +impl Default for __mbstate_t { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +impl ::std::fmt::Debug for __mbstate_t { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + write!( + f, + "__mbstate_t {{ __count: {:?}, __value: {:?} }}", + self.__count, self.__value + ) + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _G_fpos_t { + pub __pos: __off_t, + pub __state: __mbstate_t, +} +#[test] +fn bindgen_test_layout__G_fpos_t() { + const UNINIT: ::std::mem::MaybeUninit<_G_fpos_t> = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<_G_fpos_t>(), + 16usize, + concat!("Size of: ", stringify!(_G_fpos_t)) + ); + assert_eq!( + ::std::mem::align_of::<_G_fpos_t>(), + 8usize, + concat!("Alignment of ", stringify!(_G_fpos_t)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__pos) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(_G_fpos_t), + "::", + stringify!(__pos) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__state) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(_G_fpos_t), + "::", + stringify!(__state) + ) + ); +} +impl Default for _G_fpos_t { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +impl ::std::fmt::Debug for _G_fpos_t { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + write!( + f, + "_G_fpos_t {{ __pos: {:?}, __state: {:?} }}", + self.__pos, self.__state + ) + } +} +pub type __fpos_t = _G_fpos_t; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _G_fpos64_t { + pub __pos: __off64_t, + pub __state: __mbstate_t, +} +#[test] +fn bindgen_test_layout__G_fpos64_t() { + const UNINIT: ::std::mem::MaybeUninit<_G_fpos64_t> = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<_G_fpos64_t>(), + 16usize, + concat!("Size of: ", stringify!(_G_fpos64_t)) + ); + assert_eq!( + ::std::mem::align_of::<_G_fpos64_t>(), + 8usize, + concat!("Alignment of ", stringify!(_G_fpos64_t)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__pos) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(_G_fpos64_t), + "::", + stringify!(__pos) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__state) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(_G_fpos64_t), + "::", + stringify!(__state) + ) + ); +} +impl Default for _G_fpos64_t { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +impl ::std::fmt::Debug for _G_fpos64_t { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + write!( + f, + "_G_fpos64_t {{ __pos: {:?}, __state: {:?} }}", + self.__pos, self.__state + ) + } +} +pub type __fpos64_t = _G_fpos64_t; +pub type __FILE = _IO_FILE; +pub type FILE = _IO_FILE; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _IO_marker { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _IO_codecvt { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _IO_wide_data { + _unused: [u8; 0], +} +pub type _IO_lock_t = ::std::os::raw::c_void; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _IO_FILE { + pub _flags: ::std::os::raw::c_int, + pub _IO_read_ptr: *mut ::std::os::raw::c_char, + pub _IO_read_end: *mut ::std::os::raw::c_char, + pub _IO_read_base: *mut ::std::os::raw::c_char, + pub _IO_write_base: *mut ::std::os::raw::c_char, + pub _IO_write_ptr: *mut ::std::os::raw::c_char, + pub _IO_write_end: *mut ::std::os::raw::c_char, + pub _IO_buf_base: *mut ::std::os::raw::c_char, + pub _IO_buf_end: *mut ::std::os::raw::c_char, + pub _IO_save_base: *mut ::std::os::raw::c_char, + pub _IO_backup_base: *mut ::std::os::raw::c_char, + pub _IO_save_end: *mut ::std::os::raw::c_char, + pub _markers: *mut _IO_marker, + pub _chain: *mut _IO_FILE, + pub _fileno: ::std::os::raw::c_int, + pub _flags2: ::std::os::raw::c_int, + pub _old_offset: __off_t, + pub _cur_column: ::std::os::raw::c_ushort, + pub _vtable_offset: ::std::os::raw::c_schar, + pub _shortbuf: [::std::os::raw::c_char; 1usize], + pub _lock: *mut _IO_lock_t, + pub _offset: __off64_t, + pub _codecvt: *mut _IO_codecvt, + pub _wide_data: *mut _IO_wide_data, + pub _freeres_list: *mut _IO_FILE, + pub _freeres_buf: *mut ::std::os::raw::c_void, + pub _prevchain: *mut *mut _IO_FILE, + pub _mode: ::std::os::raw::c_int, + pub _unused2: [::std::os::raw::c_char; 20usize], +} +#[test] +fn bindgen_test_layout__IO_FILE() { + const UNINIT: ::std::mem::MaybeUninit<_IO_FILE> = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<_IO_FILE>(), + 216usize, + concat!("Size of: ", stringify!(_IO_FILE)) + ); + assert_eq!( + ::std::mem::align_of::<_IO_FILE>(), + 8usize, + concat!("Alignment of ", stringify!(_IO_FILE)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._flags) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(_IO_FILE), + "::", + stringify!(_flags) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._IO_read_ptr) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(_IO_FILE), + "::", + stringify!(_IO_read_ptr) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._IO_read_end) as usize - ptr as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(_IO_FILE), + "::", + stringify!(_IO_read_end) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._IO_read_base) as usize - ptr as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(_IO_FILE), + "::", + stringify!(_IO_read_base) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._IO_write_base) as usize - ptr as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(_IO_FILE), + "::", + stringify!(_IO_write_base) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._IO_write_ptr) as usize - ptr as usize }, + 40usize, + concat!( + "Offset of field: ", + stringify!(_IO_FILE), + "::", + stringify!(_IO_write_ptr) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._IO_write_end) as usize - ptr as usize }, + 48usize, + concat!( + "Offset of field: ", + stringify!(_IO_FILE), + "::", + stringify!(_IO_write_end) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._IO_buf_base) as usize - ptr as usize }, + 56usize, + concat!( + "Offset of field: ", + stringify!(_IO_FILE), + "::", + stringify!(_IO_buf_base) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._IO_buf_end) as usize - ptr as usize }, + 64usize, + concat!( + "Offset of field: ", + stringify!(_IO_FILE), + "::", + stringify!(_IO_buf_end) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._IO_save_base) as usize - ptr as usize }, + 72usize, + concat!( + "Offset of field: ", + stringify!(_IO_FILE), + "::", + stringify!(_IO_save_base) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._IO_backup_base) as usize - ptr as usize }, + 80usize, + concat!( + "Offset of field: ", + stringify!(_IO_FILE), + "::", + stringify!(_IO_backup_base) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._IO_save_end) as usize - ptr as usize }, + 88usize, + concat!( + "Offset of field: ", + stringify!(_IO_FILE), + "::", + stringify!(_IO_save_end) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._markers) as usize - ptr as usize }, + 96usize, + concat!( + "Offset of field: ", + stringify!(_IO_FILE), + "::", + stringify!(_markers) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._chain) as usize - ptr as usize }, + 104usize, + concat!( + "Offset of field: ", + stringify!(_IO_FILE), + "::", + stringify!(_chain) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._fileno) as usize - ptr as usize }, + 112usize, + concat!( + "Offset of field: ", + stringify!(_IO_FILE), + "::", + stringify!(_fileno) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._flags2) as usize - ptr as usize }, + 116usize, + concat!( + "Offset of field: ", + stringify!(_IO_FILE), + "::", + stringify!(_flags2) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._old_offset) as usize - ptr as usize }, + 120usize, + concat!( + "Offset of field: ", + stringify!(_IO_FILE), + "::", + stringify!(_old_offset) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._cur_column) as usize - ptr as usize }, + 128usize, + concat!( + "Offset of field: ", + stringify!(_IO_FILE), + "::", + stringify!(_cur_column) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._vtable_offset) as usize - ptr as usize }, + 130usize, + concat!( + "Offset of field: ", + stringify!(_IO_FILE), + "::", + stringify!(_vtable_offset) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._shortbuf) as usize - ptr as usize }, + 131usize, + concat!( + "Offset of field: ", + stringify!(_IO_FILE), + "::", + stringify!(_shortbuf) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._lock) as usize - ptr as usize }, + 136usize, + concat!( + "Offset of field: ", + stringify!(_IO_FILE), + "::", + stringify!(_lock) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._offset) as usize - ptr as usize }, + 144usize, + concat!( + "Offset of field: ", + stringify!(_IO_FILE), + "::", + stringify!(_offset) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._codecvt) as usize - ptr as usize }, + 152usize, + concat!( + "Offset of field: ", + stringify!(_IO_FILE), + "::", + stringify!(_codecvt) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._wide_data) as usize - ptr as usize }, + 160usize, + concat!( + "Offset of field: ", + stringify!(_IO_FILE), + "::", + stringify!(_wide_data) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._freeres_list) as usize - ptr as usize }, + 168usize, + concat!( + "Offset of field: ", + stringify!(_IO_FILE), + "::", + stringify!(_freeres_list) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._freeres_buf) as usize - ptr as usize }, + 176usize, + concat!( + "Offset of field: ", + stringify!(_IO_FILE), + "::", + stringify!(_freeres_buf) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._prevchain) as usize - ptr as usize }, + 184usize, + concat!( + "Offset of field: ", + stringify!(_IO_FILE), + "::", + stringify!(_prevchain) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._mode) as usize - ptr as usize }, + 192usize, + concat!( + "Offset of field: ", + stringify!(_IO_FILE), + "::", + stringify!(_mode) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._unused2) as usize - ptr as usize }, + 196usize, + concat!( + "Offset of field: ", + stringify!(_IO_FILE), + "::", + stringify!(_unused2) + ) + ); +} +impl Default for _IO_FILE { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +pub type cookie_read_function_t = ::std::option::Option< + unsafe extern "C" fn( + __cookie: *mut ::std::os::raw::c_void, + __buf: *mut ::std::os::raw::c_char, + __nbytes: usize, + ) -> __ssize_t, +>; +pub type cookie_write_function_t = ::std::option::Option< + unsafe extern "C" fn( + __cookie: *mut ::std::os::raw::c_void, + __buf: *const ::std::os::raw::c_char, + __nbytes: usize, + ) -> __ssize_t, +>; +pub type cookie_seek_function_t = ::std::option::Option< + unsafe extern "C" fn( + __cookie: *mut ::std::os::raw::c_void, + __pos: *mut __off64_t, + __w: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int, +>; +pub type cookie_close_function_t = ::std::option::Option< + unsafe extern "C" fn(__cookie: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int, +>; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct _IO_cookie_io_functions_t { + pub read: cookie_read_function_t, + pub write: cookie_write_function_t, + pub seek: cookie_seek_function_t, + pub close: cookie_close_function_t, +} +#[test] +fn bindgen_test_layout__IO_cookie_io_functions_t() { + const UNINIT: ::std::mem::MaybeUninit<_IO_cookie_io_functions_t> = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<_IO_cookie_io_functions_t>(), + 32usize, + concat!("Size of: ", stringify!(_IO_cookie_io_functions_t)) + ); + assert_eq!( + ::std::mem::align_of::<_IO_cookie_io_functions_t>(), + 8usize, + concat!("Alignment of ", stringify!(_IO_cookie_io_functions_t)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).read) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(_IO_cookie_io_functions_t), + "::", + stringify!(read) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).write) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(_IO_cookie_io_functions_t), + "::", + stringify!(write) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).seek) as usize - ptr as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(_IO_cookie_io_functions_t), + "::", + stringify!(seek) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).close) as usize - ptr as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(_IO_cookie_io_functions_t), + "::", + stringify!(close) + ) + ); +} +pub type cookie_io_functions_t = _IO_cookie_io_functions_t; +pub type va_list = __gnuc_va_list; +pub type off_t = __off_t; +pub type fpos_t = __fpos_t; +extern "C" { + pub static mut stdin: *mut FILE; +} +extern "C" { + pub static mut stdout: *mut FILE; +} +extern "C" { + pub static mut stderr: *mut FILE; +} +extern "C" { + pub fn remove(__filename: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn rename( + __old: *const ::std::os::raw::c_char, + __new: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn renameat( + __oldfd: ::std::os::raw::c_int, + __old: *const ::std::os::raw::c_char, + __newfd: ::std::os::raw::c_int, + __new: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fclose(__stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn tmpfile() -> *mut FILE; +} +extern "C" { + pub fn tmpnam(arg1: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn tmpnam_r(__s: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn tempnam( + __dir: *const ::std::os::raw::c_char, + __pfx: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn fflush(__stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fflush_unlocked(__stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fopen( + __filename: *const ::std::os::raw::c_char, + __modes: *const ::std::os::raw::c_char, + ) -> *mut FILE; +} +extern "C" { + pub fn freopen( + __filename: *const ::std::os::raw::c_char, + __modes: *const ::std::os::raw::c_char, + __stream: *mut FILE, + ) -> *mut FILE; +} +extern "C" { + pub fn fdopen(__fd: ::std::os::raw::c_int, __modes: *const ::std::os::raw::c_char) + -> *mut FILE; +} +extern "C" { + pub fn fopencookie( + __magic_cookie: *mut ::std::os::raw::c_void, + __modes: *const ::std::os::raw::c_char, + __io_funcs: cookie_io_functions_t, + ) -> *mut FILE; +} +extern "C" { + pub fn fmemopen( + __s: *mut ::std::os::raw::c_void, + __len: usize, + __modes: *const ::std::os::raw::c_char, + ) -> *mut FILE; +} +extern "C" { + pub fn open_memstream( + __bufloc: *mut *mut ::std::os::raw::c_char, + __sizeloc: *mut usize, + ) -> *mut FILE; +} +extern "C" { + pub fn setbuf(__stream: *mut FILE, __buf: *mut ::std::os::raw::c_char); +} +extern "C" { + pub fn setvbuf( + __stream: *mut FILE, + __buf: *mut ::std::os::raw::c_char, + __modes: ::std::os::raw::c_int, + __n: usize, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn setbuffer(__stream: *mut FILE, __buf: *mut ::std::os::raw::c_char, __size: usize); +} +extern "C" { + pub fn setlinebuf(__stream: *mut FILE); +} +extern "C" { + pub fn fprintf( + __stream: *mut FILE, + __format: *const ::std::os::raw::c_char, + ... + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn printf(__format: *const ::std::os::raw::c_char, ...) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sprintf( + __s: *mut ::std::os::raw::c_char, + __format: *const ::std::os::raw::c_char, + ... + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn vfprintf( + __s: *mut FILE, + __format: *const ::std::os::raw::c_char, + __arg: *mut __va_list_tag, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn vprintf( + __format: *const ::std::os::raw::c_char, + __arg: *mut __va_list_tag, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn vsprintf( + __s: *mut ::std::os::raw::c_char, + __format: *const ::std::os::raw::c_char, + __arg: *mut __va_list_tag, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn snprintf( + __s: *mut ::std::os::raw::c_char, + __maxlen: ::std::os::raw::c_ulong, + __format: *const ::std::os::raw::c_char, + ... + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn vsnprintf( + __s: *mut ::std::os::raw::c_char, + __maxlen: ::std::os::raw::c_ulong, + __format: *const ::std::os::raw::c_char, + __arg: *mut __va_list_tag, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn vasprintf( + __ptr: *mut *mut ::std::os::raw::c_char, + __f: *const ::std::os::raw::c_char, + __arg: *mut __va_list_tag, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn __asprintf( + __ptr: *mut *mut ::std::os::raw::c_char, + __fmt: *const ::std::os::raw::c_char, + ... + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn asprintf( + __ptr: *mut *mut ::std::os::raw::c_char, + __fmt: *const ::std::os::raw::c_char, + ... + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn vdprintf( + __fd: ::std::os::raw::c_int, + __fmt: *const ::std::os::raw::c_char, + __arg: *mut __va_list_tag, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn dprintf( + __fd: ::std::os::raw::c_int, + __fmt: *const ::std::os::raw::c_char, + ... + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fscanf( + __stream: *mut FILE, + __format: *const ::std::os::raw::c_char, + ... + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn scanf(__format: *const ::std::os::raw::c_char, ...) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn sscanf( + __s: *const ::std::os::raw::c_char, + __format: *const ::std::os::raw::c_char, + ... + ) -> ::std::os::raw::c_int; +} +pub type _Float32 = f32; +pub type _Float64 = f64; +pub type _Float32x = f64; +pub type _Float64x = u128; +extern "C" { + #[link_name = "\u{1}__isoc99_fscanf"] + pub fn fscanf1( + __stream: *mut FILE, + __format: *const ::std::os::raw::c_char, + ... + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}__isoc99_scanf"] + pub fn scanf1(__format: *const ::std::os::raw::c_char, ...) -> ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}__isoc99_sscanf"] + pub fn sscanf1( + __s: *const ::std::os::raw::c_char, + __format: *const ::std::os::raw::c_char, + ... + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn vfscanf( + __s: *mut FILE, + __format: *const ::std::os::raw::c_char, + __arg: *mut __va_list_tag, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn vscanf( + __format: *const ::std::os::raw::c_char, + __arg: *mut __va_list_tag, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn vsscanf( + __s: *const ::std::os::raw::c_char, + __format: *const ::std::os::raw::c_char, + __arg: *mut __va_list_tag, + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}__isoc99_vfscanf"] + pub fn vfscanf1( + __s: *mut FILE, + __format: *const ::std::os::raw::c_char, + __arg: *mut __va_list_tag, + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}__isoc99_vscanf"] + pub fn vscanf1( + __format: *const ::std::os::raw::c_char, + __arg: *mut __va_list_tag, + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[link_name = "\u{1}__isoc99_vsscanf"] + pub fn vsscanf1( + __s: *const ::std::os::raw::c_char, + __format: *const ::std::os::raw::c_char, + __arg: *mut __va_list_tag, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fgetc(__stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn getc(__stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn getchar() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn getc_unlocked(__stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn getchar_unlocked() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fgetc_unlocked(__stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fputc(__c: ::std::os::raw::c_int, __stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn putc(__c: ::std::os::raw::c_int, __stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn putchar(__c: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fputc_unlocked(__c: ::std::os::raw::c_int, __stream: *mut FILE) + -> ::std::os::raw::c_int; +} +extern "C" { + pub fn putc_unlocked(__c: ::std::os::raw::c_int, __stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn putchar_unlocked(__c: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn getw(__stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn putw(__w: ::std::os::raw::c_int, __stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fgets( + __s: *mut ::std::os::raw::c_char, + __n: ::std::os::raw::c_int, + __stream: *mut FILE, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn __getdelim( + __lineptr: *mut *mut ::std::os::raw::c_char, + __n: *mut usize, + __delimiter: ::std::os::raw::c_int, + __stream: *mut FILE, + ) -> __ssize_t; +} +extern "C" { + pub fn getdelim( + __lineptr: *mut *mut ::std::os::raw::c_char, + __n: *mut usize, + __delimiter: ::std::os::raw::c_int, + __stream: *mut FILE, + ) -> __ssize_t; +} +extern "C" { + pub fn getline( + __lineptr: *mut *mut ::std::os::raw::c_char, + __n: *mut usize, + __stream: *mut FILE, + ) -> __ssize_t; +} +extern "C" { + pub fn fputs(__s: *const ::std::os::raw::c_char, __stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn puts(__s: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ungetc(__c: ::std::os::raw::c_int, __stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fread( + __ptr: *mut ::std::os::raw::c_void, + __size: ::std::os::raw::c_ulong, + __n: ::std::os::raw::c_ulong, + __stream: *mut FILE, + ) -> ::std::os::raw::c_ulong; +} +extern "C" { + pub fn fwrite( + __ptr: *const ::std::os::raw::c_void, + __size: ::std::os::raw::c_ulong, + __n: ::std::os::raw::c_ulong, + __s: *mut FILE, + ) -> ::std::os::raw::c_ulong; +} +extern "C" { + pub fn fread_unlocked( + __ptr: *mut ::std::os::raw::c_void, + __size: usize, + __n: usize, + __stream: *mut FILE, + ) -> usize; +} +extern "C" { + pub fn fwrite_unlocked( + __ptr: *const ::std::os::raw::c_void, + __size: usize, + __n: usize, + __stream: *mut FILE, + ) -> usize; +} +extern "C" { + pub fn fseek( + __stream: *mut FILE, + __off: ::std::os::raw::c_long, + __whence: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ftell(__stream: *mut FILE) -> ::std::os::raw::c_long; +} +extern "C" { + pub fn rewind(__stream: *mut FILE); +} +extern "C" { + pub fn fseeko( + __stream: *mut FILE, + __off: __off_t, + __whence: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ftello(__stream: *mut FILE) -> __off_t; +} +extern "C" { + pub fn fgetpos(__stream: *mut FILE, __pos: *mut fpos_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fsetpos(__stream: *mut FILE, __pos: *const fpos_t) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clearerr(__stream: *mut FILE); +} +extern "C" { + pub fn feof(__stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ferror(__stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn clearerr_unlocked(__stream: *mut FILE); +} +extern "C" { + pub fn feof_unlocked(__stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn ferror_unlocked(__stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn perror(__s: *const ::std::os::raw::c_char); +} +extern "C" { + pub fn fileno(__stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn fileno_unlocked(__stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn pclose(__stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn popen( + __command: *const ::std::os::raw::c_char, + __modes: *const ::std::os::raw::c_char, + ) -> *mut FILE; +} +extern "C" { + pub fn ctermid(__s: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn flockfile(__stream: *mut FILE); +} +extern "C" { + pub fn ftrylockfile(__stream: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn funlockfile(__stream: *mut FILE); +} +extern "C" { + pub fn __uflow(arg1: *mut FILE) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn __overflow(arg1: *mut FILE, arg2: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} pub type int_least8_t = __int_least8_t; pub type int_least16_t = __int_least16_t; pub type int_least32_t = __int_least32_t; @@ -214,50 +1472,32 @@ pub type uint_fast64_t = ::std::os::raw::c_ulong; pub type intmax_t = __intmax_t; pub type uintmax_t = __uintmax_t; pub type libafl_word = u64; -pub const LibaflQemuCommand_LIBAFL_QEMU_COMMAND_START_VIRT: LibaflQemuCommand = - LibaflQemuCommand(0); -pub const LibaflQemuCommand_LIBAFL_QEMU_COMMAND_START_PHYS: LibaflQemuCommand = - LibaflQemuCommand(1); -pub const LibaflQemuCommand_LIBAFL_QEMU_COMMAND_INPUT_VIRT: LibaflQemuCommand = - LibaflQemuCommand(2); -pub const LibaflQemuCommand_LIBAFL_QEMU_COMMAND_INPUT_PHYS: LibaflQemuCommand = - LibaflQemuCommand(3); -pub const LibaflQemuCommand_LIBAFL_QEMU_COMMAND_END: LibaflQemuCommand = LibaflQemuCommand(4); -pub const LibaflQemuCommand_LIBAFL_QEMU_COMMAND_SAVE: LibaflQemuCommand = LibaflQemuCommand(5); -pub const LibaflQemuCommand_LIBAFL_QEMU_COMMAND_LOAD: LibaflQemuCommand = LibaflQemuCommand(6); -pub const LibaflQemuCommand_LIBAFL_QEMU_COMMAND_VERSION: LibaflQemuCommand = LibaflQemuCommand(7); -pub const LibaflQemuCommand_LIBAFL_QEMU_COMMAND_VADDR_FILTER_ALLOW: LibaflQemuCommand = - LibaflQemuCommand(8); -impl ::std::ops::BitOr for LibaflQemuCommand { - type Output = Self; - #[inline] - fn bitor(self, other: Self) -> Self { - LibaflQemuCommand(self.0 | other.0) - } +extern "C" { + pub fn _libafl_sync_exit_call0(action: libafl_word) -> libafl_word; } -impl ::std::ops::BitOrAssign for LibaflQemuCommand { - #[inline] - fn bitor_assign(&mut self, rhs: LibaflQemuCommand) { - self.0 |= rhs.0; - } +extern "C" { + pub fn _libafl_sync_exit_call1(action: libafl_word, arg1: libafl_word) -> libafl_word; } -impl ::std::ops::BitAnd for LibaflQemuCommand { - type Output = Self; - #[inline] - fn bitand(self, other: Self) -> Self { - LibaflQemuCommand(self.0 & other.0) - } +extern "C" { + pub fn _libafl_sync_exit_call2( + action: libafl_word, + arg1: libafl_word, + arg2: libafl_word, + ) -> libafl_word; } -impl ::std::ops::BitAndAssign for LibaflQemuCommand { - #[inline] - fn bitand_assign(&mut self, rhs: LibaflQemuCommand) { - self.0 &= rhs.0; - } +extern "C" { + pub fn _libafl_backdoor_call0(action: libafl_word) -> libafl_word; +} +extern "C" { + pub fn _libafl_backdoor_call1(action: libafl_word, arg1: libafl_word) -> libafl_word; +} +extern "C" { + pub fn _libafl_backdoor_call2( + action: libafl_word, + arg1: libafl_word, + arg2: libafl_word, + ) -> libafl_word; } -#[repr(transparent)] -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct LibaflQemuCommand(pub ::std::os::raw::c_uint); -pub use self::LibaflQemuCommand as LibaflExit; pub const LibaflQemuEndStatus_LIBAFL_QEMU_END_UNKNOWN: LibaflQemuEndStatus = LibaflQemuEndStatus(0); pub const LibaflQemuEndStatus_LIBAFL_QEMU_END_OK: LibaflQemuEndStatus = LibaflQemuEndStatus(1); pub const LibaflQemuEndStatus_LIBAFL_QEMU_END_CRASH: LibaflQemuEndStatus = LibaflQemuEndStatus(2); @@ -288,32 +1528,136 @@ impl ::std::ops::BitAndAssign for LibaflQemuEndStatus { } } #[repr(transparent)] +#[doc = " LibAFL QEMU header file.\n\n This file is a portable header file used to build target harnesses more\n conveniently. Its main purpose is to generate ready-to-use calls to\n communicate with the fuzzer. The list of commands is available at the bottom\n of this file. The rest mostly consists of macros generating the code used by\n the commands."] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct LibaflQemuEndStatus(pub ::std::os::raw::c_uint); -pub use self::LibaflQemuEndStatus as LibaflExitEndParams; extern "C" { - pub fn _libafl_sync_exit_call0(action: libafl_word) -> libafl_word; -} -extern "C" { - pub fn _libafl_sync_exit_call1(action: libafl_word, arg1: libafl_word) -> libafl_word; -} -extern "C" { - pub fn _libafl_sync_exit_call2( - action: libafl_word, - arg1: libafl_word, - arg2: libafl_word, + pub fn libafl_qemu_start_virt( + buf_vaddr: *mut ::std::os::raw::c_void, + max_len: libafl_word, ) -> libafl_word; } extern "C" { - pub fn _libafl_backdoor_call0(action: libafl_word) -> libafl_word; -} -extern "C" { - pub fn _libafl_backdoor_call1(action: libafl_word, arg1: libafl_word) -> libafl_word; -} -extern "C" { - pub fn _libafl_backdoor_call2( - action: libafl_word, - arg1: libafl_word, - arg2: libafl_word, + pub fn libafl_qemu_start_phys( + buf_paddr: *mut ::std::os::raw::c_void, + max_len: libafl_word, ) -> libafl_word; } +extern "C" { + pub fn libafl_qemu_input_virt( + buf_vaddr: *mut ::std::os::raw::c_void, + max_len: libafl_word, + ) -> libafl_word; +} +extern "C" { + pub fn libafl_qemu_input_phys( + buf_paddr: *mut ::std::os::raw::c_void, + max_len: libafl_word, + ) -> libafl_word; +} +extern "C" { + pub fn libafl_qemu_end(status: LibaflQemuEndStatus); +} +extern "C" { + pub fn libafl_qemu_save(); +} +extern "C" { + pub fn libafl_qemu_load(); +} +extern "C" { + pub fn libafl_qemu_version() -> libafl_word; +} +extern "C" { + pub fn libafl_qemu_page_current_allow(); +} +extern "C" { + pub fn libafl_qemu_internal_error(); +} +extern "C" { + pub fn lqprintf(fmt: *const ::std::os::raw::c_char, ...); +} +extern "C" { + pub fn libafl_qemu_test(); +} +extern "C" { + pub fn libafl_qemu_trace_vaddr_range(start: libafl_word, end: libafl_word); +} +extern "C" { + pub fn libafl_qemu_trace_vaddr_size(start: libafl_word, size: libafl_word); +} +extern "C" { + pub static mut _lqprintf_buffer: [::std::os::raw::c_char; 4096usize]; +} +pub type __builtin_va_list = [__va_list_tag; 1usize]; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __va_list_tag { + pub gp_offset: ::std::os::raw::c_uint, + pub fp_offset: ::std::os::raw::c_uint, + pub overflow_arg_area: *mut ::std::os::raw::c_void, + pub reg_save_area: *mut ::std::os::raw::c_void, +} +#[test] +fn bindgen_test_layout___va_list_tag() { + const UNINIT: ::std::mem::MaybeUninit<__va_list_tag> = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<__va_list_tag>(), + 24usize, + concat!("Size of: ", stringify!(__va_list_tag)) + ); + assert_eq!( + ::std::mem::align_of::<__va_list_tag>(), + 8usize, + concat!("Alignment of ", stringify!(__va_list_tag)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).gp_offset) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__va_list_tag), + "::", + stringify!(gp_offset) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).fp_offset) as usize - ptr as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(__va_list_tag), + "::", + stringify!(fp_offset) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).overflow_arg_area) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(__va_list_tag), + "::", + stringify!(overflow_arg_area) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).reg_save_area) as usize - ptr as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(__va_list_tag), + "::", + stringify!(reg_save_area) + ) + ); +} +impl Default for __va_list_tag { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} diff --git a/libafl_qemu/src/arch/x86_64.rs b/libafl_qemu/src/arch/x86_64.rs index 9e9538f083..810fda8b36 100644 --- a/libafl_qemu/src/arch/x86_64.rs +++ b/libafl_qemu/src/arch/x86_64.rs @@ -1,4 +1,4 @@ -use std::{mem::size_of, sync::OnceLock}; +use std::{mem::size_of, ops::Range, sync::OnceLock}; use capstone::arch::BuildsCapstone; use enum_map::{enum_map, EnumMap}; @@ -75,6 +75,8 @@ pub fn capstone() -> capstone::arch::x86::ArchCapstoneBuilder { pub type GuestReg = u64; +pub const PROCESS_ADDRESS_RANGE: Range = 0..0x0000_7fff_ffff_ffff; + impl crate::ArchExtras for crate::CPU { fn read_return_address(&self) -> Result where diff --git a/libafl_qemu/src/command/mod.rs b/libafl_qemu/src/command/mod.rs index f89df85d17..a980b752ba 100644 --- a/libafl_qemu/src/command/mod.rs +++ b/libafl_qemu/src/command/mod.rs @@ -2,33 +2,31 @@ use std::{ fmt, fmt::{Debug, Display, Formatter}, marker::PhantomData, + ops::Range, }; use enum_map::{Enum, EnumMap}; -#[cfg(emulation_mode = "systemmode")] -use hashbrown::HashSet; use libafl::{ executors::ExitKind, inputs::{HasTargetBytes, UsesInput}, }; use libafl_bolts::AsSlice; +use libafl_qemu_sys::GuestAddr; +#[cfg(emulation_mode = "systemmode")] +use libafl_qemu_sys::GuestPhysAddr; use libc::c_uint; use num_enum::TryFromPrimitive; use paste::paste; -#[cfg(emulation_mode = "systemmode")] -use crate::modules::QemuInstrumentationPagingFilter; use crate::{ command::parser::{ EndCommandParser, InputPhysCommandParser, InputVirtCommandParser, LoadCommandParser, - NativeCommandParser, SaveCommandParser, StartPhysCommandParser, StartVirtCommandParser, - VaddrFilterAllowRangeCommandParser, VersionCommandParser, + LqprintfCommandParser, NativeCommandParser, SaveCommandParser, StartPhysCommandParser, + StartVirtCommandParser, TestCommandParser, VaddrFilterAllowRangeCommandParser, + VersionCommandParser, }, get_exit_arch_regs, - modules::{ - EmulatorModuleTuple, HasInstrumentationFilter, QemuInstrumentationAddressRangeFilter, - StdInstrumentationFilter, - }, + modules::EmulatorModuleTuple, sync_exit::ExitArgs, Emulator, EmulatorDriverError, EmulatorDriverResult, GuestReg, InputLocation, IsSnapshotManager, Qemu, QemuMemoryChunk, QemuRWError, Regs, StdEmulatorDriver, CPU, @@ -56,40 +54,56 @@ macro_rules! define_std_command_manager { ($name:ident, [$($command:ty),+], [$($native_command_parser:ty),+]) => { paste! { pub struct $name { + has_started: bool, phantom: PhantomData, } impl Clone for $name { fn clone(&self) -> Self { Self { - phantom: PhantomData + has_started: self.has_started, + phantom: PhantomData, } } } impl Debug for $name { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!(f, stringify!($name)) + write!(f, "{} (has started? {:?})", stringify!($name), self.has_started) } } impl Default for $name { fn default() -> Self { Self { - phantom: PhantomData + has_started: false, + phantom: PhantomData, } } } + impl $name { + fn start(&mut self) -> bool { + let tmp = self.has_started; + self.has_started = true; + tmp + } + + fn has_started(&self) -> bool { + self.has_started + } + } + impl CommandManager for $name where - ET: EmulatorModuleTuple + StdInstrumentationFilter, + ET: EmulatorModuleTuple, S: UsesInput + Unpin, S::Input: HasTargetBytes, SM: IsSnapshotManager, { type Commands = [<$name Commands>]; + #[deny(unreachable_patterns)] fn parse(&self, qemu: Qemu) -> Result { let arch_regs_map: &'static EnumMap = get_exit_arch_regs(); let cmd_id = qemu.read_reg::(arch_regs_map[ExitArgs::Cmd])? as c_uint; @@ -111,7 +125,7 @@ macro_rules! define_std_command_manager { impl IsCommand<$name, StdEmulatorDriver, ET, S, SM> for [<$name Commands>] where - ET: EmulatorModuleTuple + StdInstrumentationFilter, + ET: EmulatorModuleTuple, S: UsesInput + Unpin, S::Input: HasTargetBytes, SM: IsSnapshotManager, @@ -124,12 +138,12 @@ macro_rules! define_std_command_manager { fn run(&self, emu: &mut Emulator<$name, StdEmulatorDriver, ET, S, SM>, - driver: &mut StdEmulatorDriver, + state: &mut S, input: &S::Input, ret_reg: Option ) -> Result, StdEmulatorDriver, ET, S, SM>>, EmulatorDriverError> { match self { - $([<$name Commands>]::$command(cmd) => cmd.run(emu, driver, input, ret_reg)),+ + $([<$name Commands>]::$command(cmd) => cmd.run(emu, state, input, ret_reg)),+ } } } @@ -176,7 +190,9 @@ define_std_command_manager!( LoadCommand, EndCommand, VersionCommand, - AddressRangeFilterCommand + AddressAllowCommand, + LqprintfCommand, + TestCommand ], [ StartPhysCommandParser, @@ -187,7 +203,9 @@ define_std_command_manager!( LoadCommandParser, EndCommandParser, VersionCommandParser, - VaddrFilterAllowRangeCommandParser + VaddrFilterAllowRangeCommandParser, + LqprintfCommandParser, + TestCommandParser ] ); @@ -217,22 +235,20 @@ where fn run( &self, emu: &mut Emulator, - driver: &mut ED, + state: &mut S, input: &S::Input, ret_reg: Option, ) -> Result>, EmulatorDriverError>; } -#[cfg(emulation_mode = "systemmode")] -pub type PagingFilterCommand = FilterCommand; - -pub type AddressRangeFilterCommand = FilterCommand; - #[derive(Debug, Clone)] pub enum CommandError { UnknownCommand(GuestReg), RWError(QemuRWError), VersionDifference(u64), + TestDifference(GuestReg, GuestReg), // received, expected + StartedTwice, + EndBeforeStart, } impl From for CommandError { @@ -262,7 +278,7 @@ where fn run( &self, _emu: &mut Emulator, - _driver: &mut ED, + _state: &mut S, _input: &S::Input, _ret_reg: Option, ) -> Result>, EmulatorDriverError> { @@ -274,7 +290,7 @@ where pub struct SaveCommand; impl IsCommand for SaveCommand where - ET: EmulatorModuleTuple + StdInstrumentationFilter, + ET: EmulatorModuleTuple, CM: CommandManager, S: UsesInput + Unpin, SM: IsSnapshotManager, @@ -286,7 +302,7 @@ where fn run( &self, emu: &mut Emulator, - driver: &mut StdEmulatorDriver, + _state: &mut S, _input: &S::Input, _ret_reg: Option, ) -> Result>, EmulatorDriverError> @@ -294,27 +310,10 @@ where let qemu = emu.qemu(); let snapshot_id = emu.snapshot_manager_mut().save(qemu); - driver + emu.driver_mut() .set_snapshot_id(snapshot_id) .map_err(|_| EmulatorDriverError::MultipleSnapshotDefinition)?; - #[cfg(emulation_mode = "systemmode")] - { - let emulator_modules = emu.modules_mut().modules_mut(); - - let mut allowed_paging_ids = HashSet::new(); - - let current_paging_id = qemu.current_cpu().unwrap().current_paging_id().unwrap(); - allowed_paging_ids.insert(current_paging_id); - - let paging_filter = - HasInstrumentationFilter::::filter_mut( - emulator_modules, - ); - - *paging_filter = QemuInstrumentationPagingFilter::AllowList(allowed_paging_ids); - } - Ok(None) } } @@ -335,14 +334,15 @@ where fn run( &self, emu: &mut Emulator, - driver: &mut StdEmulatorDriver, + _state: &mut S, _input: &S::Input, _ret_reg: Option, ) -> Result>, EmulatorDriverError> { let qemu = emu.qemu(); - let snapshot_id = driver + let snapshot_id = emu + .driver_mut() .snapshot_id() .ok_or(EmulatorDriverError::SnapshotNotFound)?; @@ -374,7 +374,7 @@ where fn run( &self, emu: &mut Emulator, - _driver: &mut ED, + _state: &mut S, input: &S::Input, ret_reg: Option, ) -> Result>, EmulatorDriverError> { @@ -394,11 +394,10 @@ where pub struct StartCommand { input_location: QemuMemoryChunk, } - -impl IsCommand for StartCommand +impl IsCommand, StdEmulatorDriver, ET, S, SM> for StartCommand where - CM: CommandManager, - S: UsesInput, + ET: EmulatorModuleTuple, + S: UsesInput + Unpin, S::Input: HasTargetBytes, SM: IsSnapshotManager, { @@ -408,20 +407,32 @@ where fn run( &self, - emu: &mut Emulator, - driver: &mut StdEmulatorDriver, + emu: &mut Emulator, StdEmulatorDriver, ET, S, SM>, + state: &mut S, input: &S::Input, ret_reg: Option, - ) -> Result>, EmulatorDriverError> - { + ) -> Result< + Option, StdEmulatorDriver, ET, S, SM>>, + EmulatorDriverError, + > { + if emu.command_manager_mut().start() { + return Err(EmulatorDriverError::CommandError( + CommandError::StartedTwice, + )); + } + let qemu = emu.qemu(); + + // Snapshot VM let snapshot_id = emu.snapshot_manager_mut().save(qemu); - driver + // Set snapshot ID to restore to after fuzzing ends + emu.driver_mut() .set_snapshot_id(snapshot_id) .map_err(|_| EmulatorDriverError::MultipleSnapshotDefinition)?; - driver + // Save input location for next runs + emu.driver_mut() .set_input_location(InputLocation::new( self.input_location.clone(), qemu.current_cpu().unwrap(), @@ -429,14 +440,43 @@ where )) .unwrap(); + // Write input to input location let ret_value = self .input_location .write(qemu, input.target_bytes().as_slice()); + // Unleash hooks if locked + if emu.driver_mut().unlock_hooks() { + // Prepare hooks + emu.modules_mut().first_exec_all(state); + emu.modules_mut().pre_exec_all(state, input); + } + + // Auto page filtering if option is enabled + #[cfg(emulation_mode = "systemmode")] + if emu.driver_mut().allow_page_on_start() { + if let Some(page_id) = qemu.current_cpu().unwrap().current_paging_id() { + emu.modules_mut().modules_mut().allow_page_id_all(page_id); + } + } + + #[cfg(feature = "x86_64")] + if emu.driver_mut().is_process_only() { + emu.modules_mut() + .modules_mut() + .allow_address_range_all(crate::PROCESS_ADDRESS_RANGE); + } + + // Make sure JIT cache is empty just before starting + qemu.flush_jit(); + + // Set input size in return register if there is any if let Some(reg) = ret_reg { qemu.write_reg(reg, ret_value).unwrap(); } + log::info!("Fuzzing starts"); + Ok(None) } } @@ -446,10 +486,11 @@ pub struct EndCommand { exit_kind: Option, } -impl IsCommand for EndCommand +impl IsCommand, StdEmulatorDriver, ET, S, SM> for EndCommand where - CM: CommandManager, - S: UsesInput, + ET: EmulatorModuleTuple, + S: UsesInput + Unpin, + S::Input: HasTargetBytes, SM: IsSnapshotManager, { fn usable_at_runtime(&self) -> bool { @@ -458,15 +499,24 @@ where fn run( &self, - emu: &mut Emulator, - driver: &mut StdEmulatorDriver, + emu: &mut Emulator, StdEmulatorDriver, ET, S, SM>, + _state: &mut S, _input: &S::Input, _ret_reg: Option, - ) -> Result>, EmulatorDriverError> - { + ) -> Result< + Option, StdEmulatorDriver, ET, S, SM>>, + EmulatorDriverError, + > { let qemu = emu.qemu(); - let snapshot_id = driver + if !emu.command_manager_mut().has_started() { + return Err(EmulatorDriverError::CommandError( + CommandError::EndBeforeStart, + )); + } + + let snapshot_id = emu + .driver_mut() .snapshot_id() .ok_or(EmulatorDriverError::SnapshotNotFound)?; @@ -496,7 +546,7 @@ where fn run( &self, _emu: &mut Emulator, - _driver: &mut ED, + _state: &mut S, _input: &S::Input, _ret_reg: Option, ) -> Result>, EmulatorDriverError> { @@ -512,15 +562,16 @@ where } } +#[cfg(emulation_mode = "systemmode")] #[derive(Debug, Clone)] -pub struct FilterCommand { - filter: T, +pub struct PageAllowCommand { + page_id: GuestPhysAddr, } #[cfg(emulation_mode = "systemmode")] -impl IsCommand for PagingFilterCommand +impl IsCommand for PageAllowCommand where - ET: StdInstrumentationFilter + Unpin, + ET: EmulatorModuleTuple, CM: CommandManager, S: UsesInput + Unpin, { @@ -531,25 +582,54 @@ where fn run( &self, emu: &mut Emulator, - _driver: &mut ED, + _state: &mut S, _input: &S::Input, _ret_reg: Option, ) -> Result>, EmulatorDriverError> { - let qemu_modules = emu.modules_mut().modules_mut(); - - let paging_filter = - HasInstrumentationFilter::::filter_mut(qemu_modules); - - *paging_filter = self.filter.clone(); - + emu.modules_mut() + .modules_mut() + .allow_page_id_all(self.page_id.clone()); Ok(None) } } -impl IsCommand for AddressRangeFilterCommand +#[derive(Debug, Clone)] +pub struct AddressAllowCommand { + address_range: Range, +} +impl IsCommand for AddressAllowCommand where + ET: EmulatorModuleTuple, CM: CommandManager, - S: UsesInput, + S: UsesInput + Unpin, +{ + fn usable_at_runtime(&self) -> bool { + true + } + + fn run( + &self, + emu: &mut Emulator, + _state: &mut S, + _input: &S::Input, + _ret_reg: Option, + ) -> Result>, EmulatorDriverError> { + emu.modules_mut() + .modules_mut() + .allow_address_range_all(self.address_range.clone()); + Ok(None) + } +} + +#[derive(Debug, Clone)] +pub struct LqprintfCommand { + content: String, +} +impl IsCommand for LqprintfCommand +where + ET: EmulatorModuleTuple, + CM: CommandManager, + S: UsesInput + Unpin, { fn usable_at_runtime(&self) -> bool { true @@ -558,23 +638,64 @@ where fn run( &self, _emu: &mut Emulator, - _driver: &mut ED, + _state: &mut S, _input: &S::Input, _ret_reg: Option, ) -> Result>, EmulatorDriverError> { - let qemu_modules = &mut (); - - let addr_range_filter = - HasInstrumentationFilter::::filter_mut( - qemu_modules, - ); - - *addr_range_filter = self.filter.clone(); - + print!("LQPRINTF: {}", self.content); Ok(None) } } +#[derive(Debug, Clone)] +pub struct TestCommand { + expected_value: GuestReg, + received_value: GuestReg, +} +impl IsCommand for TestCommand +where + ET: EmulatorModuleTuple, + CM: CommandManager, + S: UsesInput + Unpin, +{ + fn usable_at_runtime(&self) -> bool { + true + } + + fn run( + &self, + _emu: &mut Emulator, + _state: &mut S, + _input: &S::Input, + _ret_reg: Option, + ) -> Result>, EmulatorDriverError> { + if self.expected_value == self.received_value { + Ok(None) + } else { + Err(EmulatorDriverError::CommandError( + CommandError::TestDifference(self.received_value, self.expected_value), + )) + } + } +} + +impl TestCommand { + #[must_use] + pub fn new(received_value: GuestReg, expected_value: GuestReg) -> Self { + Self { + expected_value, + received_value, + } + } +} + +impl LqprintfCommand { + #[must_use] + pub fn new(content: String) -> Self { + Self { content } + } +} + impl VersionCommand { #[must_use] pub fn new(version: u64) -> Self { @@ -582,9 +703,10 @@ impl VersionCommand { } } -impl FilterCommand { - pub fn new(filter: T) -> Self { - Self { filter } +impl AddressAllowCommand { + #[must_use] + pub fn new(address_range: Range) -> Self { + Self { address_range } } } @@ -628,16 +750,16 @@ impl Display for VersionCommand { } } -impl Display for AddressRangeFilterCommand { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "Addr range filter: {:?}", self.filter,) +impl Display for AddressAllowCommand { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "Addr range allow: {:?}", self.address_range) } } #[cfg(emulation_mode = "systemmode")] -impl Display for PagingFilterCommand { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "Addr range filter: {:?}", self.filter,) +impl Display for PageAllowCommand { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "Allowed page: {:?}", self.page_id) } } diff --git a/libafl_qemu/src/command/parser.rs b/libafl_qemu/src/command/parser.rs index 267ee23de7..d8d34c73b2 100644 --- a/libafl_qemu/src/command/parser.rs +++ b/libafl_qemu/src/command/parser.rs @@ -1,21 +1,21 @@ -use std::sync::OnceLock; +use std::{ffi::CStr, sync::OnceLock}; use enum_map::{enum_map, EnumMap}; use libafl::{ executors::ExitKind, inputs::{HasTargetBytes, UsesInput}, }; +use libafl_bolts::AsSliceMut; use libafl_qemu_sys::{GuestAddr, GuestPhysAddr, GuestVirtAddr}; use libc::c_uint; use crate::{ command::{ - bindings, CommandError, CommandManager, EndCommand, FilterCommand, InputCommand, IsCommand, - LoadCommand, NativeExitKind, SaveCommand, StartCommand, VersionCommand, - }, - modules::{ - EmulatorModuleTuple, QemuInstrumentationAddressRangeFilter, StdInstrumentationFilter, + bindings, AddressAllowCommand, CommandError, CommandManager, EndCommand, InputCommand, + IsCommand, LoadCommand, LqprintfCommand, NativeExitKind, SaveCommand, StartCommand, + StdCommandManager, TestCommand, VersionCommand, }, + modules::EmulatorModuleTuple, sync_exit::ExitArgs, GuestReg, IsSnapshotManager, Qemu, QemuMemoryChunk, Regs, StdEmulatorDriver, }; @@ -93,10 +93,11 @@ where pub struct StartPhysCommandParser; -impl NativeCommandParser for StartPhysCommandParser +impl NativeCommandParser, StdEmulatorDriver, ET, S, SM> + for StartPhysCommandParser where - CM: CommandManager, - S: UsesInput, + ET: EmulatorModuleTuple, + S: UsesInput + Unpin, S::Input: HasTargetBytes, SM: IsSnapshotManager, { @@ -121,10 +122,11 @@ where pub struct StartVirtCommandParser; -impl NativeCommandParser for StartVirtCommandParser +impl NativeCommandParser, StdEmulatorDriver, ET, S, SM> + for StartVirtCommandParser where - CM: CommandManager, - S: UsesInput, + ET: EmulatorModuleTuple, + S: UsesInput + Unpin, S::Input: HasTargetBytes, SM: IsSnapshotManager, { @@ -150,7 +152,7 @@ where pub struct SaveCommandParser; impl NativeCommandParser for SaveCommandParser where - ET: EmulatorModuleTuple + StdInstrumentationFilter, + ET: EmulatorModuleTuple, CM: CommandManager, S: UsesInput + Unpin, SM: IsSnapshotManager, @@ -188,10 +190,12 @@ where pub struct EndCommandParser; -impl NativeCommandParser for EndCommandParser +impl NativeCommandParser, StdEmulatorDriver, ET, S, SM> + for EndCommandParser where - CM: CommandManager, - S: UsesInput, + ET: EmulatorModuleTuple, + S: UsesInput + Unpin, + S::Input: HasTargetBytes, SM: IsSnapshotManager, { type OutputCommand = EndCommand; @@ -243,10 +247,11 @@ pub struct VaddrFilterAllowRangeCommandParser; impl NativeCommandParser for VaddrFilterAllowRangeCommandParser where + ET: EmulatorModuleTuple, CM: CommandManager, - S: UsesInput, + S: UsesInput + Unpin, { - type OutputCommand = FilterCommand; + type OutputCommand = AddressAllowCommand; const COMMAND_ID: c_uint = bindings::LibaflQemuCommand_LIBAFL_QEMU_COMMAND_VADDR_FILTER_ALLOW.0; @@ -257,9 +262,70 @@ where let vaddr_start: GuestAddr = qemu.read_reg(arch_regs_map[ExitArgs::Arg1])?; let vaddr_end: GuestAddr = qemu.read_reg(arch_regs_map[ExitArgs::Arg2])?; - Ok(FilterCommand::new( - #[allow(clippy::single_range_in_vec_init)] - QemuInstrumentationAddressRangeFilter::AllowList(vec![vaddr_start..vaddr_end]), + Ok(AddressAllowCommand::new(vaddr_start..vaddr_end)) + } +} + +pub struct LqprintfCommandParser; +impl NativeCommandParser for LqprintfCommandParser +where + ET: EmulatorModuleTuple, + CM: CommandManager, + S: UsesInput + Unpin, +{ + type OutputCommand = LqprintfCommand; + const COMMAND_ID: c_uint = bindings::LibaflQemuCommand_LIBAFL_QEMU_COMMAND_LQPRINTF.0; + + #[allow(clippy::uninit_vec)] + fn parse( + qemu: Qemu, + arch_regs_map: &'static EnumMap, + ) -> Result { + let buf_addr: GuestAddr = qemu.read_reg(arch_regs_map[ExitArgs::Arg1])?; + let str_size: usize = qemu + .read_reg::(arch_regs_map[ExitArgs::Arg2])? + .try_into() + .unwrap(); // without null byte + let cpu = qemu.current_cpu().unwrap(); + + let total_size = str_size + 1; + + let mut str_copy: Vec = unsafe { + let mut res = Vec::::with_capacity(total_size); + res.set_len(total_size); + res + }; + + let mem_chunk = + QemuMemoryChunk::virt(buf_addr as GuestVirtAddr, total_size as GuestReg, cpu); + mem_chunk.read(qemu, str_copy.as_slice_mut()); + + let c_str: &CStr = CStr::from_bytes_with_nul(str_copy.as_slice()).unwrap(); + + Ok(LqprintfCommand::new(c_str.to_str().unwrap().to_string())) + } +} + +pub struct TestCommandParser; +impl NativeCommandParser for TestCommandParser +where + ET: EmulatorModuleTuple, + CM: CommandManager, + S: UsesInput + Unpin, +{ + type OutputCommand = TestCommand; + const COMMAND_ID: c_uint = bindings::LibaflQemuCommand_LIBAFL_QEMU_COMMAND_TEST.0; + + #[allow(clippy::cast_sign_loss)] + fn parse( + qemu: Qemu, + arch_regs_map: &'static EnumMap, + ) -> Result { + let received_value: GuestReg = qemu.read_reg(arch_regs_map[ExitArgs::Arg1])?; + + Ok(TestCommand::new( + received_value, + bindings::LIBAFL_QEMU_TEST_VALUE as GuestReg, )) } } diff --git a/libafl_qemu/src/emu/builder.rs b/libafl_qemu/src/emu/builder.rs index 9c9c00e6f1..2fe81bb4ce 100644 --- a/libafl_qemu/src/emu/builder.rs +++ b/libafl_qemu/src/emu/builder.rs @@ -66,7 +66,7 @@ where modules: tuple_list!(), command_manager: StdCommandManager::default(), snapshot_manager: StdSnapshotManager::default(), - driver: StdEmulatorDriver::default(), + driver: StdEmulatorDriver::builder().build(), qemu_builder: None, phantom: PhantomData, } @@ -84,7 +84,7 @@ where modules: (), command_manager: StdCommandManager::default(), snapshot_manager: FastSnapshotManager::default(), - driver: StdEmulatorDriver::default(), + driver: StdEmulatorDriver::builder().build(), qemu_builder: None, phantom: PhantomData, } diff --git a/libafl_qemu/src/emu/drivers.rs b/libafl_qemu/src/emu/drivers.rs index a07000502a..66cc0bb7c1 100644 --- a/libafl_qemu/src/emu/drivers.rs +++ b/libafl_qemu/src/emu/drivers.rs @@ -6,11 +6,14 @@ use std::{cell::OnceCell, fmt::Debug}; use libafl::{ executors::ExitKind, inputs::{HasTargetBytes, UsesInput}, + observers::ObserversTuple, }; -use libafl_bolts::os::unix_signals::Signal; +use libafl_bolts::os::{unix_signals::Signal, CTRL_C_EXIT}; +use typed_builder::TypedBuilder; use crate::{ command::{CommandError, CommandManager, InputCommand, IsCommand}, + modules::EmulatorModuleTuple, Emulator, EmulatorExitError, EmulatorExitResult, InputLocation, IsSnapshotManager, QemuShutdownCause, Regs, SnapshotId, SnapshotManagerCheckError, SnapshotManagerError, }; @@ -45,14 +48,47 @@ pub enum EmulatorDriverError { pub trait EmulatorDriver: 'static + Sized where CM: CommandManager, - S: UsesInput, + ET: EmulatorModuleTuple, + S: UsesInput + Unpin, { - fn pre_exec(&mut self, _emulator: &mut Emulator, _input: &S::Input) {} + /// Just before calling user's harness for the first time. + /// Called only once + fn first_harness_exec(emulator: &mut Emulator, state: &mut S) { + emulator.modules.first_exec_all(state); + } + /// Just before calling user's harness + fn pre_harness_exec( + emulator: &mut Emulator, + state: &mut S, + input: &S::Input, + ) { + emulator.modules.pre_exec_all(state, input); + } + + /// Just after returning from user's harness + fn post_harness_exec( + emulator: &mut Emulator, + input: &S::Input, + observers: &mut OT, + state: &mut S, + exit_kind: &mut ExitKind, + ) where + OT: ObserversTuple, + { + emulator + .modules + .post_exec_all(state, input, observers, exit_kind); + } + + /// Just before entering QEMU + fn pre_qemu_exec(_emulator: &mut Emulator, _input: &S::Input) {} + + /// Just after QEMU exits #[allow(clippy::type_complexity)] - fn post_exec( - &mut self, + fn post_qemu_exec( _emulator: &mut Emulator, + _state: &mut S, exit_reason: &mut Result, EmulatorExitError>, _input: &S::Input, ) -> Result>, EmulatorDriverError> { @@ -67,31 +103,31 @@ pub struct NopEmulatorDriver; impl EmulatorDriver for NopEmulatorDriver where CM: CommandManager, - S: UsesInput, + ET: EmulatorModuleTuple, + S: UsesInput + Unpin, { } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default, TypedBuilder)] +#[allow(clippy::struct_excessive_bools)] pub struct StdEmulatorDriver { + #[builder(default = OnceCell::new())] snapshot_id: OnceCell, + #[builder(default = OnceCell::new())] input_location: OnceCell, -} - -impl Default for StdEmulatorDriver { - fn default() -> Self { - StdEmulatorDriver::new() - } + #[builder(default = true)] + hooks_locked: bool, + #[cfg(emulation_mode = "systemmode")] + #[builder(default = false)] + allow_page_on_start: bool, + #[cfg(feature = "x86_64")] + #[builder(default = false)] + process_only: bool, + #[builder(default = false)] + print_commands: bool, } impl StdEmulatorDriver { - #[must_use] - pub fn new() -> Self { - Self { - snapshot_id: OnceCell::new(), - input_location: OnceCell::new(), - } - } - pub fn set_input_location(&self, input_location: InputLocation) -> Result<(), InputLocation> { self.input_location.set(input_location) } @@ -103,32 +139,82 @@ impl StdEmulatorDriver { pub fn snapshot_id(&self) -> Option { Some(*self.snapshot_id.get()?) } + + // return if was locked or not + pub fn unlock_hooks(&mut self) -> bool { + let was_locked = self.hooks_locked; + self.hooks_locked = false; + was_locked + } + + #[cfg(emulation_mode = "systemmode")] + pub fn allow_page_on_start(&self) -> bool { + self.allow_page_on_start + } + + #[cfg(feature = "x86_64")] + pub fn is_process_only(&self) -> bool { + self.process_only + } } // TODO: replace handlers with generics to permit compile-time customization of handlers impl EmulatorDriver for StdEmulatorDriver where CM: CommandManager, + ET: EmulatorModuleTuple, S: UsesInput + Unpin, S::Input: HasTargetBytes, SM: IsSnapshotManager, { - fn pre_exec(&mut self, emulator: &mut Emulator, input: &S::Input) { - let input_location = { self.input_location.get().cloned() }; + fn first_harness_exec(emulator: &mut Emulator, state: &mut S) { + if !emulator.driver.hooks_locked { + emulator.modules.first_exec_all(state); + } + } + + fn pre_harness_exec( + emulator: &mut Emulator, + state: &mut S, + input: &S::Input, + ) { + if !emulator.driver.hooks_locked { + emulator.modules.pre_exec_all(state, input); + } + + let input_location = { emulator.driver.input_location.get().cloned() }; if let Some(input_location) = input_location { let input_command = InputCommand::new(input_location.mem_chunk.clone(), input_location.cpu); input_command - .run(emulator, self, input, input_location.ret_register) + .run(emulator, state, input, input_location.ret_register) .unwrap(); } } - fn post_exec( - &mut self, + fn post_harness_exec( emulator: &mut Emulator, + input: &S::Input, + observers: &mut OT, + state: &mut S, + exit_kind: &mut ExitKind, + ) where + OT: ObserversTuple, + { + if !emulator.driver.hooks_locked { + emulator + .modules + .post_exec_all(state, input, observers, exit_kind); + } + } + + fn pre_qemu_exec(_emulator: &mut Emulator, _input: &S::Input) {} + + fn post_qemu_exec( + emulator: &mut Emulator, + state: &mut S, exit_reason: &mut Result, EmulatorExitError>, input: &S::Input, ) -> Result>, EmulatorDriverError> { @@ -138,7 +224,7 @@ where Ok(exit_reason) => exit_reason, Err(exit_error) => match exit_error { EmulatorExitError::UnexpectedExit => { - if let Some(snapshot_id) = self.snapshot_id.get() { + if let Some(snapshot_id) = emulator.driver.snapshot_id.get() { emulator.snapshot_manager.restore(qemu, snapshot_id)?; } return Ok(Some(EmulatorDriverResult::EndOfRun(ExitKind::Crash))); @@ -157,8 +243,15 @@ where QemuShutdownCause::GuestPanic => { return Ok(Some(EmulatorDriverResult::EndOfRun(ExitKind::Crash))) } + QemuShutdownCause::GuestShutdown | QemuShutdownCause::HostQmpQuit => { + log::warn!("Guest shutdown. Stopping fuzzing..."); + std::process::exit(CTRL_C_EXIT); + } _ => panic!("Unhandled QEMU shutdown cause: {shutdown_cause:?}."), }, + EmulatorExitResult::Timeout => { + return Ok(Some(EmulatorDriverResult::EndOfRun(ExitKind::Timeout))) + } EmulatorExitResult::Breakpoint(bp) => (bp.trigger(qemu), None), EmulatorExitResult::SyncExit(sync_backdoor) => { let command = sync_backdoor.command().clone(); @@ -167,7 +260,10 @@ where }; if let Some(cmd) = command { - cmd.run(emulator, self, input, ret_reg) + if emulator.driver.print_commands { + println!("Received command: {cmd:?}"); + } + cmd.run(emulator, state, input, ret_reg) } else { Ok(Some(EmulatorDriverResult::ReturnToHarness( exit_reason.clone(), diff --git a/libafl_qemu/src/emu/hooks.rs b/libafl_qemu/src/emu/hooks.rs index 5447996132..542d487d91 100644 --- a/libafl_qemu/src/emu/hooks.rs +++ b/libafl_qemu/src/emu/hooks.rs @@ -1125,18 +1125,18 @@ where } } - pub fn pre_exec_all(&mut self, input: &S::Input, state: &mut S) { + pub fn pre_exec_all(&mut self, state: &mut S, input: &S::Input) { unsafe { self.modules_mut() - .pre_exec_all(Self::emulator_modules_mut_unchecked(), input, state); + .pre_exec_all(Self::emulator_modules_mut_unchecked(), state, input); } } pub fn post_exec_all( &mut self, + state: &mut S, input: &S::Input, observers: &mut OT, - state: &mut S, exit_kind: &mut ExitKind, ) where OT: ObserversTuple, @@ -1144,9 +1144,9 @@ where unsafe { self.modules_mut().post_exec_all( Self::emulator_modules_mut_unchecked(), + state, input, observers, - state, exit_kind, ); } diff --git a/libafl_qemu/src/emu/mod.rs b/libafl_qemu/src/emu/mod.rs index d2a060253e..29b6bcb20d 100644 --- a/libafl_qemu/src/emu/mod.rs +++ b/libafl_qemu/src/emu/mod.rs @@ -17,7 +17,7 @@ use libafl_qemu_sys::{GuestAddr, GuestPhysAddr, GuestUsize, GuestVirtAddr}; use crate::{ breakpoint::{Breakpoint, BreakpointId}, command::{CommandError, CommandManager, NopCommandManager, StdCommandManager}, - modules::{EmulatorModuleTuple, StdInstrumentationFilter}, + modules::EmulatorModuleTuple, sync_exit::SyncExit, Qemu, QemuExitError, QemuExitReason, QemuInitError, QemuMemoryChunk, QemuShutdownCause, Regs, CPU, @@ -59,6 +59,7 @@ where QemuExit(QemuShutdownCause), // QEMU ended for some reason. Breakpoint(Breakpoint), // Breakpoint triggered. Contains the address of the trigger. SyncExit(SyncExit), // Synchronous backdoor: The guest triggered a backdoor and should return to LibAFL. + Timeout, // Timeout } impl Clone for EmulatorExitResult @@ -75,6 +76,7 @@ where EmulatorExitResult::SyncExit(sync_exit) => { EmulatorExitResult::SyncExit(sync_exit.clone()) } + EmulatorExitResult::Timeout => EmulatorExitResult::Timeout, } } } @@ -84,7 +86,7 @@ where CM: CommandManager, S: UsesInput, { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { EmulatorExitResult::QemuExit(qemu_exit) => { write!(f, "{qemu_exit:?}") @@ -95,6 +97,9 @@ where EmulatorExitResult::SyncExit(sync_exit) => { write!(f, "{sync_exit:?}") } + EmulatorExitResult::Timeout => { + write!(f, "Timeout") + } } } } @@ -123,11 +128,10 @@ where snapshot_manager: SM, modules: Pin>>, command_manager: CM, - driver: Option, + driver: ED, breakpoints_by_addr: RefCell>>, // TODO: change to RC here breakpoints_by_id: RefCell>>, qemu: Qemu, - first_exec: bool, } impl EmulatorDriverResult @@ -146,10 +150,10 @@ where } impl Debug for GuestAddrKind { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { - GuestAddrKind::Physical(paddr) => write!(f, "vaddr {paddr:x}"), - GuestAddrKind::Virtual(vaddr) => write!(f, "paddr {vaddr:x}"), + GuestAddrKind::Physical(paddr) => write!(f, "paddr {paddr:#x}"), + GuestAddrKind::Virtual(vaddr) => write!(f, "vaddr {vaddr:#x}"), } } } @@ -221,6 +225,9 @@ where EmulatorExitResult::SyncExit(sync_exit) => { write!(f, "Sync exit: {sync_exit:?}") } + EmulatorExitResult::Timeout => { + write!(f, "Timeout") + } } } } @@ -270,12 +277,12 @@ where #[must_use] pub fn driver(&self) -> &ED { - self.driver.as_ref().unwrap() + &self.driver } #[must_use] pub fn driver_mut(&mut self) -> &mut ED { - self.driver.as_mut().unwrap() + &mut self.driver } #[must_use] @@ -287,6 +294,14 @@ where pub fn snapshot_manager_mut(&mut self) -> &mut SM { &mut self.snapshot_manager } + + pub fn command_manager(&self) -> &CM { + &self.command_manager + } + + pub fn command_manager_mut(&mut self) -> &mut CM { + &mut self.command_manager + } } impl Emulator @@ -330,45 +345,20 @@ where modules: EmulatorModules::new(qemu, modules), command_manager, snapshot_manager, - driver: Some(driver), + driver, breakpoints_by_addr: RefCell::new(HashMap::new()), breakpoints_by_id: RefCell::new(HashMap::new()), - first_exec: true, qemu, }) } - - pub fn first_exec_all(&mut self, state: &mut S) { - if self.first_exec { - self.modules.first_exec_all(state); - self.first_exec = false; - } - } - - pub fn pre_exec_all(&mut self, input: &S::Input, state: &mut S) { - self.modules.pre_exec_all(input, state); - } - - pub fn post_exec_all( - &mut self, - input: &S::Input, - observers: &mut OT, - state: &mut S, - exit_kind: &mut ExitKind, - ) where - OT: ObserversTuple, - { - self.modules - .post_exec_all(input, observers, state, exit_kind); - } } impl Emulator where CM: CommandManager, ED: EmulatorDriver, - ET: StdInstrumentationFilter + Unpin, - S: UsesInput, + ET: EmulatorModuleTuple + Unpin, + S: UsesInput + Unpin, { /// This function will run the emulator until the exit handler decides to stop the execution for /// whatever reason, depending on the choosen handler. @@ -380,20 +370,20 @@ where /// Of course, the emulated target is not contained securely and can corrupt state or interact with the operating system. pub unsafe fn run( &mut self, + state: &mut S, input: &S::Input, ) -> Result, EmulatorDriverError> { - let mut driver = self.driver.take().unwrap(); - loop { // Insert input if the location is already known - driver.pre_exec(self, input); + ED::pre_qemu_exec(self, input); // Run QEMU let mut exit_reason = self.run_qemu(); // Handle QEMU exit - if let Some(exit_handler_result) = driver.post_exec(self, &mut exit_reason, input)? { - self.driver = Some(driver); + if let Some(exit_handler_result) = + ED::post_qemu_exec(self, state, &mut exit_reason, input)? + { return Ok(exit_handler_result); } } @@ -412,6 +402,7 @@ where QemuExitReason::End(qemu_shutdown_cause) => { EmulatorExitResult::QemuExit(qemu_shutdown_cause) } + QemuExitReason::Timeout => EmulatorExitResult::Timeout, QemuExitReason::Breakpoint(bp_addr) => { let bp = self .breakpoints_by_addr @@ -431,6 +422,29 @@ where }), } } + + /// First exec of Emulator, called before calling to user harness the first time + pub fn first_exec(&mut self, state: &mut S) { + ED::first_harness_exec(self, state); + } + + /// Pre exec of Emulator, called before calling to user harness + pub fn pre_exec(&mut self, state: &mut S, input: &S::Input) { + ED::pre_harness_exec(self, state, input); + } + + /// Post exec of Emulator, called before calling to user harness + pub fn post_exec( + &mut self, + input: &S::Input, + observers: &mut OT, + state: &mut S, + exit_kind: &mut ExitKind, + ) where + OT: ObserversTuple, + { + ED::post_harness_exec(self, input, observers, state, exit_kind); + } } #[allow(clippy::unused_self)] diff --git a/libafl_qemu/src/emu/snapshot.rs b/libafl_qemu/src/emu/snapshot.rs index 7b3e9d64a8..8d9f1a2c55 100644 --- a/libafl_qemu/src/emu/snapshot.rs +++ b/libafl_qemu/src/emu/snapshot.rs @@ -6,6 +6,8 @@ use std::{ use crate::Qemu; pub trait IsSnapshotManager: Clone + Debug { + fn init(&mut self, _qemu: Qemu) {} + fn save(&mut self, qemu: Qemu) -> SnapshotId; fn restore(&mut self, qemu: Qemu, snapshot_id: &SnapshotId) -> Result<(), SnapshotManagerError>; diff --git a/libafl_qemu/src/emu/systemmode.rs b/libafl_qemu/src/emu/systemmode.rs index e025ea9f49..450144e393 100644 --- a/libafl_qemu/src/emu/systemmode.rs +++ b/libafl_qemu/src/emu/systemmode.rs @@ -1,17 +1,13 @@ use std::fmt::Debug; use hashbrown::HashMap; -use libafl::{ - inputs::{HasTargetBytes, UsesInput}, - state::{HasExecutions, State}, -}; +use libafl::inputs::UsesInput; use libafl_qemu_sys::GuestPhysAddr; use crate::{ - command::{CommandManager, StdCommandManager}, + command::CommandManager, emu::{IsSnapshotManager, QemuSnapshotCheckResult}, - DeviceSnapshotFilter, Emulator, EmulatorBuilder, Qemu, SnapshotId, SnapshotManagerError, - StdEmulatorDriver, + DeviceSnapshotFilter, Emulator, Qemu, SnapshotId, SnapshotManagerError, }; #[derive(Debug, Clone)] @@ -83,6 +79,12 @@ pub struct QemuSnapshotManager { is_sync: bool, } +impl Default for QemuSnapshotManager { + fn default() -> Self { + QemuSnapshotManager::new(true) + } +} + impl QemuSnapshotManager { pub fn new(is_sync: bool) -> Self { Self { is_sync } diff --git a/libafl_qemu/src/executor.rs b/libafl_qemu/src/executor.rs index e43ac51e87..d426fd793c 100644 --- a/libafl_qemu/src/executor.rs +++ b/libafl_qemu/src/executor.rs @@ -31,10 +31,10 @@ use libafl_bolts::{ os::unix_signals::{ucontext_t, Signal}, tuples::RefIndexable, }; +#[cfg(emulation_mode = "systemmode")] +use libafl_qemu_sys::libafl_exit_request_timeout; #[cfg(emulation_mode = "usermode")] use libafl_qemu_sys::libafl_qemu_handle_crash; -#[cfg(emulation_mode = "systemmode")] -use libafl_qemu_sys::qemu_system_debug_request; #[cfg(emulation_mode = "usermode")] use libafl_qemu_sys::siginfo_t; #[cfg(emulation_mode = "systemmode")] @@ -42,17 +42,18 @@ use libc::siginfo_t; #[cfg(emulation_mode = "usermode")] use crate::EmulatorModules; -use crate::{command::CommandManager, modules::EmulatorModuleTuple, Emulator}; +use crate::{command::CommandManager, modules::EmulatorModuleTuple, Emulator, EmulatorDriver}; pub struct QemuExecutor<'a, CM, ED, ET, H, OT, S, SM> where CM: CommandManager, ET: EmulatorModuleTuple, - H: FnMut(&mut Emulator, &S::Input) -> ExitKind, + H: FnMut(&mut Emulator, &mut S, &S::Input) -> ExitKind, OT: ObserversTuple, S: State, { inner: StatefulInProcessExecutor<'a, H, OT, S, Emulator>, + first_exec: bool, } #[cfg(emulation_mode = "usermode")] @@ -86,7 +87,7 @@ pub unsafe fn inproc_qemu_timeout_handler( Z: HasObjective, { if BREAK_ON_TMOUT { - qemu_system_debug_request(); + libafl_exit_request_timeout(); } else { libafl::executors::hooks::unix::unix_signal_handler::inproc_timeout_handler::( signal, info, context, data, @@ -98,7 +99,7 @@ impl<'a, CM, ED, ET, H, OT, S, SM> Debug for QemuExecutor<'a, CM, ED, ET, H, OT, where CM: CommandManager, ET: EmulatorModuleTuple + Debug, - H: FnMut(&mut Emulator, &S::Input) -> ExitKind, + H: FnMut(&mut Emulator, &mut S, &S::Input) -> ExitKind, OT: ObserversTuple + Debug, S: State, { @@ -113,7 +114,7 @@ impl<'a, CM, ED, ET, H, OT, S, SM> QemuExecutor<'a, CM, ED, ET, H, OT, S, SM> where CM: CommandManager, ET: EmulatorModuleTuple, - H: FnMut(&mut Emulator, &S::Input) -> ExitKind, + H: FnMut(&mut Emulator, &mut S, &S::Input) -> ExitKind, OT: ObserversTuple, S: State, { @@ -127,6 +128,7 @@ where timeout: Duration, ) -> Result where + ED: EmulatorDriver, EM: EventFirer + EventRestarter, OF: Feedback, S: Unpin + State + HasExecutions + HasCorpus + HasSolutions, @@ -166,7 +168,10 @@ where > as *const c_void; } - Ok(Self { inner }) + Ok(Self { + inner, + first_exec: true, + }) } pub fn inner(&self) -> &StatefulInProcessExecutor<'a, H, OT, S, Emulator> { @@ -191,9 +196,10 @@ impl<'a, CM, ED, EM, ET, H, OT, S, SM, Z> Executor for QemuExecutor<'a, CM, ED, ET, H, OT, S, SM> where CM: CommandManager, + ED: EmulatorDriver, EM: UsesState, ET: EmulatorModuleTuple, - H: FnMut(&mut Emulator, &S::Input) -> ExitKind, + H: FnMut(&mut Emulator, &mut S, &S::Input) -> ExitKind, OT: ObserversTuple, S: State + HasExecutions + Unpin, Z: UsesState, @@ -205,17 +211,18 @@ where mgr: &mut EM, input: &Self::Input, ) -> Result { - self.inner - .exposed_executor_state_mut() - .first_exec_all(state); + if self.first_exec { + self.inner.exposed_executor_state_mut().first_exec(state); + self.first_exec = false; + } self.inner .exposed_executor_state_mut() - .pre_exec_all(input, state); + .pre_exec(state, input); let mut exit_kind = self.inner.run_target(fuzzer, state, mgr, input)?; - self.inner.exposed_executor_state.post_exec_all( + self.inner.exposed_executor_state.post_exec( input, &mut *self.inner.inner.observers_mut(), state, @@ -230,7 +237,7 @@ impl<'a, CM, ED, ET, H, OT, S, SM> UsesState for QemuExecutor<'a, CM, ED, ET, H, where CM: CommandManager, ET: EmulatorModuleTuple, - H: FnMut(&mut Emulator, &S::Input) -> ExitKind, + H: FnMut(&mut Emulator, &mut S, &S::Input) -> ExitKind, OT: ObserversTuple, S: State, { @@ -241,7 +248,7 @@ impl<'a, CM, ED, ET, H, OT, S, SM> UsesObservers for QemuExecutor<'a, CM, ED, ET where CM: CommandManager, ET: EmulatorModuleTuple, - H: FnMut(&mut Emulator, &S::Input) -> ExitKind, + H: FnMut(&mut Emulator, &mut S, &S::Input) -> ExitKind, OT: ObserversTuple, S: State, { @@ -252,7 +259,7 @@ impl<'a, CM, ED, ET, H, OT, S, SM> HasObservers for QemuExecutor<'a, CM, ED, ET, where CM: CommandManager, ET: EmulatorModuleTuple, - H: FnMut(&mut Emulator, &S::Input) -> ExitKind, + H: FnMut(&mut Emulator, &mut S, &S::Input) -> ExitKind, OT: ObserversTuple, S: State, { diff --git a/libafl_qemu/src/modules/calls.rs b/libafl_qemu/src/modules/calls.rs index 4352cd2d9a..1bf3023894 100644 --- a/libafl_qemu/src/modules/calls.rs +++ b/libafl_qemu/src/modules/calls.rs @@ -10,11 +10,12 @@ use libafl_bolts::tuples::{Handle, Handled, MatchFirstType, MatchNameRef}; use libafl_qemu_sys::GuestAddr; use thread_local::ThreadLocal; +#[cfg(emulation_mode = "systemmode")] +use crate::modules::{NopPageFilter, NOP_PAGE_FILTER}; use crate::{ capstone, modules::{ - EmulatorModule, EmulatorModuleTuple, EmulatorModules, HasInstrumentationFilter, IsFilter, - QemuInstrumentationAddressRangeFilter, + AddressFilter, EmulatorModule, EmulatorModuleTuple, EmulatorModules, StdAddressFilter, }, qemu::{ArchExtras, Hook}, Qemu, @@ -218,7 +219,7 @@ pub struct CallTracerModule where T: CallTraceCollectorTuple, { - filter: QemuInstrumentationAddressRangeFilter, + filter: StdAddressFilter, cs: Capstone, collectors: Option, } @@ -228,7 +229,7 @@ where T: CallTraceCollectorTuple + Debug, { #[must_use] - pub fn new(filter: QemuInstrumentationAddressRangeFilter, collectors: T) -> Self { + pub fn new(filter: StdAddressFilter, collectors: T) -> Self { Self { filter, cs: capstone().detail(true).build().unwrap(), @@ -238,7 +239,7 @@ where #[must_use] pub fn must_instrument(&self, addr: GuestAddr) -> bool { - self.filter.allowed(addr) + self.filter.allowed(&addr) } fn on_ret( @@ -383,24 +384,15 @@ where } } -impl HasInstrumentationFilter for CallTracerModule -where - T: CallTraceCollectorTuple, -{ - fn filter(&self) -> &QemuInstrumentationAddressRangeFilter { - &self.filter - } - - fn filter_mut(&mut self) -> &mut QemuInstrumentationAddressRangeFilter { - &mut self.filter - } -} - impl EmulatorModule for CallTracerModule where S: Unpin + UsesInput, T: CallTraceCollectorTuple + Debug, { + type ModuleAddressFilter = StdAddressFilter; + #[cfg(emulation_mode = "systemmode")] + type ModulePageFilter = NopPageFilter; + fn init_module(&self, emulator_modules: &mut EmulatorModules) where ET: EmulatorModuleTuple, @@ -414,8 +406,8 @@ where fn pre_exec( &mut self, - _state: &mut S, emulator_modules: &mut EmulatorModules, + _state: &mut S, input: &S::Input, ) where ET: EmulatorModuleTuple, @@ -428,8 +420,8 @@ where fn post_exec( &mut self, - _state: &mut S, emulator_modules: &mut EmulatorModules, + _state: &mut S, input: &S::Input, observers: &mut OT, exit_kind: &mut ExitKind, @@ -444,6 +436,24 @@ where exit_kind, ); } + + fn address_filter(&self) -> &Self::ModuleAddressFilter { + &self.filter + } + + fn address_filter_mut(&mut self) -> &mut Self::ModuleAddressFilter { + &mut self.filter + } + + #[cfg(emulation_mode = "systemmode")] + fn page_filter(&self) -> &Self::ModulePageFilter { + &NopPageFilter + } + + #[cfg(emulation_mode = "systemmode")] + fn page_filter_mut(&mut self) -> &mut Self::ModulePageFilter { + unsafe { addr_of_mut!(NOP_PAGE_FILTER).as_mut().unwrap().get_mut() } + } } // TODO support multiple threads with thread local callstack diff --git a/libafl_qemu/src/modules/cmplog.rs b/libafl_qemu/src/modules/cmplog.rs index 165eb86fca..24711f8489 100644 --- a/libafl_qemu/src/modules/cmplog.rs +++ b/libafl_qemu/src/modules/cmplog.rs @@ -1,3 +1,6 @@ +#[cfg(emulation_mode = "systemmode")] +use std::ptr::addr_of_mut; + #[cfg(emulation_mode = "usermode")] use capstone::{arch::BuildsCapstone, Capstone, InsnDetail}; use hashbrown::HashMap; @@ -11,14 +14,13 @@ pub use libafl_targets::{ }; use serde::{Deserialize, Serialize}; +#[cfg(emulation_mode = "systemmode")] +use crate::modules::{NopPageFilter, NOP_PAGE_FILTER}; #[cfg(emulation_mode = "usermode")] use crate::{capstone, qemu::ArchExtras, CallingConvention, Qemu}; use crate::{ emu::EmulatorModules, - modules::{ - hash_me, EmulatorModule, EmulatorModuleTuple, HasInstrumentationFilter, IsFilter, - QemuInstrumentationAddressRangeFilter, - }, + modules::{hash_me, AddressFilter, EmulatorModule, EmulatorModuleTuple, StdAddressFilter}, qemu::Hook, }; @@ -46,34 +48,24 @@ libafl_bolts::impl_serdeany!(QemuCmpsMapMetadata); #[derive(Debug)] pub struct CmpLogModule { - filter: QemuInstrumentationAddressRangeFilter, + address_filter: StdAddressFilter, } impl CmpLogModule { #[must_use] - pub fn new(filter: QemuInstrumentationAddressRangeFilter) -> Self { - Self { filter } + pub fn new(address_filter: StdAddressFilter) -> Self { + Self { address_filter } } #[must_use] pub fn must_instrument(&self, addr: GuestAddr) -> bool { - self.filter.allowed(addr) + self.address_filter.allowed(&addr) } } impl Default for CmpLogModule { fn default() -> Self { - Self::new(QemuInstrumentationAddressRangeFilter::None) - } -} - -impl HasInstrumentationFilter for CmpLogModule { - fn filter(&self) -> &QemuInstrumentationAddressRangeFilter { - &self.filter - } - - fn filter_mut(&mut self) -> &mut QemuInstrumentationAddressRangeFilter { - &mut self.filter + Self::new(StdAddressFilter::default()) } } @@ -81,7 +73,11 @@ impl EmulatorModule for CmpLogModule where S: Unpin + UsesInput + HasMetadata, { - fn first_exec(&mut self, _state: &mut S, emulator_modules: &mut EmulatorModules) + type ModuleAddressFilter = StdAddressFilter; + #[cfg(emulation_mode = "systemmode")] + type ModulePageFilter = NopPageFilter; + + fn first_exec(&mut self, emulator_modules: &mut EmulatorModules, _state: &mut S) where ET: EmulatorModuleTuple, { @@ -93,28 +89,46 @@ where Hook::Raw(trace_cmp8_cmplog), ); } + + fn address_filter(&self) -> &Self::ModuleAddressFilter { + &self.address_filter + } + + fn address_filter_mut(&mut self) -> &mut Self::ModuleAddressFilter { + &mut self.address_filter + } + + #[cfg(emulation_mode = "systemmode")] + fn page_filter(&self) -> &Self::ModulePageFilter { + &NopPageFilter + } + + #[cfg(emulation_mode = "systemmode")] + fn page_filter_mut(&mut self) -> &mut Self::ModulePageFilter { + unsafe { addr_of_mut!(NOP_PAGE_FILTER).as_mut().unwrap().get_mut() } + } } #[derive(Debug)] pub struct CmpLogChildModule { - filter: QemuInstrumentationAddressRangeFilter, + address_filter: StdAddressFilter, } impl CmpLogChildModule { #[must_use] - pub fn new(filter: QemuInstrumentationAddressRangeFilter) -> Self { - Self { filter } + pub fn new(address_filter: StdAddressFilter) -> Self { + Self { address_filter } } #[must_use] pub fn must_instrument(&self, addr: GuestAddr) -> bool { - self.filter.allowed(addr) + self.address_filter.allowed(&addr) } } impl Default for CmpLogChildModule { fn default() -> Self { - Self::new(QemuInstrumentationAddressRangeFilter::None) + Self::new(StdAddressFilter::default()) } } @@ -122,9 +136,13 @@ impl EmulatorModule for CmpLogChildModule where S: Unpin + UsesInput + HasMetadata, { + type ModuleAddressFilter = StdAddressFilter; + #[cfg(emulation_mode = "systemmode")] + type ModulePageFilter = NopPageFilter; + const HOOKS_DO_SIDE_EFFECTS: bool = false; - fn first_exec(&mut self, _state: &mut S, emulator_modules: &mut EmulatorModules) + fn first_exec(&mut self, emulator_modules: &mut EmulatorModules, _state: &mut S) where ET: EmulatorModuleTuple, { @@ -136,6 +154,24 @@ where Hook::Raw(trace_cmp8_cmplog), ); } + + fn address_filter(&self) -> &Self::ModuleAddressFilter { + &self.address_filter + } + + fn address_filter_mut(&mut self) -> &mut Self::ModuleAddressFilter { + &mut self.address_filter + } + + #[cfg(emulation_mode = "systemmode")] + fn page_filter(&self) -> &Self::ModulePageFilter { + &NopPageFilter + } + + #[cfg(emulation_mode = "systemmode")] + fn page_filter_mut(&mut self) -> &mut Self::ModulePageFilter { + unsafe { addr_of_mut!(NOP_PAGE_FILTER).as_mut().unwrap().get_mut() } + } } pub fn gen_unique_cmp_ids( @@ -214,23 +250,23 @@ pub extern "C" fn trace_cmp8_cmplog(_: *const (), id: u64, v0: u64, v1: u64) { #[cfg(emulation_mode = "usermode")] #[derive(Debug)] pub struct CmpLogRoutinesModule { - filter: QemuInstrumentationAddressRangeFilter, + address_filter: StdAddressFilter, cs: Capstone, } #[cfg(emulation_mode = "usermode")] impl CmpLogRoutinesModule { #[must_use] - pub fn new(filter: QemuInstrumentationAddressRangeFilter) -> Self { + pub fn new(address_filter: StdAddressFilter) -> Self { Self { - filter, + address_filter, cs: capstone().detail(true).build().unwrap(), } } #[must_use] pub fn must_instrument(&self, addr: GuestAddr) -> bool { - self.filter.allowed(addr) + self.address_filter.allowed(&addr) } extern "C" fn on_call(k: u64, _pc: GuestAddr) { @@ -347,23 +383,16 @@ impl CmpLogRoutinesModule { } } -#[cfg(emulation_mode = "usermode")] -impl HasInstrumentationFilter for CmpLogRoutinesModule { - fn filter(&self) -> &QemuInstrumentationAddressRangeFilter { - &self.filter - } - - fn filter_mut(&mut self) -> &mut QemuInstrumentationAddressRangeFilter { - &mut self.filter - } -} - #[cfg(emulation_mode = "usermode")] impl EmulatorModule for CmpLogRoutinesModule where S: Unpin + UsesInput, { - fn first_exec(&mut self, _state: &mut S, emulator_modules: &mut EmulatorModules) + type ModuleAddressFilter = StdAddressFilter; + #[cfg(emulation_mode = "systemmode")] + type ModulePageFilter = NopPageFilter; + + fn first_exec(&mut self, emulator_modules: &mut EmulatorModules, _state: &mut S) where ET: EmulatorModuleTuple, { @@ -373,4 +402,22 @@ where Hook::Empty, ); } + + fn address_filter(&self) -> &Self::ModuleAddressFilter { + &self.address_filter + } + + fn address_filter_mut(&mut self) -> &mut Self::ModuleAddressFilter { + &mut self.address_filter + } + + #[cfg(emulation_mode = "systemmode")] + fn page_filter(&self) -> &Self::ModulePageFilter { + &NopPageFilter + } + + #[cfg(emulation_mode = "systemmode")] + fn page_filter_mut(&mut self) -> &mut Self::ModulePageFilter { + &mut NopPageFilter + } } diff --git a/libafl_qemu/src/modules/edges.rs b/libafl_qemu/src/modules/edges.rs index 28a7d8e6c8..6cec27f1ed 100644 --- a/libafl_qemu/src/modules/edges.rs +++ b/libafl_qemu/src/modules/edges.rs @@ -1,4 +1,4 @@ -use std::{cell::UnsafeCell, cmp::max}; +use std::{cell::UnsafeCell, cmp::max, fmt::Debug}; use hashbrown::{hash_map::Entry, HashMap}; use libafl::{inputs::UsesInput, HasMetadata}; @@ -11,13 +11,11 @@ pub use libafl_targets::{ }; use serde::{Deserialize, Serialize}; -#[cfg(emulation_mode = "systemmode")] -use crate::modules::QemuInstrumentationPagingFilter; use crate::{ emu::EmulatorModules, modules::{ - hash_me, EmulatorModule, EmulatorModuleTuple, HasInstrumentationFilter, IsFilter, - QemuInstrumentationAddressRangeFilter, + hash_me, AddressFilter, EmulatorModule, EmulatorModuleTuple, PageFilter, StdAddressFilter, + StdPageFilter, }, qemu::Hook, }; @@ -32,6 +30,8 @@ pub struct QemuEdgesMapMetadata { pub current_id: u64, } +libafl_bolts::impl_serdeany!(QemuEdgesMapMetadata); + impl QemuEdgesMapMetadata { #[must_use] pub fn new() -> Self { @@ -42,481 +42,511 @@ impl QemuEdgesMapMetadata { } } -libafl_bolts::impl_serdeany!(QemuEdgesMapMetadata); +/// Standard edge coverage module, adapted to most use cases +pub type StdEdgeCoverageModule = StdEdgeCoverageFullModule; -#[cfg(emulation_mode = "usermode")] -#[derive(Debug)] -pub struct EdgeCoverageModule { - address_filter: QemuInstrumentationAddressRangeFilter, - use_hitcounts: bool, +/// Standard edge coverage module builder, adapted to most use cases +pub type StdEdgeCoverageModuleBuilder = StdEdgeCoverageFullModuleBuilder; + +pub type CollidingEdgeCoverageModule = EdgeCoverageModule; + +pub trait EdgeCoverageVariant: 'static + Debug { + const DO_SIDE_EFFECTS: bool = true; + + fn jit_hitcount(&mut self, _emulator_modules: &mut EmulatorModules) + where + AF: AddressFilter, + ET: EmulatorModuleTuple, + PF: PageFilter, + S: Unpin + UsesInput + HasMetadata, + { + panic!("JIT hitcount is not supported.") + } + + fn jit_no_hitcount(&mut self, _emulator_modules: &mut EmulatorModules) + where + AF: AddressFilter, + ET: EmulatorModuleTuple, + PF: PageFilter, + S: Unpin + UsesInput + HasMetadata, + { + panic!("JIT no hitcount is not supported.") + } + + fn fn_hitcount(&mut self, _emulator_modules: &mut EmulatorModules) + where + AF: AddressFilter, + ET: EmulatorModuleTuple, + PF: PageFilter, + S: Unpin + UsesInput + HasMetadata, + { + panic!("Func hitcount is not supported.") + } + + fn fn_no_hitcount(&mut self, _emulator_modules: &mut EmulatorModules) + where + AF: AddressFilter, + ET: EmulatorModuleTuple, + PF: PageFilter, + S: Unpin + UsesInput + HasMetadata, + { + panic!("Func no hitcount is not supported.") + } } -#[cfg(emulation_mode = "systemmode")] #[derive(Debug)] -pub struct EdgeCoverageModule { - address_filter: QemuInstrumentationAddressRangeFilter, - paging_filter: QemuInstrumentationPagingFilter, - use_hitcounts: bool, +pub struct EdgeCoverageFullVariant; + +pub type StdEdgeCoverageFullModule = + EdgeCoverageModule; +pub type StdEdgeCoverageFullModuleBuilder = + EdgeCoverageModuleBuilder; + +impl EdgeCoverageVariant for EdgeCoverageFullVariant { + fn jit_hitcount(&mut self, emulator_modules: &mut EmulatorModules) + where + AF: AddressFilter, + ET: EmulatorModuleTuple, + PF: PageFilter, + S: Unpin + UsesInput + HasMetadata, + { + let hook_id = emulator_modules.edges( + Hook::Function(gen_unique_edge_ids::), + Hook::Empty, + ); + unsafe { + libafl_qemu_sys::libafl_qemu_edge_hook_set_jit( + hook_id.0, + Some(libafl_qemu_sys::libafl_jit_trace_edge_hitcount), + ); + } + } + + fn jit_no_hitcount(&mut self, emulator_modules: &mut EmulatorModules) + where + AF: AddressFilter, + ET: EmulatorModuleTuple, + PF: PageFilter, + S: Unpin + UsesInput + HasMetadata, + { + let hook_id = emulator_modules.edges( + Hook::Function(gen_unique_edge_ids::), + Hook::Empty, + ); + unsafe { + libafl_qemu_sys::libafl_qemu_edge_hook_set_jit( + hook_id.0, + Some(libafl_qemu_sys::libafl_jit_trace_edge_single), + ); + } + } + + fn fn_hitcount(&mut self, emulator_modules: &mut EmulatorModules) + where + AF: AddressFilter, + ET: EmulatorModuleTuple, + PF: PageFilter, + S: Unpin + UsesInput + HasMetadata, + { + emulator_modules.edges( + Hook::Function(gen_unique_edge_ids::), + Hook::Raw(trace_edge_hitcount), + ); + } + + fn fn_no_hitcount(&mut self, emulator_modules: &mut EmulatorModules) + where + AF: AddressFilter, + ET: EmulatorModuleTuple, + PF: PageFilter, + S: Unpin + UsesInput + HasMetadata, + { + emulator_modules.edges( + Hook::Function(gen_unique_edge_ids::), + Hook::Raw(trace_edge_single), + ); + } } -#[cfg(emulation_mode = "usermode")] -impl EdgeCoverageModule { - #[must_use] - pub fn new(address_filter: QemuInstrumentationAddressRangeFilter) -> Self { +impl Default for StdEdgeCoverageFullModuleBuilder { + fn default() -> Self { Self { - address_filter, + variant: EdgeCoverageFullVariant, + address_filter: StdAddressFilter::default(), + page_filter: StdPageFilter::default(), use_hitcounts: true, + use_jit: true, } } - - #[must_use] - pub fn without_hitcounts(address_filter: QemuInstrumentationAddressRangeFilter) -> Self { - Self { - address_filter, - use_hitcounts: false, - } - } - - #[must_use] - pub fn must_instrument(&self, addr: GuestAddr) -> bool { - self.address_filter.allowed(addr) - } } -#[cfg(emulation_mode = "systemmode")] -impl EdgeCoverageModule { +impl StdEdgeCoverageFullModule { #[must_use] + pub fn builder() -> StdEdgeCoverageFullModuleBuilder { + EdgeCoverageModuleBuilder::default() + } +} + +#[derive(Debug)] +pub struct EdgeCoverageClassicVariant; + +pub type StdEdgeCoverageClassicModule = + EdgeCoverageModule; +pub type StdEdgeCoverageClassicModuleBuilder = + EdgeCoverageModuleBuilder; + +impl EdgeCoverageVariant for EdgeCoverageClassicVariant { + const DO_SIDE_EFFECTS: bool = false; + + fn jit_hitcount(&mut self, emulator_modules: &mut EmulatorModules) + where + AF: AddressFilter, + ET: EmulatorModuleTuple, + PF: PageFilter, + S: Unpin + UsesInput + HasMetadata, + { + let hook_id = emulator_modules.blocks( + Hook::Function(gen_hashed_block_ids::), + Hook::Empty, + Hook::Empty, + ); + + unsafe { + libafl_qemu_sys::libafl_qemu_block_hook_set_jit( + hook_id.0, + Some(libafl_qemu_sys::libafl_jit_trace_block_hitcount), + ); + } + } + + fn jit_no_hitcount(&mut self, emulator_modules: &mut EmulatorModules) + where + AF: AddressFilter, + ET: EmulatorModuleTuple, + PF: PageFilter, + S: Unpin + UsesInput + HasMetadata, + { + let hook_id = emulator_modules.blocks( + Hook::Function(gen_hashed_block_ids::), + Hook::Empty, + Hook::Empty, + ); + + unsafe { + libafl_qemu_sys::libafl_qemu_block_hook_set_jit( + hook_id.0, + Some(libafl_qemu_sys::libafl_jit_trace_block_single), + ); + } + } + + fn fn_hitcount(&mut self, emulator_modules: &mut EmulatorModules) + where + AF: AddressFilter, + ET: EmulatorModuleTuple, + PF: PageFilter, + S: Unpin + UsesInput + HasMetadata, + { + emulator_modules.blocks( + Hook::Function(gen_hashed_block_ids::), + Hook::Empty, + Hook::Raw(trace_block_transition_hitcount), + ); + } + + fn fn_no_hitcount(&mut self, emulator_modules: &mut EmulatorModules) + where + AF: AddressFilter, + ET: EmulatorModuleTuple, + PF: PageFilter, + S: Unpin + UsesInput + HasMetadata, + { + emulator_modules.blocks( + Hook::Function(gen_hashed_block_ids::), + Hook::Empty, + Hook::Raw(trace_block_transition_single), + ); + } +} + +impl Default for StdEdgeCoverageClassicModuleBuilder { + fn default() -> Self { + Self { + variant: EdgeCoverageClassicVariant, + address_filter: StdAddressFilter::default(), + page_filter: StdPageFilter::default(), + use_hitcounts: true, + use_jit: true, + } + } +} + +impl StdEdgeCoverageClassicModule { + #[must_use] + pub fn builder() -> StdEdgeCoverageClassicModuleBuilder { + EdgeCoverageModuleBuilder::default() + } +} + +#[derive(Debug)] +pub struct EdgeCoverageChildVariant; +pub type StdEdgeCoverageChildModule = + EdgeCoverageModule; +pub type StdEdgeCoverageChildModuleBuilder = + EdgeCoverageModuleBuilder; + +impl EdgeCoverageVariant for EdgeCoverageChildVariant { + const DO_SIDE_EFFECTS: bool = false; + + fn fn_hitcount(&mut self, emulator_modules: &mut EmulatorModules) + where + AF: AddressFilter, + ET: EmulatorModuleTuple, + PF: PageFilter, + S: Unpin + UsesInput + HasMetadata, + { + emulator_modules.edges( + Hook::Function(gen_hashed_edge_ids::), + Hook::Raw(trace_edge_hitcount_ptr), + ); + } + + fn fn_no_hitcount(&mut self, emulator_modules: &mut EmulatorModules) + where + AF: AddressFilter, + ET: EmulatorModuleTuple, + PF: PageFilter, + S: Unpin + UsesInput + HasMetadata, + { + emulator_modules.edges( + Hook::Function(gen_hashed_edge_ids::), + Hook::Raw(trace_edge_single_ptr), + ); + } +} + +impl Default for StdEdgeCoverageChildModuleBuilder { + fn default() -> Self { + Self { + variant: EdgeCoverageChildVariant, + address_filter: StdAddressFilter::default(), + page_filter: StdPageFilter::default(), + use_hitcounts: true, + use_jit: true, + } + } +} + +impl StdEdgeCoverageChildModule { + #[must_use] + pub fn builder() -> StdEdgeCoverageClassicModuleBuilder { + EdgeCoverageModuleBuilder::default() + } +} + +#[derive(Debug)] +pub struct EdgeCoverageModuleBuilder { + variant: V, + address_filter: AF, + page_filter: PF, + use_hitcounts: bool, + use_jit: bool, +} + +#[derive(Debug)] +pub struct EdgeCoverageModule { + variant: V, + address_filter: AF, + page_filter: PF, + use_hitcounts: bool, + use_jit: bool, +} + +impl EdgeCoverageModuleBuilder { pub fn new( - address_filter: QemuInstrumentationAddressRangeFilter, - paging_filter: QemuInstrumentationPagingFilter, + variant: V, + address_filter: AF, + page_filter: PF, + use_hitcounts: bool, + use_jit: bool, ) -> Self { Self { + variant, address_filter, - paging_filter, - use_hitcounts: true, + page_filter, + use_hitcounts, + use_jit, } } - #[must_use] - pub fn without_hitcounts( - address_filter: QemuInstrumentationAddressRangeFilter, - paging_filter: QemuInstrumentationPagingFilter, - ) -> Self { - Self { + pub fn build(self) -> EdgeCoverageModule { + EdgeCoverageModule::new( + self.address_filter, + self.page_filter, + self.variant, + self.use_hitcounts, + self.use_jit, + ) + } + + pub fn variant(self, variant: V2) -> EdgeCoverageModuleBuilder { + EdgeCoverageModuleBuilder::new( + variant, + self.address_filter, + self.page_filter, + self.use_hitcounts, + self.use_jit, + ) + } + + pub fn address_filter(self, address_filter: AF2) -> EdgeCoverageModuleBuilder { + EdgeCoverageModuleBuilder::new( + self.variant, address_filter, - paging_filter, - use_hitcounts: false, - } + self.page_filter, + self.use_hitcounts, + self.use_jit, + ) + } + + pub fn page_filter(self, page_filter: PF2) -> EdgeCoverageModuleBuilder { + EdgeCoverageModuleBuilder::new( + self.variant, + self.address_filter, + page_filter, + self.use_hitcounts, + self.use_jit, + ) } #[must_use] - pub fn must_instrument(&self, addr: GuestAddr, paging_id: Option) -> bool { - self.address_filter.allowed(addr) && self.paging_filter.allowed(paging_id) + pub fn hitcounts(self, use_hitcounts: bool) -> EdgeCoverageModuleBuilder { + EdgeCoverageModuleBuilder::new( + self.variant, + self.address_filter, + self.page_filter, + use_hitcounts, + self.use_jit, + ) } -} -#[cfg(emulation_mode = "usermode")] -impl Default for EdgeCoverageModule { - fn default() -> Self { - Self::new(QemuInstrumentationAddressRangeFilter::None) - } -} - -#[cfg(emulation_mode = "systemmode")] -impl Default for EdgeCoverageModule { - fn default() -> Self { - Self::new( - QemuInstrumentationAddressRangeFilter::None, - QemuInstrumentationPagingFilter::None, + #[must_use] + pub fn jit(self, use_jit: bool) -> EdgeCoverageModuleBuilder { + EdgeCoverageModuleBuilder::new( + self.variant, + self.address_filter, + self.page_filter, + self.use_hitcounts, + use_jit, ) } } -impl HasInstrumentationFilter for EdgeCoverageModule { - fn filter(&self) -> &QemuInstrumentationAddressRangeFilter { - &self.address_filter - } - - fn filter_mut(&mut self) -> &mut QemuInstrumentationAddressRangeFilter { - &mut self.address_filter +impl EdgeCoverageModule { + #[must_use] + pub fn new( + address_filter: AF, + page_filter: PF, + variant: V, + use_hitcounts: bool, + use_jit: bool, + ) -> Self { + Self { + variant, + address_filter, + page_filter, + use_hitcounts, + use_jit, + } } } -#[cfg(emulation_mode = "systemmode")] -impl HasInstrumentationFilter for EdgeCoverageModule { - fn filter(&self) -> &QemuInstrumentationPagingFilter { - &self.paging_filter - } - - fn filter_mut(&mut self) -> &mut QemuInstrumentationPagingFilter { - &mut self.paging_filter - } -} - -impl EmulatorModule for EdgeCoverageModule +impl EdgeCoverageModule where + AF: AddressFilter, + PF: PageFilter, +{ + #[cfg(emulation_mode = "usermode")] + #[must_use] + pub fn must_instrument(&self, addr: GuestAddr) -> bool { + self.address_filter.allowed(&addr) + } + + #[cfg(emulation_mode = "systemmode")] + #[must_use] + pub fn must_instrument(&self, addr: GuestAddr, page_id: Option) -> bool { + if let Some(page_id) = page_id { + self.address_filter.allowed(&addr) && self.page_filter.allowed(&page_id) + } else { + self.address_filter.allowed(&addr) + } + } +} + +impl EmulatorModule for EdgeCoverageModule +where + AF: AddressFilter + 'static, + PF: PageFilter + 'static, S: Unpin + UsesInput + HasMetadata, + V: EdgeCoverageVariant + 'static, { - fn first_exec(&mut self, _state: &mut S, emulator_modules: &mut EmulatorModules) - where - ET: EmulatorModuleTuple, - { - if self.use_hitcounts { - // emulator_modules.edges( - // Hook::Function(gen_unique_edge_ids::), - // Hook::Raw(trace_edge_hitcount), - // ); - let hook_id = - emulator_modules.edges(Hook::Function(gen_unique_edge_ids::), Hook::Empty); - unsafe { - libafl_qemu_sys::libafl_qemu_edge_hook_set_jit( - hook_id.0, - Some(libafl_qemu_sys::libafl_jit_trace_edge_hitcount), - ); - } - } else { - // emulator_modules.edges( - // Hook::Function(gen_unique_edge_ids::), - // Hook::Raw(trace_edge_single), - // ); - let hook_id = - emulator_modules.edges(Hook::Function(gen_unique_edge_ids::), Hook::Empty); - unsafe { - libafl_qemu_sys::libafl_qemu_edge_hook_set_jit( - hook_id.0, - Some(libafl_qemu_sys::libafl_jit_trace_edge_single), - ); - } - } - } -} + const HOOKS_DO_SIDE_EFFECTS: bool = V::DO_SIDE_EFFECTS; -pub type CollidingEdgeCoverageModule = EdgeCoverageChildModule; + type ModuleAddressFilter = AF; + #[cfg(emulation_mode = "systemmode")] + type ModulePageFilter = PF; -#[cfg(emulation_mode = "usermode")] -#[derive(Debug)] -pub struct EdgeCoverageChildModule { - address_filter: QemuInstrumentationAddressRangeFilter, - use_hitcounts: bool, -} - -#[cfg(emulation_mode = "systemmode")] -#[derive(Debug)] -pub struct EdgeCoverageChildModule { - address_filter: QemuInstrumentationAddressRangeFilter, - paging_filter: QemuInstrumentationPagingFilter, - use_hitcounts: bool, -} - -#[cfg(emulation_mode = "usermode")] -impl EdgeCoverageChildModule { - #[must_use] - pub fn new(address_filter: QemuInstrumentationAddressRangeFilter) -> Self { - Self { - address_filter, - use_hitcounts: true, - } - } - - #[must_use] - pub fn without_hitcounts(address_filter: QemuInstrumentationAddressRangeFilter) -> Self { - Self { - address_filter, - use_hitcounts: false, - } - } - - #[must_use] - pub fn must_instrument(&self, addr: GuestAddr) -> bool { - self.address_filter.allowed(addr) - } -} - -#[cfg(emulation_mode = "systemmode")] -impl EdgeCoverageChildModule { - #[must_use] - pub fn new( - address_filter: QemuInstrumentationAddressRangeFilter, - paging_filter: QemuInstrumentationPagingFilter, - ) -> Self { - Self { - address_filter, - paging_filter, - use_hitcounts: true, - } - } - - #[must_use] - pub fn without_hitcounts( - address_filter: QemuInstrumentationAddressRangeFilter, - paging_filter: QemuInstrumentationPagingFilter, - ) -> Self { - Self { - address_filter, - paging_filter, - use_hitcounts: false, - } - } - - #[must_use] - pub fn must_instrument(&self, addr: GuestAddr, paging_id: Option) -> bool { - self.address_filter.allowed(addr) && self.paging_filter.allowed(paging_id) - } -} - -#[cfg(emulation_mode = "usermode")] -impl Default for EdgeCoverageChildModule { - fn default() -> Self { - Self::new(QemuInstrumentationAddressRangeFilter::None) - } -} - -#[cfg(emulation_mode = "systemmode")] -impl Default for EdgeCoverageChildModule { - fn default() -> Self { - Self::new( - QemuInstrumentationAddressRangeFilter::None, - QemuInstrumentationPagingFilter::None, - ) - } -} - -impl HasInstrumentationFilter for EdgeCoverageChildModule { - fn filter(&self) -> &QemuInstrumentationAddressRangeFilter { - &self.address_filter - } - - fn filter_mut(&mut self) -> &mut QemuInstrumentationAddressRangeFilter { - &mut self.address_filter - } -} - -#[cfg(emulation_mode = "systemmode")] -impl HasInstrumentationFilter for EdgeCoverageChildModule { - fn filter(&self) -> &QemuInstrumentationPagingFilter { - &self.paging_filter - } - - fn filter_mut(&mut self) -> &mut QemuInstrumentationPagingFilter { - &mut self.paging_filter - } -} - -impl EmulatorModule for EdgeCoverageChildModule -where - S: Unpin + UsesInput, -{ - const HOOKS_DO_SIDE_EFFECTS: bool = false; - - fn first_exec(&mut self, _state: &mut S, emulator_modules: &mut EmulatorModules) - where - ET: EmulatorModuleTuple, - { - if self.use_hitcounts { - emulator_modules.edges( - Hook::Function(gen_hashed_edge_ids::), - Hook::Raw(trace_edge_hitcount_ptr), - ); - } else { - emulator_modules.edges( - Hook::Function(gen_hashed_edge_ids::), - Hook::Raw(trace_edge_single_ptr), - ); - } - } -} - -#[cfg(emulation_mode = "usermode")] -#[derive(Debug)] -pub struct EdgeCoverageClassicModule { - address_filter: QemuInstrumentationAddressRangeFilter, - use_hitcounts: bool, - use_jit: bool, -} - -#[cfg(emulation_mode = "systemmode")] -#[derive(Debug)] -pub struct EdgeCoverageClassicModule { - address_filter: QemuInstrumentationAddressRangeFilter, - paging_filter: QemuInstrumentationPagingFilter, - use_hitcounts: bool, - use_jit: bool, -} - -#[cfg(emulation_mode = "usermode")] -impl EdgeCoverageClassicModule { - #[must_use] - pub fn new(address_filter: QemuInstrumentationAddressRangeFilter, use_jit: bool) -> Self { - Self { - address_filter, - use_hitcounts: true, - use_jit, - } - } - - #[must_use] - pub fn without_hitcounts( - address_filter: QemuInstrumentationAddressRangeFilter, - use_jit: bool, - ) -> Self { - Self { - address_filter, - use_hitcounts: false, - use_jit, - } - } - - #[must_use] - pub fn must_instrument(&self, addr: GuestAddr) -> bool { - self.address_filter.allowed(addr) - } -} - -#[cfg(emulation_mode = "systemmode")] -impl EdgeCoverageClassicModule { - #[must_use] - pub fn new( - address_filter: QemuInstrumentationAddressRangeFilter, - paging_filter: QemuInstrumentationPagingFilter, - use_jit: bool, - ) -> Self { - Self { - address_filter, - paging_filter, - use_hitcounts: true, - use_jit, - } - } - - #[must_use] - pub fn without_hitcounts( - address_filter: QemuInstrumentationAddressRangeFilter, - paging_filter: QemuInstrumentationPagingFilter, - use_jit: bool, - ) -> Self { - Self { - address_filter, - paging_filter, - use_hitcounts: false, - use_jit, - } - } - - #[must_use] - pub fn must_instrument(&self, addr: GuestAddr, paging_id: Option) -> bool { - self.address_filter.allowed(addr) && self.paging_filter.allowed(paging_id) - } -} - -#[cfg(emulation_mode = "usermode")] -impl Default for EdgeCoverageClassicModule { - fn default() -> Self { - Self::new(QemuInstrumentationAddressRangeFilter::None, false) - } -} - -#[cfg(emulation_mode = "systemmode")] -impl Default for EdgeCoverageClassicModule { - fn default() -> Self { - Self::new( - QemuInstrumentationAddressRangeFilter::None, - QemuInstrumentationPagingFilter::None, - false, - ) - } -} - -impl HasInstrumentationFilter for EdgeCoverageClassicModule { - fn filter(&self) -> &QemuInstrumentationAddressRangeFilter { - &self.address_filter - } - - fn filter_mut(&mut self) -> &mut QemuInstrumentationAddressRangeFilter { - &mut self.address_filter - } -} - -#[cfg(emulation_mode = "systemmode")] -impl HasInstrumentationFilter for EdgeCoverageClassicModule { - fn filter(&self) -> &QemuInstrumentationPagingFilter { - &self.paging_filter - } - - fn filter_mut(&mut self) -> &mut QemuInstrumentationPagingFilter { - &mut self.paging_filter - } -} - -#[allow(clippy::collapsible_else_if)] -impl EmulatorModule for EdgeCoverageClassicModule -where - S: Unpin + UsesInput, -{ - const HOOKS_DO_SIDE_EFFECTS: bool = false; - - fn first_exec(&mut self, _state: &mut S, emulator_modules: &mut EmulatorModules) + fn first_exec(&mut self, emulator_modules: &mut EmulatorModules, _state: &mut S) where ET: EmulatorModuleTuple, { if self.use_hitcounts { if self.use_jit { - let hook_id = emulator_modules.blocks( - Hook::Function(gen_hashed_block_ids::), - Hook::Empty, - Hook::Empty, - ); - - unsafe { - libafl_qemu_sys::libafl_qemu_block_hook_set_jit( - hook_id.0, - Some(libafl_qemu_sys::libafl_jit_trace_block_hitcount), - ); - } + self.variant.jit_hitcount(emulator_modules); } else { - emulator_modules.blocks( - Hook::Function(gen_hashed_block_ids::), - Hook::Empty, - Hook::Raw(trace_block_transition_hitcount), - ); + self.variant.fn_hitcount(emulator_modules); } + } else if self.use_jit { + self.variant.jit_no_hitcount(emulator_modules); } else { - if self.use_jit { - let hook_id = emulator_modules.blocks( - Hook::Function(gen_hashed_block_ids::), - Hook::Empty, - Hook::Empty, - ); - - unsafe { - libafl_qemu_sys::libafl_qemu_block_hook_set_jit( - hook_id.0, - Some(libafl_qemu_sys::libafl_jit_trace_block_single), - ); - } - } else { - emulator_modules.blocks( - Hook::Function(gen_hashed_block_ids::), - Hook::Empty, - Hook::Raw(trace_block_transition_single), - ); - } + self.variant.fn_no_hitcount(emulator_modules); } } + + fn address_filter(&self) -> &Self::ModuleAddressFilter { + &self.address_filter + } + + fn address_filter_mut(&mut self) -> &mut Self::ModuleAddressFilter { + &mut self.address_filter + } + + #[cfg(emulation_mode = "systemmode")] + fn page_filter(&self) -> &Self::ModulePageFilter { + &self.page_filter + } + + #[cfg(emulation_mode = "systemmode")] + fn page_filter_mut(&mut self) -> &mut Self::ModulePageFilter { + &mut self.page_filter + } } thread_local!(static PREV_LOC : UnsafeCell = const { UnsafeCell::new(0) }); - -pub fn gen_unique_edge_ids( +pub fn gen_unique_edge_ids( emulator_modules: &mut EmulatorModules, state: Option<&mut S>, src: GuestAddr, dest: GuestAddr, ) -> Option where + AF: AddressFilter, ET: EmulatorModuleTuple, + PF: PageFilter, S: Unpin + UsesInput + HasMetadata, + V: EdgeCoverageVariant, { - if let Some(h) = emulator_modules.get::() { + if let Some(h) = emulator_modules.get::>() { #[cfg(emulation_mode = "usermode")] { if !h.must_instrument(src) && !h.must_instrument(dest) { @@ -574,17 +604,21 @@ pub extern "C" fn trace_edge_single(_: *const (), id: u64) { } } -pub fn gen_hashed_edge_ids( +#[allow(clippy::unnecessary_cast)] +pub fn gen_hashed_edge_ids( emulator_modules: &mut EmulatorModules, _state: Option<&mut S>, src: GuestAddr, dest: GuestAddr, ) -> Option where + AF: AddressFilter, ET: EmulatorModuleTuple, - S: Unpin + UsesInput, + PF: PageFilter, + S: Unpin + UsesInput + HasMetadata, + V: EdgeCoverageVariant, { - if let Some(h) = emulator_modules.get::() { + if let Some(h) = emulator_modules.get::>() { #[cfg(emulation_mode = "usermode")] if !h.must_instrument(src) && !h.must_instrument(dest) { return None; @@ -602,9 +636,17 @@ where } } } + + let id = hash_me(src as u64) ^ hash_me(dest as u64); + let nxt = (id as usize + 1) & (EDGES_MAP_SIZE_MAX - 1); + + unsafe { + MAX_EDGES_FOUND = nxt; + } + // GuestAddress is u32 for 32 bit guests #[allow(clippy::unnecessary_cast)] - Some((hash_me(src as u64) ^ hash_me(dest as u64)) & (EDGES_MAP_SIZE_MAX as u64 - 1)) + Some(id) } pub extern "C" fn trace_edge_hitcount_ptr(_: *const (), id: u64) { @@ -621,16 +663,20 @@ pub extern "C" fn trace_edge_single_ptr(_: *const (), id: u64) { } } -pub fn gen_hashed_block_ids( +#[allow(clippy::unnecessary_cast)] +pub fn gen_hashed_block_ids( emulator_modules: &mut EmulatorModules, _state: Option<&mut S>, pc: GuestAddr, ) -> Option where - S: Unpin + UsesInput, + AF: AddressFilter, ET: EmulatorModuleTuple, + PF: PageFilter, + S: Unpin + UsesInput + HasMetadata, + V: EdgeCoverageVariant, { - if let Some(h) = emulator_modules.get::() { + if let Some(h) = emulator_modules.get::>() { #[cfg(emulation_mode = "usermode")] { if !h.must_instrument(pc) { @@ -639,19 +685,27 @@ where } #[cfg(emulation_mode = "systemmode")] { - let paging_id = emulator_modules + let page_id = emulator_modules .qemu() .current_cpu() .and_then(|cpu| cpu.current_paging_id()); - if !h.must_instrument(pc, paging_id) { + if !h.must_instrument(pc, page_id) { return None; } } } + + let id = hash_me(pc as u64); + let nxt = (id as usize + 1) & (EDGES_MAP_SIZE_MAX - 1); + + unsafe { + MAX_EDGES_FOUND = nxt; + } + // GuestAddress is u32 for 32 bit guests #[allow(clippy::unnecessary_cast)] - Some(hash_me(pc as u64)) + Some(id) } pub extern "C" fn trace_block_transition_hitcount(_: *const (), id: u64) { diff --git a/libafl_qemu/src/modules/mod.rs b/libafl_qemu/src/modules/mod.rs index 700a02beb8..572de025df 100644 --- a/libafl_qemu/src/modules/mod.rs +++ b/libafl_qemu/src/modules/mod.rs @@ -1,12 +1,11 @@ -use core::{cell::UnsafeCell, fmt::Debug, hash::BuildHasher, ops::Range, ptr::addr_of_mut}; +use core::{fmt::Debug, ops::Range}; +use std::cell::UnsafeCell; use hashbrown::HashSet; use libafl::{executors::ExitKind, inputs::UsesInput, observers::ObserversTuple}; use libafl_bolts::tuples::{MatchFirstType, SplitBorrowExtractFirstType}; use libafl_qemu_sys::{GuestAddr, GuestPhysAddr}; -use crate::Qemu; - #[cfg(emulation_mode = "usermode")] pub mod usermode; #[cfg(emulation_mode = "usermode")] @@ -15,6 +14,7 @@ pub use usermode::*; #[cfg(emulation_mode = "systemmode")] pub mod systemmode; #[cfg(emulation_mode = "systemmode")] +#[allow(unused_imports)] pub use systemmode::*; pub mod edges; @@ -30,7 +30,7 @@ pub mod cmplog; #[cfg(not(any(cpu_target = "mips", cpu_target = "hexagon")))] pub use cmplog::CmpLogModule; -use crate::emu::EmulatorModules; +use crate::{emu::EmulatorModules, Qemu}; /// A module for `libafl_qemu`. // TODO remove 'static when specialization will be stable @@ -38,35 +38,49 @@ pub trait EmulatorModule: 'static + Debug where S: UsesInput, { + type ModuleAddressFilter: AddressFilter; + + #[cfg(emulation_mode = "systemmode")] + type ModulePageFilter: PageFilter; + const HOOKS_DO_SIDE_EFFECTS: bool = true; /// Initialize the module, mostly used to install some hooks early. + /// This is always run when Emulator gets initialized, in any case. + /// Install here hooks that should be alive for the whole execution of the VM. fn init_module(&self, _emulator_modules: &mut EmulatorModules) where ET: EmulatorModuleTuple, { } - fn first_exec(&mut self, _state: &mut S, _emulator_modules: &mut EmulatorModules) + /// Run once just before fuzzing starts. + /// This call can be delayed to the point at which fuzzing is supposed to start. + /// It is mostly used to avoid running hooks during VM initialization, either + /// because it is useless or it would produce wrong results. + fn first_exec(&mut self, _emulator_modules: &mut EmulatorModules, _state: &mut S) where ET: EmulatorModuleTuple, { } + /// Run before a new fuzzing run starts. + /// On the first run, it is executed after [`Self::first_exec`]. fn pre_exec( &mut self, - _state: &mut S, _emulator_modules: &mut EmulatorModules, + _state: &mut S, _input: &S::Input, ) where ET: EmulatorModuleTuple, { } + /// Run after a fuzzing run ends. fn post_exec( &mut self, - _state: &mut S, _emulator_modules: &mut EmulatorModules, + _state: &mut S, _input: &S::Input, _observers: &mut OT, _exit_kind: &mut ExitKind, @@ -75,6 +89,14 @@ where ET: EmulatorModuleTuple, { } + + fn address_filter(&self) -> &Self::ModuleAddressFilter; + fn address_filter_mut(&mut self) -> &mut Self::ModuleAddressFilter; + + #[cfg(emulation_mode = "systemmode")] + fn page_filter(&self) -> &Self::ModulePageFilter; + #[cfg(emulation_mode = "systemmode")] + fn page_filter_mut(&mut self) -> &mut Self::ModulePageFilter; } pub trait EmulatorModuleTuple: @@ -88,31 +110,33 @@ where where ET: EmulatorModuleTuple; - fn first_exec_all( - &mut self, - _emulator_modules: &mut EmulatorModules, - _state: &mut S, - ) where + fn first_exec_all(&mut self, emulator_modules: &mut EmulatorModules, state: &mut S) + where ET: EmulatorModuleTuple; fn pre_exec_all( &mut self, - _emulator_modules: &mut EmulatorModules, - _input: &S::Input, - _state: &mut S, + emulator_modules: &mut EmulatorModules, + state: &mut S, + input: &S::Input, ) where ET: EmulatorModuleTuple; fn post_exec_all( &mut self, - _emulator_modules: &mut EmulatorModules, - _input: &S::Input, - _observers: &mut OT, - _state: &mut S, - _exit_kind: &mut ExitKind, + emulator_modules: &mut EmulatorModules, + state: &mut S, + input: &S::Input, + observers: &mut OT, + exit_kind: &mut ExitKind, ) where OT: ObserversTuple, ET: EmulatorModuleTuple; + + fn allow_address_range_all(&mut self, address_range: Range); + + #[cfg(emulation_mode = "systemmode")] + fn allow_page_id_all(&mut self, page_id: GuestPhysAddr); } impl EmulatorModuleTuple for () @@ -136,8 +160,8 @@ where fn pre_exec_all( &mut self, _emulator_modules: &mut EmulatorModules, - _input: &S::Input, _state: &mut S, + _input: &S::Input, ) where ET: EmulatorModuleTuple, { @@ -146,15 +170,20 @@ where fn post_exec_all( &mut self, _emulator_modules: &mut EmulatorModules, + _state: &mut S, _input: &S::Input, _observers: &mut OT, - _state: &mut S, _exit_kind: &mut ExitKind, ) where OT: ObserversTuple, ET: EmulatorModuleTuple, { } + + fn allow_address_range_all(&mut self, _address_range: Range) {} + + #[cfg(emulation_mode = "systemmode")] + fn allow_page_id_all(&mut self, _page_id: GuestPhysAddr) {} } impl EmulatorModuleTuple for (Head, Tail) @@ -177,175 +206,268 @@ where where ET: EmulatorModuleTuple, { - self.0.first_exec(state, emulator_modules); + self.0.first_exec(emulator_modules, state); self.1.first_exec_all(emulator_modules, state); } fn pre_exec_all( &mut self, emulator_modules: &mut EmulatorModules, - input: &S::Input, state: &mut S, + input: &S::Input, ) where ET: EmulatorModuleTuple, { - self.0.pre_exec(state, emulator_modules, input); - self.1.pre_exec_all(emulator_modules, input, state); + self.0.pre_exec(emulator_modules, state, input); + self.1.pre_exec_all(emulator_modules, state, input); } fn post_exec_all( &mut self, emulator_modules: &mut EmulatorModules, + state: &mut S, input: &S::Input, observers: &mut OT, - state: &mut S, exit_kind: &mut ExitKind, ) where OT: ObserversTuple, ET: EmulatorModuleTuple, { self.0 - .post_exec(state, emulator_modules, input, observers, exit_kind); + .post_exec(emulator_modules, state, input, observers, exit_kind); self.1 - .post_exec_all(emulator_modules, input, observers, state, exit_kind); - } -} - -impl HasInstrumentationFilter<()> for () { - fn filter(&self) -> &() { - self + .post_exec_all(emulator_modules, state, input, observers, exit_kind); } - fn filter_mut(&mut self) -> &mut () { - self - } -} - -impl HasInstrumentationFilter for (Head, ()) -where - Head: HasInstrumentationFilter, - F: IsFilter, -{ - fn filter(&self) -> &F { - self.0.filter() + fn allow_address_range_all(&mut self, address_range: Range) { + self.0.address_filter_mut().register(address_range.clone()); + self.1.allow_address_range_all(address_range); } - fn filter_mut(&mut self) -> &mut F { - self.0.filter_mut() + #[cfg(emulation_mode = "systemmode")] + fn allow_page_id_all(&mut self, page_id: GuestPhysAddr) { + self.0.page_filter_mut().register(page_id.clone()); + self.1.allow_page_id_all(page_id) } } #[derive(Debug, Clone)] -pub enum QemuFilterList { +pub enum FilterList { AllowList(T), DenyList(T), None, } -impl IsFilter for QemuFilterList +impl AddressFilter for FilterList where - T: IsFilter + Clone, + T: AddressFilter, { - type FilterParameter = T::FilterParameter; - - fn allowed(&self, filter_parameter: Self::FilterParameter) -> bool { + fn register(&mut self, address_range: Range) { match self { - QemuFilterList::AllowList(allow_list) => allow_list.allowed(filter_parameter), - QemuFilterList::DenyList(deny_list) => !deny_list.allowed(filter_parameter), - QemuFilterList::None => true, + FilterList::AllowList(allow_list) => allow_list.register(address_range), + FilterList::DenyList(deny_list) => deny_list.register(address_range), + FilterList::None => {} + } + } + + fn allowed(&self, address: &GuestAddr) -> bool { + match self { + FilterList::AllowList(allow_list) => allow_list.allowed(address), + FilterList::DenyList(deny_list) => !deny_list.allowed(address), + FilterList::None => true, } } } -pub type QemuInstrumentationPagingFilter = QemuFilterList>; - -impl IsFilter for HashSet +impl PageFilter for FilterList where - H: BuildHasher, + T: PageFilter, { - type FilterParameter = Option; + fn register(&mut self, page_id: GuestPhysAddr) { + match self { + FilterList::AllowList(allow_list) => allow_list.register(page_id), + FilterList::DenyList(deny_list) => deny_list.register(page_id), + FilterList::None => {} + } + } - fn allowed(&self, paging_id: Self::FilterParameter) -> bool { - paging_id.is_some_and(|pid| self.contains(&pid)) + fn allowed(&self, page: &GuestPhysAddr) -> bool { + match self { + FilterList::AllowList(allow_list) => allow_list.allowed(page), + FilterList::DenyList(deny_list) => !deny_list.allowed(page), + FilterList::None => true, + } } } -pub type QemuInstrumentationAddressRangeFilter = QemuFilterList>>; +#[derive(Clone, Debug, Default)] +pub struct AddressFilterVec { + // ideally, we should use a tree + registered_addresses: Vec>, +} +#[derive(Clone, Debug)] +pub struct StdAddressFilter(FilterList); -impl IsFilter for Vec> { - type FilterParameter = GuestAddr; +impl Default for StdAddressFilter { + fn default() -> Self { + Self(FilterList::None) + } +} - fn allowed(&self, addr: Self::FilterParameter) -> bool { - for rng in self { - if rng.contains(&addr) { +impl StdAddressFilter { + #[must_use] + pub fn allow_list(registered_addresses: Vec>) -> Self { + StdAddressFilter(FilterList::AllowList(AddressFilterVec::new( + registered_addresses, + ))) + } + + #[must_use] + pub fn deny_list(registered_addresses: Vec>) -> Self { + StdAddressFilter(FilterList::DenyList(AddressFilterVec::new( + registered_addresses, + ))) + } +} + +impl AddressFilterVec { + #[must_use] + pub fn new(registered_addresses: Vec>) -> Self { + Self { + registered_addresses, + } + } +} + +impl AddressFilter for AddressFilterVec { + fn register(&mut self, address_range: Range) { + self.registered_addresses.push(address_range); + Qemu::get().unwrap().flush_jit(); + } + + fn allowed(&self, addr: &GuestAddr) -> bool { + if self.registered_addresses.is_empty() { + return true; + } + + for addr_range in &self.registered_addresses { + if addr_range.contains(addr) { return true; } } + false } } -pub trait HasInstrumentationFilter -where - F: IsFilter, -{ - fn filter(&self) -> &F; +impl AddressFilter for StdAddressFilter { + fn register(&mut self, address_range: Range) { + self.0.register(address_range); + } - fn filter_mut(&mut self) -> &mut F; - - fn update_filter(&mut self, filter: F, emu: &Qemu) { - *self.filter_mut() = filter; - emu.flush_jit(); + fn allowed(&self, address: &GuestAddr) -> bool { + self.0.allowed(address) } } -static mut EMPTY_ADDRESS_FILTER: UnsafeCell = - UnsafeCell::new(QemuFilterList::None); -static mut EMPTY_PAGING_FILTER: UnsafeCell = - UnsafeCell::new(QemuFilterList::None); +#[derive(Clone, Debug)] +pub struct PageFilterVec { + registered_pages: HashSet, +} -impl HasInstrumentationFilter for () { - fn filter(&self) -> &QemuInstrumentationAddressRangeFilter { - &QemuFilterList::None - } +#[cfg(emulation_mode = "systemmode")] +#[derive(Clone, Debug)] +pub struct StdPageFilter(FilterList); - fn filter_mut(&mut self) -> &mut QemuInstrumentationAddressRangeFilter { - unsafe { (*addr_of_mut!(EMPTY_ADDRESS_FILTER)).get_mut() } +#[cfg(emulation_mode = "usermode")] +pub type StdPageFilter = NopPageFilter; + +impl Default for PageFilterVec { + fn default() -> Self { + Self { + registered_pages: HashSet::new(), + } } } -impl HasInstrumentationFilter for () { - fn filter(&self) -> &QemuInstrumentationPagingFilter { - &QemuFilterList::None - } - - fn filter_mut(&mut self) -> &mut QemuInstrumentationPagingFilter { - unsafe { (*addr_of_mut!(EMPTY_PAGING_FILTER)).get_mut() } +#[cfg(emulation_mode = "systemmode")] +impl Default for StdPageFilter { + fn default() -> Self { + Self(FilterList::None) } } -pub trait IsFilter: Debug { - type FilterParameter; +impl PageFilter for PageFilterVec { + fn register(&mut self, page_id: GuestPhysAddr) { + self.registered_pages.insert(page_id); + Qemu::get().unwrap().flush_jit(); + } - fn allowed(&self, filter_parameter: Self::FilterParameter) -> bool; + fn allowed(&self, paging_id: &GuestPhysAddr) -> bool { + // if self.allowed_pages.is_empty() { + // return true; + // } + + self.registered_pages.contains(paging_id) + } } -impl IsFilter for () { - type FilterParameter = (); +#[cfg(emulation_mode = "systemmode")] +impl PageFilter for StdPageFilter { + fn register(&mut self, page_id: GuestPhysAddr) { + self.0.register(page_id); + } - fn allowed(&self, _filter_parameter: Self::FilterParameter) -> bool { + fn allowed(&self, page_id: &GuestPhysAddr) -> bool { + self.0.allowed(page_id) + } +} + +// adapted from https://xorshift.di.unimi.it/splitmix64.c +#[must_use] +pub fn hash_me(mut x: u64) -> u64 { + x = (x ^ (x.overflowing_shr(30).0)) + .overflowing_mul(0xbf58476d1ce4e5b9) + .0; + x = (x ^ (x.overflowing_shr(27).0)) + .overflowing_mul(0x94d049bb133111eb) + .0; + x ^ (x.overflowing_shr(31).0) +} + +pub trait AddressFilter: 'static + Debug { + fn register(&mut self, address_range: Range); + + fn allowed(&self, address: &GuestAddr) -> bool; +} + +#[derive(Debug)] +pub struct NopAddressFilter; +impl AddressFilter for NopAddressFilter { + fn register(&mut self, _address: Range) {} + + fn allowed(&self, _address: &GuestAddr) -> bool { true } } -pub trait IsAddressFilter: IsFilter {} +pub trait PageFilter: 'static + Debug { + fn register(&mut self, page_id: GuestPhysAddr); -impl IsAddressFilter for QemuInstrumentationAddressRangeFilter {} - -#[must_use] -pub fn hash_me(mut x: u64) -> u64 { - x = (x.overflowing_shr(16).0 ^ x).overflowing_mul(0x45d9f3b).0; - x = (x.overflowing_shr(16).0 ^ x).overflowing_mul(0x45d9f3b).0; - x = (x.overflowing_shr(16).0 ^ x) ^ x; - x + fn allowed(&self, page_id: &GuestPhysAddr) -> bool; } + +#[derive(Clone, Debug, Default)] +pub struct NopPageFilter; +impl PageFilter for NopPageFilter { + fn register(&mut self, _page_id: GuestPhysAddr) {} + + fn allowed(&self, _page_id: &GuestPhysAddr) -> bool { + true + } +} + +#[cfg(emulation_mode = "usermode")] +static mut NOP_ADDRESS_FILTER: UnsafeCell = UnsafeCell::new(NopAddressFilter); +#[cfg(emulation_mode = "systemmode")] +static mut NOP_PAGE_FILTER: UnsafeCell = UnsafeCell::new(NopPageFilter); diff --git a/libafl_qemu/src/modules/systemmode/mod.rs b/libafl_qemu/src/modules/systemmode/mod.rs index 4af5773832..8b13789179 100644 --- a/libafl_qemu/src/modules/systemmode/mod.rs +++ b/libafl_qemu/src/modules/systemmode/mod.rs @@ -1,28 +1 @@ -use std::fmt::Debug; -use libafl_qemu_sys::GuestPhysAddr; - -use crate::modules::{ - HasInstrumentationFilter, IsFilter, QemuInstrumentationAddressRangeFilter, - QemuInstrumentationPagingFilter, -}; - -pub trait StdInstrumentationFilter: - Debug - + HasInstrumentationFilter - + HasInstrumentationFilter -{ -} - -impl crate::modules::StdInstrumentationFilter for (Head, ()) where - Head: HasInstrumentationFilter - + HasInstrumentationFilter - + Debug -{ -} - -impl StdInstrumentationFilter for () {} - -pub trait IsPagingFilter: IsFilter> {} - -impl IsPagingFilter for QemuInstrumentationPagingFilter {} diff --git a/libafl_qemu/src/modules/usermode/asan.rs b/libafl_qemu/src/modules/usermode/asan.rs index 15f356f380..be3d28ed31 100644 --- a/libafl_qemu/src/modules/usermode/asan.rs +++ b/libafl_qemu/src/modules/usermode/asan.rs @@ -14,8 +14,7 @@ use rangemap::RangeMap; use crate::{ modules::{ calls::FullBacktraceCollector, snapshot::SnapshotModule, EmulatorModule, - EmulatorModuleTuple, HasInstrumentationFilter, IsFilter, - QemuInstrumentationAddressRangeFilter, + EmulatorModuleTuple, }, qemu::{MemAccessInfo, QemuInitError}, sys::TCGTemp, @@ -154,6 +153,7 @@ use object::{Object, ObjectSection}; use crate::{ emu::EmulatorModules, + modules::{AddressFilter, StdAddressFilter}, qemu::{Hook, QemuHooks, SyscallHookResult}, }; @@ -739,23 +739,19 @@ pub struct AsanModule { detect_leaks: bool, empty: bool, rt: Pin>, - filter: QemuInstrumentationAddressRangeFilter, + filter: StdAddressFilter, } impl AsanModule { #[must_use] pub fn default(rt: Pin>) -> Self { - Self::new( - rt, - QemuInstrumentationAddressRangeFilter::None, - QemuAsanOptions::Snapshot, - ) + Self::new(rt, StdAddressFilter::default(), QemuAsanOptions::Snapshot) } #[must_use] pub fn new( mut rt: Pin>, - filter: QemuInstrumentationAddressRangeFilter, + filter: StdAddressFilter, options: QemuAsanOptions, ) -> Self { assert!(unsafe { ASAN_INITED }, "The ASan runtime is not initialized, use init_qemu_with_asan(...) instead of just Qemu::init(...)"); @@ -778,7 +774,7 @@ impl AsanModule { #[must_use] pub fn with_error_callback( mut rt: Pin>, - filter: QemuInstrumentationAddressRangeFilter, + filter: StdAddressFilter, error_callback: AsanErrorCallback, options: QemuAsanOptions, ) -> Self { @@ -803,7 +799,7 @@ impl AsanModule { #[must_use] pub fn with_asan_report( rt: Pin>, - filter: QemuInstrumentationAddressRangeFilter, + filter: StdAddressFilter, options: QemuAsanOptions, ) -> Self { Self::with_error_callback(rt, filter, Box::new(asan_report), options) @@ -811,7 +807,7 @@ impl AsanModule { #[must_use] pub fn must_instrument(&self, addr: GuestAddr) -> bool { - self.filter.allowed(addr) + self.filter.allowed(&addr) } #[must_use] @@ -913,20 +909,11 @@ impl AsanModule { } } -impl HasInstrumentationFilter for AsanModule { - fn filter(&self) -> &QemuInstrumentationAddressRangeFilter { - &self.filter - } - - fn filter_mut(&mut self) -> &mut QemuInstrumentationAddressRangeFilter { - &mut self.filter - } -} - impl EmulatorModule for AsanModule where S: Unpin + UsesInput, { + type ModuleAddressFilter = StdAddressFilter; const HOOKS_DO_SIDE_EFFECTS: bool = false; fn init_module(&self, emulator_modules: &mut EmulatorModules) @@ -940,7 +927,7 @@ where } } - fn first_exec(&mut self, _state: &mut S, emulator_modules: &mut EmulatorModules) + fn first_exec(&mut self, emulator_modules: &mut EmulatorModules, _state: &mut S) where ET: EmulatorModuleTuple, { @@ -977,8 +964,8 @@ where fn pre_exec( &mut self, - _state: &mut S, emulator_modules: &mut EmulatorModules, + _state: &mut S, _input: &S::Input, ) where ET: EmulatorModuleTuple, @@ -991,8 +978,8 @@ where fn post_exec( &mut self, - _state: &mut S, emulator_modules: &mut EmulatorModules, + _state: &mut S, _input: &S::Input, _observers: &mut OT, exit_kind: &mut ExitKind, @@ -1004,6 +991,14 @@ where *exit_kind = ExitKind::Crash; } } + + fn address_filter(&self) -> &Self::ModuleAddressFilter { + &self.filter + } + + fn address_filter_mut(&mut self) -> &mut Self::ModuleAddressFilter { + &mut self.filter + } } pub fn oncrash_asan(emulator_modules: &mut EmulatorModules, target_sig: i32) diff --git a/libafl_qemu/src/modules/usermode/asan_guest.rs b/libafl_qemu/src/modules/usermode/asan_guest.rs index bfb05a4ef0..5665e93e2c 100644 --- a/libafl_qemu/src/modules/usermode/asan_guest.rs +++ b/libafl_qemu/src/modules/usermode/asan_guest.rs @@ -14,10 +14,7 @@ use libafl_qemu_sys::{GuestAddr, MapInfo}; use crate::sys::libafl_tcg_gen_asan; use crate::{ emu::EmulatorModules, - modules::{ - EmulatorModule, EmulatorModuleTuple, HasInstrumentationFilter, IsFilter, - QemuInstrumentationAddressRangeFilter, - }, + modules::{AddressFilter, EmulatorModule, EmulatorModuleTuple, StdAddressFilter}, qemu::{Hook, MemAccessInfo, Qemu, QemuInitError}, sys::TCGTemp, }; @@ -121,13 +118,13 @@ impl From<&MapInfo> for QemuAsanGuestMapping { } #[derive(Debug)] -pub struct AsanGuestModule { - filter: QemuInstrumentationAddressRangeFilter, +pub struct AsanGuestModule { + filter: F, mappings: Vec, } #[cfg(any(cpu_target = "aarch64", cpu_target = "x86_64", feature = "clippy"))] -impl AsanGuestModule { +impl AsanGuestModule { const HIGH_SHADOW_START: GuestAddr = 0x02008fff7000; const HIGH_SHADOW_END: GuestAddr = 0x10007fff7fff; const LOW_SHADOW_START: GuestAddr = 0x00007fff8000; @@ -140,21 +137,26 @@ impl AsanGuestModule { cpu_target = "mips", cpu_target = "ppc" ))] -impl AsanGuestModule { +impl AsanGuestModule { const HIGH_SHADOW_START: GuestAddr = 0x28000000; const HIGH_SHADOW_END: GuestAddr = 0x3fffffff; const LOW_SHADOW_START: GuestAddr = 0x20000000; const LOW_SHADOW_END: GuestAddr = 0x23ffffff; } -impl AsanGuestModule { +impl AsanGuestModule { #[must_use] pub fn default(emu: &Qemu, asan: String) -> Self { - Self::new(emu, asan, QemuInstrumentationAddressRangeFilter::None) + Self::new(emu, asan, StdAddressFilter::default()) } +} +impl AsanGuestModule +where + F: AddressFilter, +{ #[must_use] - pub fn new(emu: &Qemu, asan: String, filter: QemuInstrumentationAddressRangeFilter) -> Self { + pub fn new(emu: &Qemu, asan: String, filter: F) -> Self { for mapping in emu.mappings() { println!("mapping: {mapping:#?}"); } @@ -193,21 +195,11 @@ impl AsanGuestModule { #[must_use] pub fn must_instrument(&self, addr: GuestAddr) -> bool { - self.filter.allowed(addr) + self.filter.allowed(&addr) } } -impl HasInstrumentationFilter for AsanGuestModule { - fn filter(&self) -> &QemuInstrumentationAddressRangeFilter { - &self.filter - } - - fn filter_mut(&mut self) -> &mut QemuInstrumentationAddressRangeFilter { - &mut self.filter - } -} - -fn gen_readwrite_guest_asan( +fn gen_readwrite_guest_asan( emulator_modules: &mut EmulatorModules, _state: Option<&mut S>, pc: GuestAddr, @@ -215,10 +207,11 @@ fn gen_readwrite_guest_asan( info: MemAccessInfo, ) -> Option where + F: AddressFilter, S: Unpin + UsesInput, ET: EmulatorModuleTuple, { - let h = emulator_modules.get_mut::().unwrap(); + let h = emulator_modules.get_mut::>().unwrap(); if !h.must_instrument(pc) { return None; } @@ -269,17 +262,20 @@ fn guest_trace_error_n_asan( panic!("I really shouldn't be here either"); } -impl EmulatorModule for AsanGuestModule +impl EmulatorModule for AsanGuestModule where + F: AddressFilter, S: Unpin + UsesInput, { - fn first_exec(&mut self, _state: &mut S, emulator_modules: &mut EmulatorModules) + type ModuleAddressFilter = F; + + fn first_exec(&mut self, emulator_modules: &mut EmulatorModules, _state: &mut S) where ET: EmulatorModuleTuple, S: Unpin + UsesInput, { emulator_modules.reads( - Hook::Function(gen_readwrite_guest_asan::), + Hook::Function(gen_readwrite_guest_asan::), Hook::Function(guest_trace_error_asan::), Hook::Function(guest_trace_error_asan::), Hook::Function(guest_trace_error_asan::), @@ -288,7 +284,7 @@ where ); emulator_modules.writes( - Hook::Function(gen_readwrite_guest_asan::), + Hook::Function(gen_readwrite_guest_asan::), Hook::Function(guest_trace_error_asan::), Hook::Function(guest_trace_error_asan::), Hook::Function(guest_trace_error_asan::), @@ -296,4 +292,12 @@ where Hook::Function(guest_trace_error_n_asan::), ); } + + fn address_filter(&self) -> &Self::ModuleAddressFilter { + &self.filter + } + + fn address_filter_mut(&mut self) -> &mut Self::ModuleAddressFilter { + &mut self.filter + } } diff --git a/libafl_qemu/src/modules/usermode/drcov.rs b/libafl_qemu/src/modules/usermode/drcov.rs index 2755560ac9..93d0036046 100644 --- a/libafl_qemu/src/modules/usermode/drcov.rs +++ b/libafl_qemu/src/modules/usermode/drcov.rs @@ -9,10 +9,7 @@ use serde::{Deserialize, Serialize}; use crate::{ emu::EmulatorModules, - modules::{ - EmulatorModule, EmulatorModuleTuple, HasInstrumentationFilter, IsFilter, - QemuInstrumentationAddressRangeFilter, - }, + modules::{AddressFilter, EmulatorModule, EmulatorModuleTuple}, qemu::Hook, }; @@ -39,22 +36,21 @@ impl DrCovMetadata { libafl_bolts::impl_serdeany!(DrCovMetadata); #[derive(Debug)] -pub struct DrCovModule { - filter: QemuInstrumentationAddressRangeFilter, +pub struct DrCovModule { + filter: F, module_mapping: RangeMap, filename: PathBuf, full_trace: bool, drcov_len: usize, } -impl DrCovModule { +impl DrCovModule +where + F: AddressFilter, +{ #[must_use] #[allow(clippy::let_underscore_untyped)] - pub fn new( - filter: QemuInstrumentationAddressRangeFilter, - filename: PathBuf, - full_trace: bool, - ) -> Self { + pub fn new(filter: F, filename: PathBuf, full_trace: bool) -> Self { if full_trace { let _ = DRCOV_IDS.lock().unwrap().insert(vec![]); } @@ -71,36 +67,29 @@ impl DrCovModule { #[must_use] pub fn must_instrument(&self, addr: GuestAddr) -> bool { - self.filter.allowed(addr) + self.filter.allowed(&addr) } } -impl HasInstrumentationFilter for DrCovModule { - fn filter(&self) -> &QemuInstrumentationAddressRangeFilter { - &self.filter - } - - fn filter_mut(&mut self) -> &mut QemuInstrumentationAddressRangeFilter { - &mut self.filter - } -} - -impl EmulatorModule for DrCovModule +impl EmulatorModule for DrCovModule where + F: AddressFilter, S: Unpin + UsesInput + HasMetadata, { + type ModuleAddressFilter = F; + fn init_module(&self, emulator_modules: &mut EmulatorModules) where ET: EmulatorModuleTuple, { emulator_modules.blocks( - Hook::Function(gen_unique_block_ids::), - Hook::Function(gen_block_lengths::), - Hook::Function(exec_trace_block::), + Hook::Function(gen_unique_block_ids::), + Hook::Function(gen_block_lengths::), + Hook::Function(exec_trace_block::), ); } - fn first_exec(&mut self, _state: &mut S, emulator_modules: &mut EmulatorModules) + fn first_exec(&mut self, emulator_modules: &mut EmulatorModules, _state: &mut S) where ET: EmulatorModuleTuple, { @@ -121,8 +110,8 @@ where fn post_exec( &mut self, - _state: &mut S, _emulator_modules: &mut EmulatorModules, + _state: &mut S, _input: &S::Input, _observers: &mut OT, _exit_kind: &mut ExitKind, @@ -208,18 +197,27 @@ where self.drcov_len = DRCOV_MAP.lock().unwrap().as_ref().unwrap().len(); } } + + fn address_filter(&self) -> &Self::ModuleAddressFilter { + &self.filter + } + + fn address_filter_mut(&mut self) -> &mut Self::ModuleAddressFilter { + &mut self.filter + } } -pub fn gen_unique_block_ids( +pub fn gen_unique_block_ids( emulator_modules: &mut EmulatorModules, state: Option<&mut S>, pc: GuestAddr, ) -> Option where + F: AddressFilter, S: Unpin + UsesInput + HasMetadata, ET: EmulatorModuleTuple, { - let drcov_module = emulator_modules.get::().unwrap(); + let drcov_module = emulator_modules.get::>().unwrap(); if !drcov_module.must_instrument(pc) { return None; } @@ -258,16 +256,17 @@ where } } -pub fn gen_block_lengths( +pub fn gen_block_lengths( emulator_modules: &mut EmulatorModules, _state: Option<&mut S>, pc: GuestAddr, block_length: GuestUsize, ) where + F: AddressFilter, S: Unpin + UsesInput + HasMetadata, ET: EmulatorModuleTuple, { - let drcov_module = emulator_modules.get::().unwrap(); + let drcov_module = emulator_modules.get::>().unwrap(); if !drcov_module.must_instrument(pc) { return; } @@ -279,15 +278,16 @@ pub fn gen_block_lengths( .insert(pc, block_length); } -pub fn exec_trace_block( +pub fn exec_trace_block( emulator_modules: &mut EmulatorModules, _state: Option<&mut S>, id: u64, ) where + F: AddressFilter, ET: EmulatorModuleTuple, S: Unpin + UsesInput + HasMetadata, { - if emulator_modules.get::().unwrap().full_trace { + if emulator_modules.get::>().unwrap().full_trace { DRCOV_IDS.lock().unwrap().as_mut().unwrap().push(id); } } diff --git a/libafl_qemu/src/modules/usermode/injections.rs b/libafl_qemu/src/modules/usermode/injections.rs index dcc6fc0c9f..97d275598d 100644 --- a/libafl_qemu/src/modules/usermode/injections.rs +++ b/libafl_qemu/src/modules/usermode/injections.rs @@ -11,7 +11,7 @@ * */ -use std::{ffi::CStr, fmt::Display, fs, os::raw::c_char, path::Path}; +use std::{ffi::CStr, fmt::Display, fs, os::raw::c_char, path::Path, ptr::addr_of_mut}; use hashbrown::HashMap; use libafl::{inputs::UsesInput, Error}; @@ -23,7 +23,7 @@ use crate::SYS_execve; use crate::{ elf::EasyElf, emu::EmulatorModules, - modules::{EmulatorModule, EmulatorModuleTuple}, + modules::{EmulatorModule, EmulatorModuleTuple, NopAddressFilter, NOP_ADDRESS_FILTER}, qemu::{ArchExtras, Hook, SyscallHookResult}, CallingConvention, Qemu, }; @@ -260,6 +260,8 @@ impl EmulatorModule for InjectionModule where S: Unpin + UsesInput, { + type ModuleAddressFilter = NopAddressFilter; + fn init_module(&self, emulator_modules: &mut EmulatorModules) where ET: EmulatorModuleTuple, @@ -267,7 +269,7 @@ where emulator_modules.syscalls(Hook::Function(syscall_hook::)); } - fn first_exec(&mut self, _state: &mut S, emulator_modules: &mut EmulatorModules) + fn first_exec(&mut self, emulator_modules: &mut EmulatorModules, _state: &mut S) where ET: EmulatorModuleTuple, { @@ -331,6 +333,14 @@ where } } } + + fn address_filter(&self) -> &Self::ModuleAddressFilter { + &NopAddressFilter + } + + fn address_filter_mut(&mut self) -> &mut Self::ModuleAddressFilter { + unsafe { addr_of_mut!(NOP_ADDRESS_FILTER).as_mut().unwrap().get_mut() } + } } fn syscall_hook( diff --git a/libafl_qemu/src/modules/usermode/mod.rs b/libafl_qemu/src/modules/usermode/mod.rs index e98b81efbb..1b53eb77b5 100644 --- a/libafl_qemu/src/modules/usermode/mod.rs +++ b/libafl_qemu/src/modules/usermode/mod.rs @@ -1,8 +1,6 @@ #[cfg(not(cpu_target = "hexagon"))] pub mod drcov; -use std::fmt::Debug; - #[cfg(not(cpu_target = "hexagon"))] pub use drcov::DrCovModule; @@ -27,17 +25,3 @@ pub use asan::{init_qemu_with_asan, AsanModule}; pub mod asan_guest; #[cfg(not(cpu_target = "hexagon"))] pub use asan_guest::{init_qemu_with_asan_guest, AsanGuestModule}; - -use crate::modules::{HasInstrumentationFilter, QemuInstrumentationAddressRangeFilter}; - -pub trait StdInstrumentationFilter: - HasInstrumentationFilter + Debug -{ -} - -impl StdInstrumentationFilter for (Head, ()) where - Head: HasInstrumentationFilter + Debug -{ -} - -impl StdInstrumentationFilter for () {} diff --git a/libafl_qemu/src/modules/usermode/snapshot.rs b/libafl_qemu/src/modules/usermode/snapshot.rs index ff5bbbe777..ab03f173fb 100644 --- a/libafl_qemu/src/modules/usermode/snapshot.rs +++ b/libafl_qemu/src/modules/usermode/snapshot.rs @@ -1,4 +1,4 @@ -use std::{cell::UnsafeCell, mem::MaybeUninit, sync::Mutex}; +use std::{cell::UnsafeCell, mem::MaybeUninit, ptr::addr_of_mut, sync::Mutex}; use hashbrown::{HashMap, HashSet}; use libafl::inputs::UsesInput; @@ -21,7 +21,10 @@ use crate::SYS_mmap2; use crate::SYS_newfstatat; use crate::{ emu::EmulatorModules, - modules::{asan::AsanModule, EmulatorModule, EmulatorModuleTuple, Range}, + modules::{ + asan::AsanModule, EmulatorModule, EmulatorModuleTuple, NopAddressFilter, Range, + NOP_ADDRESS_FILTER, + }, qemu::{Hook, SyscallHookResult}, Qemu, SYS_brk, SYS_fstat, SYS_fstatfs, SYS_futex, SYS_getrandom, SYS_mprotect, SYS_mremap, SYS_munmap, SYS_pread64, SYS_read, SYS_readlinkat, SYS_statfs, @@ -667,6 +670,8 @@ impl EmulatorModule for SnapshotModule where S: Unpin + UsesInput, { + type ModuleAddressFilter = NopAddressFilter; + fn init_module(&self, emulator_modules: &mut EmulatorModules) where ET: EmulatorModuleTuple, @@ -691,8 +696,8 @@ where fn pre_exec( &mut self, - _state: &mut S, emulator_modules: &mut EmulatorModules, + _state: &mut S, _input: &S::Input, ) where ET: EmulatorModuleTuple, @@ -703,6 +708,14 @@ where self.reset(emulator_modules.qemu()); } } + + fn address_filter(&self) -> &Self::ModuleAddressFilter { + &NopAddressFilter + } + + fn address_filter_mut(&mut self) -> &mut Self::ModuleAddressFilter { + unsafe { addr_of_mut!(NOP_ADDRESS_FILTER).as_mut().unwrap().get_mut() } + } } pub fn trace_write_snapshot( diff --git a/libafl_qemu/src/qemu/mod.rs b/libafl_qemu/src/qemu/mod.rs index b3d6218734..84a900b51f 100644 --- a/libafl_qemu/src/qemu/mod.rs +++ b/libafl_qemu/src/qemu/mod.rs @@ -61,9 +61,17 @@ pub enum QemuInitError { #[derive(Debug, Clone)] pub enum QemuExitReason { - End(QemuShutdownCause), // QEMU ended for some reason. - Breakpoint(GuestAddr), // Breakpoint triggered. Contains the address of the trigger. - SyncExit, // Synchronous backdoor: The guest triggered a backdoor and should return to LibAFL. + /// QEMU ended for some internal reason + End(QemuShutdownCause), + + /// Breakpoint triggered. Contains the address of the trigger + Breakpoint(GuestAddr), + + /// Synchronous exit: The guest triggered a backdoor and should return to `LibAFL`. + SyncExit, + + /// Timeout, and it has been requested to be handled by the harness. + Timeout, } #[derive(Debug, Clone)] @@ -226,6 +234,7 @@ impl Display for QemuExitReason { QemuExitReason::End(shutdown_cause) => write!(f, "End: {shutdown_cause:?}"), QemuExitReason::Breakpoint(bp) => write!(f, "Breakpoint: {bp}"), QemuExitReason::SyncExit => write!(f, "Sync Exit"), + QemuExitReason::Timeout => write!(f, "Timeout"), } } } @@ -548,8 +557,8 @@ impl Qemu { #[cfg(emulation_mode = "systemmode")] unsafe { - libc::atexit(qemu_cleanup_atexit); libafl_qemu_sys::syx_snapshot_init(true); + libc::atexit(qemu_cleanup_atexit); } Ok(Qemu { _private: () }) @@ -657,6 +666,10 @@ impl Qemu { QemuExitReason::Breakpoint(bp_addr) }, libafl_qemu_sys::libafl_exit_reason_kind_SYNC_EXIT => QemuExitReason::SyncExit, + + #[cfg(emulation_mode = "systemmode")] + libafl_qemu_sys::libafl_exit_reason_kind_TIMEOUT => QemuExitReason::Timeout, + _ => return Err(QemuExitError::UnknownKind), }) } @@ -914,7 +927,42 @@ impl QemuMemoryChunk { }) } + /// Returns the number of bytes effectively read. + /// output will get chunked at `size` bytes. + pub fn read(&self, qemu: Qemu, output: &mut [u8]) -> GuestReg { + let max_len: usize = self.size.try_into().unwrap(); + + let output_sliced = if output.len() > max_len { + &mut output[0..max_len] + } else { + output + }; + + match self.addr { + GuestAddrKind::Physical(hwaddr) => unsafe { + #[cfg(emulation_mode = "usermode")] + { + // For now the default behaviour is to fall back to virtual addresses + qemu.read_mem(hwaddr.try_into().unwrap(), output_sliced); + } + #[cfg(emulation_mode = "systemmode")] + { + qemu.read_phys_mem(hwaddr, output_sliced); + } + }, + GuestAddrKind::Virtual(vaddr) => unsafe { + self.cpu + .as_ref() + .unwrap() + .read_mem(vaddr.try_into().unwrap(), output_sliced); + }, + }; + + output_sliced.len().try_into().unwrap() + } + /// Returns the number of bytes effectively written. + /// Input will get chunked at `size` bytes. #[must_use] pub fn write(&self, qemu: Qemu, input: &[u8]) -> GuestReg { let max_len: usize = self.size.try_into().unwrap(); diff --git a/libafl_sugar/src/qemu.rs b/libafl_sugar/src/qemu.rs index bcf7e5da57..f92f3e7d6d 100644 --- a/libafl_sugar/src/qemu.rs +++ b/libafl_sugar/src/qemu.rs @@ -40,7 +40,7 @@ use libafl_bolts::{ use libafl_qemu::modules::CmpLogModule; pub use libafl_qemu::qemu::Qemu; use libafl_qemu::{ - modules::edges::{self, EdgeCoverageModule}, + modules::{edges, edges::StdEdgeCoverageModule}, Emulator, QemuExecutor, }; use libafl_targets::{edges_map_mut_ptr, CmpLogObserver}; @@ -222,15 +222,20 @@ where let modules = { #[cfg(not(any(feature = "mips", feature = "hexagon")))] { - tuple_list!(EdgeCoverageModule::default(), CmpLogModule::default(),) + tuple_list!( + StdEdgeCoverageModule::builder().build(), + CmpLogModule::default(), + ) } #[cfg(any(feature = "mips", feature = "hexagon"))] { - tuple_list!(EdgeCoverageModule::default()) + tuple_list!(StdEdgeCoverageModule::builder().build()) } }; - let mut harness = |_emulator: &mut Emulator<_, _, _, _, _>, input: &BytesInput| { + let mut harness = |_emulator: &mut Emulator<_, _, _, _, _>, + _state: &mut _, + input: &BytesInput| { let target = input.target_bytes(); let buf = target.as_slice(); harness_bytes(buf); @@ -340,9 +345,11 @@ where } } } else { - let modules = tuple_list!(EdgeCoverageModule::default()); + let modules = tuple_list!(StdEdgeCoverageModule::builder().build()); - let mut harness = |_emulator: &mut Emulator<_, _, _, _, _>, input: &BytesInput| { + let mut harness = |_emulator: &mut Emulator<_, _, _, _, _>, + _state: &mut _, + input: &BytesInput| { let target = input.target_bytes(); let buf = target.as_slice(); harness_bytes(buf); diff --git a/libafl_targets/src/libfuzzer/mutators.rs b/libafl_targets/src/libfuzzer/mutators.rs index 4d40543a53..228522f07a 100644 --- a/libafl_targets/src/libfuzzer/mutators.rs +++ b/libafl_targets/src/libfuzzer/mutators.rs @@ -139,9 +139,9 @@ impl<'a, M, MT, S> MutatorProxy<'a, M, MT, S> { struct WeakMutatorProxy { /// Function which will perform the access to the state. accessor: F, + /// A weak reference to the mutator mutator: Weak>, - /// The stage index to provide to the mutator, when executed. /// The result of mutation, to be propagated to the mutational stage result: Rc>>, diff --git a/scripts/fmt_all.sh b/scripts/fmt_all.sh index 0c3529308e..e3a9a56b4b 100755 --- a/scripts/fmt_all.sh +++ b/scripts/fmt_all.sh @@ -3,6 +3,8 @@ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" LIBAFL_DIR=$(realpath "$SCRIPT_DIR/..") +cd "${LIBAFL_DIR}" || exit 1 + if [ "$1" = "check" ]; then cargo run --manifest-path "$LIBAFL_DIR/utils/libafl_fmt/Cargo.toml" --release -- -c --verbose || exit 1 else @@ -21,4 +23,11 @@ else echo "Warning: python black not found. Formatting skipped for python." fi +if [ "$1" != "check" ]; then + if command -v taplo > /dev/null; then + echo "[*] Formatting TOML files" + taplo format + fi +fi + echo "[*] Done :)" diff --git a/scripts/gen_stub_bindings.sh b/scripts/gen_stub_bindings.sh new file mode 100755 index 0000000000..35a4404373 --- /dev/null +++ b/scripts/gen_stub_bindings.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" +LIBAFL_DIR=$(realpath "$SCRIPT_DIR/..") + +export LIBAFL_QEMU_GEN_STUBS=1 + +cd "${LIBAFL_DIR}/libafl_qemu" || exit 1 +cargo build diff --git a/utils/libafl_fmt/src/main.rs b/utils/libafl_fmt/src/main.rs index c304319750..7a6831fa46 100644 --- a/utils/libafl_fmt/src/main.rs +++ b/utils/libafl_fmt/src/main.rs @@ -69,7 +69,13 @@ #![allow(clippy::borrow_as_ptr)] #![allow(clippy::borrow_deref_ref)] -use std::{io, io::ErrorKind, path::PathBuf, str::from_utf8}; +use std::{ + fs::read_to_string, + io, + io::ErrorKind, + path::{Path, PathBuf}, + str::from_utf8, +}; use clap::Parser; use regex::RegexSet; @@ -79,10 +85,25 @@ use which::which; const REF_LLVM_VERSION: u32 = 18; +fn is_workspace_toml(path: &Path) -> bool { + for line in read_to_string(path).unwrap().lines() { + if line.eq("[workspace]") { + return true; + } + } + + false +} + async fn run_cargo_fmt(path: PathBuf, is_check: bool, verbose: bool) -> io::Result<()> { // Make sure we parse the correct file assert_eq!(path.file_name().unwrap().to_str().unwrap(), "Cargo.toml"); + if is_workspace_toml(path.as_path()) { + println!("[*] Skipping {}...", path.as_path().display()); + return Ok(()); + } + let task_str = if is_check { "Checking" } else { "Formatting" }; let mut fmt_command = Command::new("cargo");