implement global CPU halting and single-CPU execution for linux-usermode#129
implement global CPU halting and single-CPU execution for linux-usermode#129rliebig wants to merge 5 commits into
Conversation
- Add libafl_qemu_run_single_cpu() to cpu.c and exit.h, allowing the fuzzer to resume execution on a specific CPU index by setting current_cpu, thread_cpu and libafl_qemu_env before entering cpu_loop. - Introduce LibAFLThreadInformation QTAILQ in exit.c to track per-thread exit_reason and expected_exit pointers; when any CPU triggers an exit, prepare_qemu_exit broadcasts the exit reason to all registered threads and kicks every CPU out of its loop via cpu_exit / EXCP_LIBAFL_EXIT. - Add libafl_thread_info_list_init/add/remove; init is called from main.c after libafl_set_qemu_env, add is called from clone_func and the fork child path in syscall.c so every new thread registers itself. - Add linux-user/thread_cpu.h providing the extern __thread CPUState declaration needed by cpu.c and exit.c. - Update libafl_exit_signal_vm_start to reset expected_exit on all registered threads rather than only the calling thread.
In case that a single thread is closed, the list entry is removed in order to avoid memory leaks and ensure that no invalid CPU structures are accessed.
|
sorry, i've been too busy to check for a few months. i'll take a look this week |
|
@rliebig the CI is failing, do you mind taking a look? |
Keep libafl_qemu_run_single_cpu() and the thread info list helpers behind CONFIG_USER_ONLY so they are not compiled for non user-mode builds.
|
@rmalmain Sorry, my bad, CI should be passing now. I will have a look at the companion patch right now. |
|
|
||
| void libafl_set_qemu_env(CPUArchState* env) { libafl_qemu_env = env; } | ||
|
|
||
| int libafl_qemu_run_single_cpu(int cpu_index) { |
There was a problem hiding this comment.
wouldn't it be better to take CPUState* as parameter instead of cpu_index.
that way, you don't have to do error handling, as we already take care of it with cpu_from_index
rmalmain
left a comment
There was a problem hiding this comment.
looks good! can you update libafl_qemu_build/src/build.rs in the companion patch as well?
| void libafl_qemu_breakpoint_run(vaddr pc_next); | ||
| int libafl_qemu_run_single_cpu(int cpu_index); | ||
|
|
||
| void libafl_thread_info_list_init(void); |
There was a problem hiding this comment.
you forgot to guard that with #ifdef CONFIG_USER_ONLY as well
| @@ -0,0 +1,2 @@ | |||
| #include "hw/core/cpu.h" | |||
There was a problem hiding this comment.
can you keep that in include/libafl/user.h instead?
we try to avoid adding files to qemu itself as much as possible.
| static THREAD_MODIFIER struct libafl_exit_reason last_exit_reason; | ||
| static THREAD_MODIFIER bool expected_exit = false; | ||
|
|
||
| typedef struct LibAFLThreadInformation { |
There was a problem hiding this comment.
for type naming we use snake case for libafl-related stuff.
prefer struct libafl_....
This PR allows breakpoints in different threads to halt the execution of all threads and fixes Issue #122. Furthermore, a function
run_single_cpuis added which allows after a all threads halt to resume the execution of a single thread. This is useful for i.e. fuzzing parsers located which are running in a single thread in a large multithreaded application.Companion patch to libafl here.