Add test case for AFL_QEMU_PERSISTENT_EXITS

Add a test case to `test/test-qemu-mode.sh` and make sure that
AFL_QEMU_PERSISTENT_EXITS loops correctly.

This works only on platforms for which `afl-qemu-trace` detects exit
signals and resets the program counter.

This commit updates `test-instr.c` to optionally call `exit(n)` instead of
returning n to the operating system. This option can be activated using
the `EXIT_AT_END` flag. This way, we can test the
QEMU persistent exit mode without having to add a new test file.

You can compile and run `test-instr.c` with the exit mode like so:

```bash
gcc -o exit -DEXIT_AT_END test-instr.c
AFL_QEMU_DEBUG_MAPS= \
    AFL_DEBUG= \
    AFL_QEMU_PERSISTENT_ADDR=$(readelf -a exit | grep 'main$' | awk '{ printf "0x%s", $2 }') \
    AFL_QEMU_PERSISTENT_GPR=1 \
    AFL_QEMU_PERSISTENT_EXITS=1 \
    ./afl-qemu-trace exit
```

Press enter repeatedly and you will see an output like this:

```
...
Debug: Sending status 0xc201ffff

test-instr:

Neither one or zero? How quaint!

test-instr:

Neither one or zero? How quaint!

test-instr:

Neither one or zero? How quaint!

test-instr:

Neither one or zero? How quaint!

test-instr:

Neither one or zero? How quaint!
```

To make sure that persistent exits are detected correctly on x86_64, I've made
the following changes to qemuafl:

```
 linux-user/i386/cpu_loop.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/linux-user/i386/cpu_loop.c b/linux-user/i386/cpu_loop.c
index 4509f46b95..46bdbaf94a 100644
--- a/linux-user/i386/cpu_loop.c
+++ b/linux-user/i386/cpu_loop.c
@@ -235,7 +235,7 @@ void cpu_loop(CPUX86State *env)
 #ifndef TARGET_ABI32
         case EXCP_SYSCALL:
             /* linux syscall from syscall instruction */
-            if (afl_fork_child && persistent_exits &&
+            if (persistent_exits &&
                 env->regs[R_EAX] == TARGET_NR_exit_group) {
               env->eip = afl_persistent_addr;
               continue;
```
This commit is contained in:
Justus Perlwitz
2025-04-29 11:40:21 +09:00
parent c340a022e2
commit b418a87340
2 changed files with 63 additions and 3 deletions

View File

@ -49,7 +49,11 @@ int main(int argc, char **argv) {
if ((cnt = read(fd, buf, sizeof(buf) - 1)) < 1) {
printf("Hum?\n");
#ifdef EXIT_AT_END
exit(1);
#else
return 1;
#endif
}
@ -76,6 +80,9 @@ int main(int argc, char **argv) {
break;
}
#ifdef EXIT_AT_END
exit(0);
#endif
return 0;