Merge pull request #37 from AFLplusplus/fixcrash
New crash handling for usermode
This commit is contained in:
commit
32206d23c3
@ -698,22 +698,6 @@ void cpu_loop_exit_sigbus(CPUState *cpu, target_ulong addr,
|
|||||||
cpu_loop_exit_restore(cpu, ra);
|
cpu_loop_exit_restore(cpu, ra);
|
||||||
}
|
}
|
||||||
|
|
||||||
//// --- Begin LibAFL code ---
|
|
||||||
|
|
||||||
void (*libafl_dump_core_hook)(int target_sig);
|
|
||||||
|
|
||||||
/* abort execution with signal */
|
|
||||||
static G_NORETURN
|
|
||||||
void die_with_signal_nodfl(int host_sig)
|
|
||||||
{
|
|
||||||
kill(getpid(), host_sig);
|
|
||||||
|
|
||||||
/* unreachable */
|
|
||||||
_exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
//// --- End LibAFL code ---
|
|
||||||
|
|
||||||
/* abort execution with signal */
|
/* abort execution with signal */
|
||||||
static G_NORETURN
|
static G_NORETURN
|
||||||
void die_with_signal(int host_sig)
|
void die_with_signal(int host_sig)
|
||||||
@ -742,6 +726,12 @@ void die_with_signal(int host_sig)
|
|||||||
_exit(EXIT_FAILURE);
|
_exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//// --- Begin LibAFL code ---
|
||||||
|
|
||||||
|
void (*libafl_dump_core_hook)(int host_sig);
|
||||||
|
|
||||||
|
//// --- End LibAFL code ---
|
||||||
|
|
||||||
static G_NORETURN
|
static G_NORETURN
|
||||||
void dump_core_and_abort(CPUArchState *env, int target_sig)
|
void dump_core_and_abort(CPUArchState *env, int target_sig)
|
||||||
{
|
{
|
||||||
@ -779,13 +769,13 @@ void dump_core_and_abort(CPUArchState *env, int target_sig)
|
|||||||
|
|
||||||
//// --- Begin LibAFL code ---
|
//// --- Begin LibAFL code ---
|
||||||
|
|
||||||
if (libafl_dump_core_hook) libafl_dump_core_hook(target_sig);
|
if (libafl_dump_core_hook) libafl_dump_core_hook(host_sig);
|
||||||
|
|
||||||
die_with_signal_nodfl(host_sig); // to trigger LibAFL sig handler
|
// die_with_signal_nodfl(host_sig); // to trigger LibAFL sig handler
|
||||||
|
|
||||||
//// --- End LibAFL code ---
|
//// --- End LibAFL code ---
|
||||||
|
|
||||||
// die_with_signal(host_sig);
|
die_with_signal(host_sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* queue a signal so that it will be send to the virtual CPU as soon
|
/* queue a signal so that it will be send to the virtual CPU as soon
|
||||||
@ -897,6 +887,13 @@ void die_from_signal(siginfo_t *info)
|
|||||||
|
|
||||||
error_report("QEMU internal SIG%s {code=%s, addr=%p}",
|
error_report("QEMU internal SIG%s {code=%s, addr=%p}",
|
||||||
sig, code, info->si_addr);
|
sig, code, info->si_addr);
|
||||||
|
|
||||||
|
//// --- Begin LibAFL code ---
|
||||||
|
|
||||||
|
if (libafl_dump_core_hook) libafl_dump_core_hook(info->si_signo);
|
||||||
|
|
||||||
|
//// --- End LibAFL code ---
|
||||||
|
|
||||||
die_with_signal(info->si_signo);
|
die_with_signal(info->si_signo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -976,9 +973,36 @@ static void host_sigbus_handler(CPUState *cpu, siginfo_t *info,
|
|||||||
|
|
||||||
//// --- Begin LibAFL code ---
|
//// --- Begin LibAFL code ---
|
||||||
|
|
||||||
int libafl_qemu_handle_crash(int host_sig, siginfo_t *info, void *puc);
|
// int libafl_qemu_is_tb_protected_write(int host_sig, siginfo_t *info,
|
||||||
|
// host_sigcontext *uc);
|
||||||
|
void libafl_qemu_handle_crash(int host_sig, siginfo_t *info, void *puc);
|
||||||
|
|
||||||
int libafl_qemu_handle_crash(int host_sig, siginfo_t *info, void *puc)
|
/* int libafl_qemu_is_tb_protected_write(int host_sig, siginfo_t *info,
|
||||||
|
host_sigcontext *uc)
|
||||||
|
{
|
||||||
|
CPUState *cpu = thread_cpu;
|
||||||
|
uintptr_t host_addr = (uintptr_t)info->si_addr;
|
||||||
|
|
||||||
|
bool is_valid = h2g_valid(host_addr);
|
||||||
|
abi_ptr guest_addr = h2g_nocheck(host_addr);
|
||||||
|
uintptr_t pc = host_signal_pc(uc);
|
||||||
|
bool is_write = host_signal_write(info, uc);
|
||||||
|
MMUAccessType access_type = adjust_signal_pc(&pc, is_write);
|
||||||
|
|
||||||
|
return is_write
|
||||||
|
&& is_valid
|
||||||
|
&& info->si_code == SEGV_ACCERR
|
||||||
|
&& handle_sigsegv_accerr_write(cpu, host_signal_mask(uc),
|
||||||
|
pc, guest_addr);
|
||||||
|
} */
|
||||||
|
|
||||||
|
void libafl_qemu_handle_crash(int host_sig, siginfo_t *info, void *puc) {
|
||||||
|
host_signal_handler(host_sig, info, puc);
|
||||||
|
}
|
||||||
|
|
||||||
|
//// --- End LibAFL code ---
|
||||||
|
|
||||||
|
static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
|
||||||
{
|
{
|
||||||
CPUState *cpu = thread_cpu;
|
CPUState *cpu = thread_cpu;
|
||||||
CPUArchState *env = cpu_env(cpu);
|
CPUArchState *env = cpu_env(cpu);
|
||||||
@ -1001,7 +1025,7 @@ int libafl_qemu_handle_crash(int host_sig, siginfo_t *info, void *puc)
|
|||||||
case SIGSEGV:
|
case SIGSEGV:
|
||||||
/* Only returns on handle_sigsegv_accerr_write success. */
|
/* Only returns on handle_sigsegv_accerr_write success. */
|
||||||
host_sigsegv_handler(cpu, info, uc);
|
host_sigsegv_handler(cpu, info, uc);
|
||||||
return 0;
|
return;
|
||||||
case SIGBUS:
|
case SIGBUS:
|
||||||
host_sigbus_handler(cpu, info, uc);
|
host_sigbus_handler(cpu, info, uc);
|
||||||
sync_sig = true;
|
sync_sig = true;
|
||||||
@ -1016,7 +1040,7 @@ int libafl_qemu_handle_crash(int host_sig, siginfo_t *info, void *puc)
|
|||||||
/* get target signal number */
|
/* get target signal number */
|
||||||
guest_sig = host_to_target_signal(host_sig);
|
guest_sig = host_to_target_signal(host_sig);
|
||||||
if (guest_sig < 1 || guest_sig > TARGET_NSIG) {
|
if (guest_sig < 1 || guest_sig > TARGET_NSIG) {
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
trace_user_host_signal(env, host_sig, guest_sig);
|
trace_user_host_signal(env, host_sig, guest_sig);
|
||||||
|
|
||||||
@ -1058,17 +1082,8 @@ int libafl_qemu_handle_crash(int host_sig, siginfo_t *info, void *puc)
|
|||||||
|
|
||||||
/* interrupt the virtual CPU as soon as possible */
|
/* interrupt the virtual CPU as soon as possible */
|
||||||
cpu_exit(thread_cpu);
|
cpu_exit(thread_cpu);
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
|
|
||||||
{
|
|
||||||
libafl_qemu_handle_crash(host_sig, info, puc);
|
|
||||||
}
|
|
||||||
|
|
||||||
//// --- End LibAFL code ---
|
|
||||||
|
|
||||||
/* do_sigaltstack() returns target values and errnos. */
|
/* do_sigaltstack() returns target values and errnos. */
|
||||||
/* compare linux/kernel/signal.c:do_sigaltstack() */
|
/* compare linux/kernel/signal.c:do_sigaltstack() */
|
||||||
abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr,
|
abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr,
|
||||||
@ -1238,15 +1253,14 @@ static void handle_pending_signal(CPUArchState *cpu_env, int sig,
|
|||||||
|
|
||||||
//// --- Start LibAFL code ---
|
//// --- Start LibAFL code ---
|
||||||
|
|
||||||
int ignore_handling = 0;
|
|
||||||
if (libafl_force_dfl && (sig == SIGABRT || sig == SIGABRT|| sig == SIGSEGV
|
if (libafl_force_dfl && (sig == SIGABRT || sig == SIGABRT|| sig == SIGSEGV
|
||||||
|| sig == SIGILL || sig == SIGBUS)) {
|
|| sig == SIGILL || sig == SIGBUS)) {
|
||||||
ignore_handling = 1;
|
handler = TARGET_SIG_DFL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//// --- End LibAFL code ---
|
//// --- End LibAFL code ---
|
||||||
|
|
||||||
if (handler == TARGET_SIG_DFL || ignore_handling) {
|
if (handler == TARGET_SIG_DFL) {
|
||||||
/* default handler : ignore some signal. The other are job control or fatal */
|
/* default handler : ignore some signal. The other are job control or fatal */
|
||||||
if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
|
if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
|
||||||
kill(getpid(),SIGSTOP);
|
kill(getpid(),SIGSTOP);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user