From ec91486cedfd9e636be0063d88bd6e7eaff74915 Mon Sep 17 00:00:00 2001 From: Romain Malmain Date: Wed, 14 Aug 2024 15:36:37 +0200 Subject: [PATCH] Run thread hooks for KVM mode * Unify qemu init function symbol for systemmode and usermode * get tid from caller instead of callee --- accel/kvm/kvm-accel-ops.c | 12 ++++++++++++ include/libafl/hooks/thread.h | 2 +- include/libafl/system.h | 3 +++ include/libafl/user.h | 3 +++ libafl/hooks/thread.c | 5 +++-- libafl/meson.build | 3 ++- libafl/system.c | 6 ++++++ libafl/user.c | 6 ++++++ linux-user/main.c | 3 +-- linux-user/syscall.c | 2 +- 10 files changed, 38 insertions(+), 7 deletions(-) create mode 100644 include/libafl/system.h create mode 100644 libafl/system.c diff --git a/accel/kvm/kvm-accel-ops.c b/accel/kvm/kvm-accel-ops.c index b3c946dc4b..e87565c208 100644 --- a/accel/kvm/kvm-accel-ops.c +++ b/accel/kvm/kvm-accel-ops.c @@ -26,6 +26,12 @@ #include #include "kvm-cpus.h" +//// --- Begin LibAFL code --- + +#include "libafl/hooks/thread.h" + +//// --- End LibAFL code --- + static void *kvm_vcpu_thread_fn(void *arg) { CPUState *cpu = arg; @@ -41,6 +47,12 @@ static void *kvm_vcpu_thread_fn(void *arg) r = kvm_init_vcpu(cpu, &error_fatal); kvm_init_cpu_signals(cpu); +//// --- Begin LibAFL code --- + + libafl_hook_new_thread_run(cpu_env(cpu), cpu->thread_id); + +//// --- End LibAFL code --- + /* signal CPU creation */ cpu_thread_signal_created(cpu); qemu_guest_random_seed_thread_part2(cpu->random_seed); diff --git a/include/libafl/hooks/thread.h b/include/libafl/hooks/thread.h index 2db1744c48..e423aad7b2 100644 --- a/include/libafl/hooks/thread.h +++ b/include/libafl/hooks/thread.h @@ -28,4 +28,4 @@ size_t libafl_add_new_thread_hook(bool (*callback)(uint64_t data, uint64_t data); int libafl_qemu_remove_new_thread_hook(size_t num); -bool libafl_hook_new_thread_run(CPUArchState* env); +bool libafl_hook_new_thread_run(CPUArchState* env, uint32_t tid); diff --git a/include/libafl/system.h b/include/libafl/system.h new file mode 100644 index 0000000000..454d45b9f4 --- /dev/null +++ b/include/libafl/system.h @@ -0,0 +1,3 @@ +#pragma once + +void libafl_qemu_init(int argc, char** argv); diff --git a/include/libafl/user.h b/include/libafl/user.h index 69eba3995f..00f3ea18f9 100644 --- a/include/libafl/user.h +++ b/include/libafl/user.h @@ -30,3 +30,6 @@ struct image_info* libafl_get_image_info(void); uint64_t libafl_get_brk(void); uint64_t libafl_set_brk(uint64_t new_brk); + +int _libafl_qemu_user_init(int argc, char** argv, char** envp); +void libafl_qemu_init(int argc, char** argv); diff --git a/libafl/hooks/thread.c b/libafl/hooks/thread.c index b58ca8b57a..134308cf27 100644 --- a/libafl/hooks/thread.c +++ b/libafl/hooks/thread.c @@ -24,13 +24,14 @@ size_t libafl_add_new_thread_hook(bool (*callback)(uint64_t data, return hook->num; } -bool libafl_hook_new_thread_run(CPUArchState* env) +bool libafl_hook_new_thread_run(CPUArchState* env, uint32_t tid) { +#ifdef CONFIG_USER_ONLY libafl_set_qemu_env(env); +#endif if (libafl_new_thread_hooks) { bool continue_execution = true; - int tid = gettid(); struct libafl_new_thread_hook* h = libafl_new_thread_hooks; while (h) { diff --git a/libafl/meson.build b/libafl/meson.build index 3f4d2f5aad..b6d1dc52e0 100644 --- a/libafl/meson.build +++ b/libafl/meson.build @@ -16,9 +16,11 @@ specific_ss.add(files( # General hooks 'hooks/cpu_run.c', + 'hooks/thread.c', )) specific_ss.add(when : 'CONFIG_SOFTMMU', if_true : [files( + 'system.c', 'qemu_snapshot.c', 'syx-snapshot/device-save.c', 'syx-snapshot/syx-snapshot.c', @@ -29,6 +31,5 @@ specific_ss.add(when : 'CONFIG_SOFTMMU', if_true : [files( specific_ss.add(when : 'CONFIG_USER_ONLY', if_true : [files( 'user.c', 'hooks/syscall.c', - 'hooks/thread.c', )]) diff --git a/libafl/system.c b/libafl/system.c new file mode 100644 index 0000000000..f22c0973c6 --- /dev/null +++ b/libafl/system.c @@ -0,0 +1,6 @@ +#include "qemu/osdep.h" +#include "sysemu/sysemu.h" + +#include "libafl/system.h" + +void libafl_qemu_init(int argc, char** argv) { qemu_init(argc, argv); } diff --git a/libafl/user.c b/libafl/user.c index e259361b97..e0b89f55be 100644 --- a/libafl/user.c +++ b/libafl/user.c @@ -35,3 +35,9 @@ uint64_t libafl_set_brk(uint64_t new_brk) target_brk = (abi_ulong)new_brk; return old_brk; } + +void libafl_qemu_init(int argc, char** argv) +{ + // main function in usermode has an env parameter but is unused in practice. + _libafl_qemu_user_init(argc, argv, NULL); +} diff --git a/linux-user/main.c b/linux-user/main.c index c46e7696b9..932967c761 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -693,8 +693,7 @@ static int parse_args(int argc, char **argv) struct linux_binprm bprm; #ifdef AS_LIB -int qemu_user_init(int argc, char **argv, char **envp); -int qemu_user_init(int argc, char **argv, char **envp) +int _libafl_qemu_user_init(int argc, char **argv, char **envp) #else //// --- End LibAFL code --- int main(int argc, char **argv, char **envp) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index a1479e77fe..9c7c7d848b 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -6556,7 +6556,7 @@ static void *clone_func(void *arg) //// --- Begin LibAFL code --- - if (libafl_hook_new_thread_run(env)) { + if (libafl_hook_new_thread_run(env, info->tid)) { cpu_loop(env); }