Skip to content

implement global CPU halting and single-CPU execution for linux-usermode#129

Open
rliebig wants to merge 5 commits into
AFLplusplus:mainfrom
rliebig:multithreaded-breakpoints-v-10.2
Open

implement global CPU halting and single-CPU execution for linux-usermode#129
rliebig wants to merge 5 commits into
AFLplusplus:mainfrom
rliebig:multithreaded-breakpoints-v-10.2

Conversation

@rliebig
Copy link
Copy Markdown

@rliebig rliebig commented May 19, 2026

This PR allows breakpoints in different threads to halt the execution of all threads and fixes Issue #122. Furthermore, a function run_single_cpu is 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.

rliebig added 2 commits April 8, 2026 17:05
- 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.
@rmalmain
Copy link
Copy Markdown
Member

rmalmain commented Jun 1, 2026

sorry, i've been too busy to check for a few months. i'll take a look this week

@rmalmain
Copy link
Copy Markdown
Member

rmalmain commented Jun 1, 2026

@rliebig the CI is failing, do you mind taking a look?

rliebig added 3 commits June 2, 2026 14:34
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.
@rliebig
Copy link
Copy Markdown
Author

rliebig commented Jun 3, 2026

@rmalmain Sorry, my bad, CI should be passing now. I will have a look at the companion patch right now.

Comment thread libafl/cpu.c

void libafl_set_qemu_env(CPUArchState* env) { libafl_qemu_env = env; }

int libafl_qemu_run_single_cpu(int cpu_index) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Member

@rmalmain rmalmain left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good! can you update libafl_qemu_build/src/build.rs in the companion patch as well?

Comment thread include/libafl/exit.h
void libafl_qemu_breakpoint_run(vaddr pc_next);
int libafl_qemu_run_single_cpu(int cpu_index);

void libafl_thread_info_list_init(void);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you forgot to guard that with #ifdef CONFIG_USER_ONLY as well

Comment thread linux-user/thread_cpu.h
@@ -0,0 +1,2 @@
#include "hw/core/cpu.h"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you keep that in include/libafl/user.h instead?
we try to avoid adding files to qemu itself as much as possible.

Comment thread libafl/exit.c
static THREAD_MODIFIER struct libafl_exit_reason last_exit_reason;
static THREAD_MODIFIER bool expected_exit = false;

typedef struct LibAFLThreadInformation {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for type naming we use snake case for libafl-related stuff.
prefer struct libafl_....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants