From 4df4d2dcfa0d2eecfb267cddf5ebfb8ef9f58d87 Mon Sep 17 00:00:00 2001 From: Romain Malmain Date: Fri, 14 Mar 2025 16:57:23 +0100 Subject: [PATCH] Add crash exit request (#106) * add crash exit request. * make it possible to choose between crashing methods --- include/libafl/exit.h | 12 ++++++++---- include/libafl/user.h | 3 +++ libafl/exit.c | 11 +++++++++++ libafl/user.c | 16 ++++++++++++++-- linux-user/signal.c | 10 +++++++++- 5 files changed, 45 insertions(+), 7 deletions(-) diff --git a/include/libafl/exit.h b/include/libafl/exit.h index 2e54c1b44f..f088ab0949 100644 --- a/include/libafl/exit.h +++ b/include/libafl/exit.h @@ -14,7 +14,8 @@ enum libafl_exit_reason_kind { INTERNAL = 0, BREAKPOINT = 1, CUSTOM_INSN = 2, - TIMEOUT = 3, + CRASH = 3, + TIMEOUT = 4, }; enum libafl_custom_insn_kind { @@ -39,6 +40,10 @@ struct libafl_exit_reason_custom_insn { enum libafl_custom_insn_kind kind; }; +// A timeout occured and we were asked to exit on timeout +struct libafl_exit_reason_crash { +}; + // A timeout occured and we were asked to exit on timeout struct libafl_exit_reason_timeout { }; @@ -52,6 +57,7 @@ struct libafl_exit_reason { struct libafl_exit_reason_breakpoint breakpoint; // kind == BREAKPOINT struct libafl_exit_reason_custom_insn custom_insn; // kind == CUSTOM_INSN + struct libafl_exit_reason_crash crash; // kind == CRASH struct libafl_exit_reason_timeout timeout; // kind == TIMEOUT } data; }; @@ -74,9 +80,7 @@ void libafl_exit_request_internal(CPUState* cpu, uint64_t pc, void libafl_exit_request_breakpoint(CPUState* cpu, target_ulong pc); void libafl_exit_request_custom_insn(CPUState* cpu, target_ulong pc, enum libafl_custom_insn_kind kind); - -#ifndef CONFIG_USER_ONLY +void libafl_exit_request_crash(CPUState* cpu); void libafl_exit_request_timeout(void); -#endif struct libafl_exit_reason* libafl_get_exit_reason(void); diff --git a/include/libafl/user.h b/include/libafl/user.h index b05139b887..8c67dbebe0 100644 --- a/include/libafl/user.h +++ b/include/libafl/user.h @@ -49,6 +49,9 @@ uint64_t libafl_set_brk(uint64_t new_brk); int _libafl_qemu_user_init(int argc, char** argv, char** envp); +bool libafl_get_return_on_crash(void); +void libafl_set_return_on_crash(bool return_on_crash); + #ifdef AS_LIB void libafl_qemu_init(int argc, char** argv); #endif diff --git a/libafl/exit.c b/libafl/exit.c index 28464b3715..92190eef4b 100644 --- a/libafl/exit.c +++ b/libafl/exit.c @@ -125,6 +125,17 @@ void libafl_exit_request_breakpoint(CPUState* cpu, target_ulong pc) prepare_qemu_exit(cpu, pc); } +void libafl_exit_request_crash(CPUState* cpu) +{ + CPUClass* cc = CPU_GET_CLASS(cpu); + + expected_exit = true; + last_exit_reason.kind = CRASH; + last_exit_reason.cpu = cpu; + + prepare_qemu_exit(current_cpu, cc->get_pc(cpu)); +} + #ifndef CONFIG_USER_ONLY void libafl_exit_request_timeout(void) { diff --git a/libafl/user.c b/libafl/user.c index ca6019eba6..d9cc7791ff 100644 --- a/libafl/user.c +++ b/libafl/user.c @@ -4,11 +4,15 @@ #include "libafl/user.h" +extern abi_ulong target_brk, initial_target_brk; + static struct image_info libafl_image_info; -struct libafl_qemu_sig_ctx libafl_qemu_sig_ctx = {0}; +static struct libafl_qemu_sig_ctx libafl_qemu_sig_ctx = {0}; -extern abi_ulong target_brk, initial_target_brk; +// if true, target crashes will issue an exit request and return to harness. +// if false, target crahes will raise the appropriate signal. +static bool libafl_return_on_crash = false; void host_signal_handler(int host_sig, siginfo_t* info, void* puc); @@ -54,6 +58,14 @@ uint64_t libafl_set_brk(uint64_t new_brk) return old_brk; } +void libafl_set_return_on_crash(bool return_on_crash) { + libafl_return_on_crash = return_on_crash; +} + +bool libafl_get_return_on_crash(void) { + return libafl_return_on_crash; +} + #ifdef AS_LIB void libafl_qemu_init(int argc, char** argv) { diff --git a/linux-user/signal.c b/linux-user/signal.c index 728325ff1c..3ee12c4f6a 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -38,6 +38,7 @@ //// --- Begin LibAFL code --- #include "libafl/user.h" +#include "libafl/exit.h" //// --- End LibAFL code --- @@ -1284,7 +1285,14 @@ static void handle_pending_signal(CPUArchState *cpu_env, int sig, sig != TARGET_SIGURG && sig != TARGET_SIGWINCH && sig != TARGET_SIGCONT) { - dump_core_and_abort(cpu_env, sig); +//// --- Start LibAFL code --- + if (libafl_get_return_on_crash()) { + libafl_exit_request_crash(env_cpu(cpu_env)); + } else { + dump_core_and_abort(cpu_env, sig); + } +//// --- End LibAFL code --- + // dump_core_and_abort(cpu_env, sig); } } else if (handler == TARGET_SIG_IGN) { /* ignore sig */