Run thread hooks for KVM mode (#84)

* Run thread hooks for KVM mode

* Unify qemu init function symbol for systemmode and usermode

* get tid from caller instead of callee
This commit is contained in:
Romain Malmain 2024-08-21 15:36:05 +02:00 committed by GitHub
parent 7f468ebba6
commit ee43af7f80
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 43 additions and 7 deletions

View File

@ -26,6 +26,12 @@
#include <linux/kvm.h>
#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);

View File

@ -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);

3
include/libafl/system.h Normal file
View File

@ -0,0 +1,3 @@
#pragma once
void libafl_qemu_init(int argc, char** argv);

View File

@ -30,3 +30,9 @@ 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);
#ifdef AS_LIB
void libafl_qemu_init(int argc, char** argv);
#endif

View File

@ -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) {

View File

@ -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',
)])

6
libafl/system.c Normal file
View File

@ -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); }

View File

@ -35,3 +35,11 @@ uint64_t libafl_set_brk(uint64_t new_brk)
target_brk = (abi_ulong)new_brk;
return old_brk;
}
#ifdef AS_LIB
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);
}
#endif

View File

@ -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)

View File

@ -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);
}