Persistent mode is broken on aarch64, since AFL_QEMU_TARGET_ARM64_SNIPPET is inserted before updating pc
galli-leo opened this issue · comments
I investigated an issue I had with persistent mode on aarch64, where a bunch of weird stuff would happen.
I finally figured out what causes this, in translate-a64.c AFL_QEMU_TARGET_ARM64_SNIPPET
is referenced before the pc is updated (s->pc_curr = s->base.pc_next;
).
In all other architectures, the pc is first updated, then the snippet is referenced. This leads to the persistent loop starting one instruction too late, and hence fp, lr are not preserved (at least for my binary).
Since I don't know where exactly it should come afterwards, I didn't open a PR, but if it's just the line afterwards like on arm, I can do that.
A repro case is here: https://gist.github.com/galli-leo/c879a84e5512f3b90d63b1e28f11112a
hook.c is not really important, just that one is needed. repro_fuzz.c should be compiled for aarch64.
Here is also the qemu log for the (beginning) of the do_fuzz
function:
IN: do_fuzz
0x00400614: a9bd7bfd stp x29, x30, [sp, #-0x30]!
0x00400618: 910003fd mov x29, sp
0x0040061c: f90017e0 str x0, [sp, #0x28]
0x00400620: f90013e1 str x1, [sp, #0x20]
0x00400624: f9000fe2 str x2, [sp, #0x18]
0x00400628: f9400fe3 ldr x3, [sp, #0x18]
0x0040062c: f94013e2 ldr x2, [sp, #0x20]
0x00400630: f94017e1 ldr x1, [sp, #0x28]
0x00400634: 90000000 adrp x0, #0x400000
0x00400638: 911d2000 add x0, x0, #0x748
0x0040063c: 97ffffa9 bl #0x4004e0
OP:
mov_i64 tmp0,$0x1461
call afl_maybe_log,$0x1,$0,tmp0
ld_i32 tmp2,env,$0xfffffffffffffff0
brcond_i32 tmp2,$0x0,lt,$L0
---- 0000000000400614 0000000000000000 0000000000000000
mov_i64 tmp0,sp
add_i64 tmp0,tmp0,$0xffffffffffffffd0
shl_i64 tmp5,tmp0,$0x8
sar_i64 tmp5,tmp5,$0x8
and_i64 tmp5,tmp5,tmp0
qemu_st_i64 x29,tmp5,leq,8
add_i64 tmp5,tmp5,$0x8
qemu_st_i64 lr,tmp5,leq,8
mov_i64 sp,tmp0
---- 0000000000400618 0000000000000000 0000000000000000
call afl_persistent_routine,$0x1,$0,env
mov_i64 tmp0,sp
mov_i64 x29,tmp0
Hi @galli-leo ,
yes the pc update is in the wrong place, probably something went wrong while updating the patches.
Can you try to just move AFL_QEMU_TARGET_ARM64_SNIPPET the line before if (dc_isar_feature(aa64_bti, s)) {
and tell me if this fix the issue?
You can rebuild qemuafl from afl++ keeping your changes using NO_CHECKOUT=1 when calling the build shell script
Yep works correctly!
@galli-leo do you want to push a PR?
Nevermind, I did it