From 5eab4fb78b736051bf7afe7ea9320f437fe13dcc Mon Sep 17 00:00:00 2001 From: am009 Date: Wed, 20 Mar 2024 03:15:07 +0800 Subject: [PATCH] Update tinyinst_simple to support Linux (#1316) (#1955) * Make fuzzers/tinyinst_simple support Linux (#1316) Fix a documentation error for `MmapShMemProvider`. * Support shmem for `fuzzers/tinyinst_simple` on Linux. Format code. * Fix CI to install cxxbridge-cmd. * Add `CARGO_TARGET_DIR` in makefile to fix CI. --- .github/workflows/build_and_test.yml | 4 +++ fuzzers/tinyinst_simple/Makefile.toml | 43 +++++++++++++++++++++++---- fuzzers/tinyinst_simple/README.md | 13 ++++---- fuzzers/tinyinst_simple/src/main.rs | 8 ++--- fuzzers/tinyinst_simple/test/test.cpp | 30 +++++++++++++++---- libafl_bolts/src/shmem.rs | 2 +- 6 files changed, 77 insertions(+), 23 deletions(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index a7e5c37bad..b83e269f6f 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -309,6 +309,10 @@ jobs: uses: baptiste0928/cargo-install@v1.3.0 with: crate: wasm-pack + - name: install cxxbridge-cmd + uses: baptiste0928/cargo-install@v1.3.0 + with: + crate: cxxbridge-cmd - name: install chrome uses: browser-actions/setup-chrome@v1 with: diff --git a/fuzzers/tinyinst_simple/Makefile.toml b/fuzzers/tinyinst_simple/Makefile.toml index ed85b91758..7b6aefc1a0 100644 --- a/fuzzers/tinyinst_simple/Makefile.toml +++ b/fuzzers/tinyinst_simple/Makefile.toml @@ -1,6 +1,7 @@ [env] PROFILE = { value = "release", condition = {env_not_set = ["PROFILE"]} } -PROFILE_DIR = {value = "release", condition = {env_not_set = ["PROFILE_DIR"] }} +PROFILE_DIR = { value = "release", condition = {env_not_set = ["PROFILE_DIR"] }} +CARGO_TARGET_DIR = { value = "target", condition = { env_not_set = ["CARGO_TARGET_DIR"] } } [tasks.unsupported] script_runner="@shell" @@ -10,10 +11,15 @@ echo "Cargo-make not integrated yet on this" # Harness [tasks.harness] -linux_alias = "unsupported" +linux_alias = "harness_linux" mac_alias = "unsupported" windows_alias = "harness_windows" +[tasks.harness_linux] +script=''' +clang test/test.cpp -o test.exe +''' + [tasks.harness_windows] script=''' cl test\test.cpp -o test.exe @@ -21,10 +27,15 @@ cl test\test.cpp -o test.exe # Fuzzer [tasks.fuzzer] -linux_alias = "unsupported" +linux_alias = "fuzzer_linux" mac_alias = "unsupported" windows_alias = "fuzzer_windows" +[tasks.fuzzer_linux] +dependencies = ["harness"] +command = "cargo" +args = ["build", "--profile", "${PROFILE}"] + [tasks.fuzzer_windows] dependencies = ["harness"] command = "cargo" @@ -32,10 +43,15 @@ args = ["build", "--profile", "${PROFILE}"] # Run the fuzzer [tasks.run] -linux_alias = "unsupported" +linux_alias = "run_linux" mac_alias = "unsupported" windows_alias = "run_windows" +[tasks.run_linux] +dependencies = ["harness", "fuzzer"] +command = "cargo" +args = ["run", "--profile", "${PROFILE}"] + [tasks.run_windows] dependencies = ["harness", "fuzzer"] command = "cargo" @@ -44,10 +60,25 @@ args = ["run", "--profile", "${PROFILE}"] # Run the fuzzer [tasks.test] -linux_alias = "unsupported" +linux_alias = "test_linux" mac_alias = "unsupported" windows_alias = "test_windows" +[tasks.test_linux] +script_runner="@shell" +script=''' +cp ${CARGO_TARGET_DIR}/${PROFILE_DIR}/tinyinst_simple . +echo running tests +timeout 5s ./tinyinst_simple || true +# corpus_discovered folder exists and is not empty +if [ -d "corpus_discovered" ] && [ -n "$(ls -A corpus_discovered)" ]; then + echo "Fuzzer works!" +else + exit 1 +fi +''' +dependencies = ["harness", "fuzzer"] + [tasks.test_windows] script_runner = "@shell" script=''' @@ -57,4 +88,4 @@ start "" "tinyinst_simple.exe" ping -n 10 127.0.0.1>NUL && taskkill /im tinyinst_simple.exe /F >nul 2>nul dir /a-d "corpus_discovered\*" && (echo Files exist) || (exit /b 1337) ''' -dependencies = [ "harness", "fuzzer" ] \ No newline at end of file +dependencies = ["harness", "fuzzer"] \ No newline at end of file diff --git a/fuzzers/tinyinst_simple/README.md b/fuzzers/tinyinst_simple/README.md index d20943d3e6..9d507df6c2 100644 --- a/fuzzers/tinyinst_simple/README.md +++ b/fuzzers/tinyinst_simple/README.md @@ -1,11 +1,12 @@ # Tinyinst example -This is a fuzzer example to show how libafl_tinyinst works +This is a fuzzer example to show how libafl_tinyinst works. ## How to build -1. Build the harness with `cl test\test.cpp -o test.exe` -2. Build the fuzzer with `cargo build --release`. The fuzzer is `target\release\tinyinst_simple.exe` +1. Install cxxbridge-cmd with `cargo install cxxbridge-cmd` +2. Build the harness with `cl test\test.cpp -o test.exe` +3. Build the fuzzer with `cargo build --release`. The fuzzer is `target\release\tinyinst_simple.exe` ## Run with cargo-make -Or, you can simple run it using cargo-make -1. Open up developer powershell so that you have access to cl (Windows Default Compiler) -2. Run `cargo make run` to run the fuzzer \ No newline at end of file +Or, you can simply run it using cargo-make +1. If on Windows, open up a developer powershell so that you have access to cl (Windows Default Compiler) +2. Run `cargo make run` to run the fuzzer diff --git a/fuzzers/tinyinst_simple/src/main.rs b/fuzzers/tinyinst_simple/src/main.rs index 60bf2307b5..c029423b11 100644 --- a/fuzzers/tinyinst_simple/src/main.rs +++ b/fuzzers/tinyinst_simple/src/main.rs @@ -13,7 +13,7 @@ use libafl::{ state::StdState, Fuzzer, StdFuzzer, }; -#[cfg(target_vendor = "apple")] +#[cfg(unix)] use libafl_bolts::shmem::UnixShMemProvider; #[cfg(windows)] use libafl_bolts::shmem::Win32ShMemProvider; @@ -25,10 +25,10 @@ use libafl_bolts::{ use libafl_tinyinst::executor::TinyInstExecutorBuilder; static mut COVERAGE: Vec = vec![]; -#[cfg(not(any(target_vendor = "apple", windows)))] +#[cfg(not(any(target_vendor = "apple", windows, target_os = "linux")))] fn main() {} -#[cfg(any(target_vendor = "apple", windows))] +#[cfg(any(target_vendor = "apple", windows, target_os = "linux"))] fn main() { // Tinyinst things let tinyinst_args = vec!["-instrument_module".to_string(), "test.exe".to_string()]; @@ -44,7 +44,7 @@ fn main() { #[cfg(windows)] let mut shmem_provider = Win32ShMemProvider::new().unwrap(); - #[cfg(target_vendor = "apple")] + #[cfg(unix)] let mut shmem_provider = UnixShMemProvider::new().unwrap(); let input = BytesInput::new(b"bad".to_vec()); diff --git a/fuzzers/tinyinst_simple/test/test.cpp b/fuzzers/tinyinst_simple/test/test.cpp index 9363d9f294..720be9eeea 100644 --- a/fuzzers/tinyinst_simple/test/test.cpp +++ b/fuzzers/tinyinst_simple/test/test.cpp @@ -23,8 +23,9 @@ limitations under the License. #include // shared memory stuff - -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) +#if defined(__linux__) + #include +#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32) #include #else #include @@ -36,7 +37,19 @@ unsigned char *shm_data; bool use_shared_memory; -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) +#if defined(__linux__) + +int setup_shmem(const char *name) { + // map shared memory to process address space + shm_data = (unsigned char *)shmat(atoi(name), NULL, 0); + if (shm_data == (void *)-1) { + perror("Error in shmat"); + return 0; + } + return 1; +} + +#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32) int setup_shmem(const char *name) { HANDLE map_file; @@ -71,7 +84,7 @@ int setup_shmem(const char *name) { // get shared memory file descriptor (NOT a file) fd = shm_open(name, O_RDONLY, S_IRUSR | S_IWUSR); if (fd == -1) { - printf("Error in shm_open\n"); + perror("Error in shm_open"); return 0; } @@ -79,7 +92,7 @@ int setup_shmem(const char *name) { shm_data = (unsigned char *)mmap(NULL, SHM_SIZE, PROT_READ, MAP_SHARED, fd, 0); if (shm_data == MAP_FAILED) { - printf("Error in mmap\n"); + perror("Error in mmap"); return 0; } @@ -101,7 +114,12 @@ char *crash = NULL; // actual target function -void FUZZ_TARGET_MODIFIERS fuzz(char *name) { +// Use extern "C" to preserve the function name for instrumentation +#ifdef __cplusplus +extern "C" +#endif // __cplusplus + void FUZZ_TARGET_MODIFIERS + fuzz(char *name) { char *sample_bytes = NULL; uint32_t sample_size = 0; diff --git a/libafl_bolts/src/shmem.rs b/libafl_bolts/src/shmem.rs index 6394685fdb..268348403e 100644 --- a/libafl_bolts/src/shmem.rs +++ b/libafl_bolts/src/shmem.rs @@ -725,7 +725,7 @@ pub mod unix_shmem { } } - /// A [`ShMemProvider`] which uses `shmget`/`shmat`/`shmctl` to provide shared memory mappings. + /// A [`ShMemProvider`] which uses [`shm_open`] and [`mmap`] to provide shared memory mappings. #[cfg(unix)] #[derive(Clone, Debug)] pub struct MmapShMemProvider {