diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 4a160e0a023..f48b96bd365 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -15,6 +15,7 @@ env: CARGO_TERM_COLOR: always CARGO_NET_GIT_FETCH_WITH_CLI: true MAIN_LLVM_VERSION: 21 + RUST_BACKTRACE: full concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/Justfile b/Justfile index 09400452ff2..1d187841deb 100644 --- a/Justfile +++ b/Justfile @@ -68,6 +68,11 @@ clippy-thumbv6m-none-eabi: test-miri: RUST_BACKTRACE=1 MIRIFLAGS="-Zmiri-disable-isolation" cargo +nightly miri test +# Tests deexit utility +[unix] +test-deexit: + cd utils/deexit && just test + # Tests all code in docs (macos version) [macos] [private] @@ -274,11 +279,11 @@ test-repro-qemu-tmin: # Tests everything (crates, fuzzers, docs, repro) [linux] -test-all: test test-fuzzers test-docs test-repro-qemu-tmin doc +test-all: test test-deexit test-fuzzers test-docs test-repro-qemu-tmin doc # Tests everything (crates, fuzzers, docs, repro) [macos] -test-all: test test-fuzzers test-docs test-repro-qemu-tmin doc +test-all: test test-deexit test-fuzzers test-docs test-repro-qemu-tmin doc # Tests everything (crates, fuzzers, docs) [windows] diff --git a/utils/deexit/.gitignore b/utils/deexit/.gitignore new file mode 100644 index 00000000000..ba077a4031a --- /dev/null +++ b/utils/deexit/.gitignore @@ -0,0 +1 @@ +bin diff --git a/utils/deexit/Cargo.toml b/utils/deexit/Cargo.toml index 9b4ed4371a2..ca5807ddaca 100644 --- a/utils/deexit/Cargo.toml +++ b/utils/deexit/Cargo.toml @@ -24,6 +24,9 @@ categories = [ [dependencies] +[target.'cfg(target_os = "macos")'.dependencies] +fishhook = "0.3" + [lib] name = "deexit" crate-type = ["cdylib"] diff --git a/utils/deexit/Justfile b/utils/deexit/Justfile index 828a80ad256..8c0ca09a38b 100644 --- a/utils/deexit/Justfile +++ b/utils/deexit/Justfile @@ -1,2 +1,34 @@ +build: + cargo build --lib + doc: cargo doc --no-deps --all-features + +build-test-bin: build + cargo build --bin exit_test + +[private] +test-helper env_var lib: + #!/usr/bin/env bash + echo "Running test..." + {{ env_var }}="{{ lib }}" ../../target/debug/exit_test + CODE=$? + + if [ $CODE -eq 134 ]; then + echo "SUCCESS: Process aborted as expected (Exit code 134)" + exit 0 + elif [ $CODE -eq 42 ]; then + echo "FAILURE: Process exited normally with code 42 (Hook failed)" + exit 1 + else + echo "FAILURE: Process exited with unexpected code $CODE" + exit 1 + fi + +[macos] +test: build-test-bin + just test-helper DYLD_INSERT_LIBRARIES ../../target/debug/libdeexit.dylib + +[linux] +test: build-test-bin + just test-helper LD_PRELOAD ../../target/debug/libdeexit.so diff --git a/utils/deexit/README.md b/utils/deexit/README.md index 47b7c653e73..eba52d84abf 100644 --- a/utils/deexit/README.md +++ b/utils/deexit/README.md @@ -2,5 +2,5 @@ This util helps you, if your target calls `exit` during a fuzz run. A simple wrapper that can be inserted into a program to turn `exit` calls to `abort`, which LibAFL will be able to catch. -If you are on MacOS, use the env variables `DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_INSERT_LIBRARIES="path/to/target/release/libdeexit.dylib" tool` +If you are on MacOS, use the env variables `DYLD_INSERT_LIBRARIES="path/to/target/release/libdeexit.dylib" tool` On Linux, use `LD_PRELOAD="path/to/target/release/libdeexit.so" tool`. diff --git a/utils/deexit/src/lib.rs b/utils/deexit/src/lib.rs index ed38dffa39b..dbedf012b8e 100644 --- a/utils/deexit/src/lib.rs +++ b/utils/deexit/src/lib.rs @@ -1,5 +1,5 @@ //! A simple wrapper that can be inserted into a program to turn `exit` calls to `abort`, which `LibAFL` will be able to catch. -//! If you are on `MacOS`, use the env variables `DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_INSERT_LIBRARIES="path/to/target/release/libdeexit.dylib" tool` +//! If you are on `MacOS`, use the env variables `DYLD_INSERT_LIBRARIES="path/to/target/release/libdeexit.dylib" tool` //! On Linux, use `LD_PRELOAD="path/to/target/release/libdeexit.so" tool`. unsafe extern "C" { @@ -14,3 +14,17 @@ pub extern "C" fn exit(status: i32) { abort(); } } + +#[cfg(target_os = "macos")] +use ctor::ctor; + +#[cfg(target_os = "macos")] +#[ctor] +fn init() { + unsafe { + fishhook::register(vec![fishhook::Rebinding { + name: "exit".to_string(), + function: exit as *const () as usize, + }]); + } +}