AFLplusplus / AFLplusplus/LibAFL

SIGSEGV when using asan in aarch64 qemu mode

Ouverte
#2,617 9 commentaires 0 réactions 1 personne assignée Réclamée par @rmalmain Voir sur GitHub
bug qemu
Langage dominant
Rust
Étoiles
2.6k
Forks
481
Merge moyen
2 j 30 min
PR mergées (30 j)
16

Description

**IMPORTANT**
1. You have verified that the issue to be present in the current `main` branch
Yes
```
$ git log | head -n 1
commit 453d733a3562dcea290265dafec1908832f97658
```

**Describe the bug**
I first encountered this issue when reproducing the result of android fuzzer in [libafl_qemu_artifact](https://github.com/AFLplusplus/libafl_qemu_artifacts/tree/main/android_fuzzer). When I added `--features asan` to the building process of the fuzzer, it crashed and the log showed:
```
qemu: QEMU internal SIGSEGV {code=MAPERR, addr=0x1555d554de02}
Segmentation fault(core dumped)
```
I debugged this issue thoroughly and carefully using gdb-multiarch, and found that it is caused by a dereference failure of shadow memory address:
```
0x5555557307b5 lea rax, [rip + 0x8ac3e4] RAX => 0x555555fdcba0 (guest_base) ◂— 0
0x5555557307bc mov rcx, qword ptr [rax] RCX, [guest_base] => 0
0x5555557307bf xor eax, eax EAX => 0
0x5555557307c1 nop word ptr cs:[rax + rax]
0x5555557307d0 lea rdx, [rcx + rbx] RDX => 0xaaaaaaaaf010 ◂— 0
0x5555557307d4 sar rdx, 3
► 0x5555557307d8 mov byte ptr [rdx + 0x7fff8000], 0
0x5555557307df add rbx, 8
```
This is in function "libafl_qemu::modules::usermode::asan::AsanGiovese::unposion", which is in libafl_qemu/src/modules/usermode/asan.rs:
```
pub fn unpoison(qemu: Qemu, addr: GuestAddr, n: usize) -> bool {
unsafe {
let n = n as isize;
let mut start = addr;
let end = start.wrapping_add(n as GuestAddr);

while start < end {
let h = qemu.g2h::<*const c_void>(start) as isize;
let shadow_addr = ((h >> 3) as *mut i8).offset(SHADOW_OFFSET);
► *shadow_addr = 0;
start = (start).wrapping_add(8);
}
true
}
}
```
In my case, the original start addr is 0xaaaaaaaaf010,n is 0x158,end addr is 0xaaaaaaaaf168. When it execute `(h >> 3)`, 0xaaaaaaaaf010 becomes 0x155555555e02. The `SHADOW_OFFSET` is 0x7fff8000, so `shadow_addr` is 0x1555d554de02. Both 0x155555555e02 and 0x1555d554de02 is not addressable:
```
pwndbg>x/x 0x155555555e02
0x155555555e02:
Cannot access memory at address 0x155555555e02
```
This happens in libafl-0.11.2, and I also tried 0.13.2, it still exists.
-------------------------------------8<----------------------------------
I saw this similar [issue 2579](https://github.com/AFLplusplus/LibAFL/issues/2579) , so I tried the example fuzzer [qemu_launcher](https://github.com/AFLplusplus/LibAFL/tree/main/fuzzers/binary_only/qemu_launcher) in the latest main version (as I said in the begining). In my case, the `--features=x86_64, asan` works well:
```
pwndbg> p/x end
$3= 0x7ffff5b004a8
pwndbg> p/x start
$4= 0x7ffff5b002a0
pwndbg> p n
$5 =
pwndbg> p/x end-start
$6 = 0x208
==============
0x7ffff5b002a0 >> 3 = 0xffffeb60054
==============
pwndbg> x/x 0xffffeb60054
0xffffeb60054: 0x00000000
```
The start addr is 0x7ffff5b004a8. After right shift it becomes 0xffffeb60054, and this addr is addressable.

But in `--features=aarch64, asan`, it crashes because of the same reason but in different code area:
```
pwndbg> set args "--input" "./corpus" "--output" "/home/LibAFL/fuzzers/binary_only/qemu_launcher/target/aarch64/output/" "--cores" "0-7" "--asan-cores" "0-3" "--cmplog-cores" "2-5" "--verbose" "--" "/home/LibAFL/fuzz
ers/binary_only/qemu_launcher/target/aarch64/libpng-harness-aarch64"
pwndbg> r
Starting program: /home/LibAFL/fuzzers/binary_only/qemu_launcher/target/aarch64/release/qemu_launcher-aarch64 "--input" "./corpus" "--output" "/home/LibAFL/fuzzers/binary_only/qemu_launcher/target/aarch64/output/" "--cores" "0-7" "--asan-cores" "0-3" "--cmplog-cores" "2-5" "--verbose" "--" "/home/LibAFL/fuzzers/binary_only/qemu_launcher/target/aarch64/libpng-harness-aarch64"
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff7800640 (LWP 3793330)]

Thread 1 "qemu_launcher-a" received signal SIGSEGV, Segmentation fault.
libafl_qemu::modules::usermode::asan::AsanModule::read_8 (self=0x55555923c428, pc=, addr=) at /home/LibAFL/libafl_qemu/src/modules/usermode/asan.rs:868
868 if self.enabled() && AsanGiovese::is_invalid_access_8(qemu, addr) {
Warning: the current language does not match this frame.
LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA
───────────────────────────────[ REGISTERS / show-flags off / show-compact-regs off ]───────────────────────────────
RAX 0x55555923c400 ◂— 0
RBX 0xaaaaaab0ff60 —▸ 0x7ffff79fdb58 ◂— 0xadb771622a56ae00
RCX 0xaaaaaab0ff60 —▸ 0x7ffff79fdb58 ◂— 0xadb771622a56ae00
RDX 0xaaaaaaaa1788 ◂— 0xf9400001f947b000
RDI 0x55555923ded0 ◂— 0
RSI 0x155555561fec
R8 0xaaaaaab0ff60 —▸ 0x7ffff79fdb58 ◂— 0xadb771622a56ae00
R9 0x55555564efb0 (libafl_qemu::modules::usermode::asan::trace_read8_asan) ◂— mov rax, qword ptr [rdi + 0x120]
R10 0
R11 0xffffedbffcd ◂— 0
R12 0x7ffff79fdb58 ◂— 0xadb771622a56ae00
R13 0xaaaaaaaa1fa0 ◂— 0x2a0003e152800000
R14 0x7fffe8000100 (code_gen_buffer+211) ◂— mov ebx, dword ptr [rbp - 0x10] /* 0xce8c0fdb85f05d8b */
R15 0x7fffe8000040 (code_gen_buffer+19) —▸ 0xaaaaaaaa176c ◂— 0xa9017bfdd10303ff
RBP 0x5555591df880 ◂— 0
RSP 0x7fffffffa3b8 —▸ 0x7fffe8000273 (code_gen_buffer+582) ◂— mov rbx, qword ptr [rbp + 0x40] /* 0x49e38b4c405d8b48 */
RIP 0x55555564efce (libafl_qemu::modules::usermode::asan::trace_read8_asan+30) ◂— cmp byte ptr [rsi + 0x7fff8000], 0
────────────────────────────────────────[ DISASM / x86-64 / set emulate on ]────────────────────────────────────────
► 0x55555564efce cmp byte ptr [rsi + 0x7fff8000], 0
0x55555564efd5 je libafl_qemu::modules::usermode::asan::trace_read8_asan+90

0x55555564efd7 sub rsp, 0x28
0x55555564efdb mov rdi, qword ptr [rax + 0x48]
0x55555564efdf mov qword ptr [rsp + 0x10], rcx
0x55555564efe4 mov qword ptr [rsp + 0x18], 8
0x55555564efed mov qword ptr [rsp + 8], 2
0x55555564eff6 lea rax, [rsp + 8]
0x55555564effb mov rsi, rdx
0x55555564effe mov rdx, rax
0x55555564f001 call libafl_qemu::modules::usermode::asan::AsanGiovese::report_or_crash
─────────────────────────────────────────────────[ SOURCE (CODE) ]──────────────────────────────────────────────────
In file: /home/LibAFL/libafl_qemu/src/modules/usermode/asan.rs:868
863 self.rt.report_or_crash(qemu, pc, AsanError::Read(addr, 4));
864 }
865 }
866
867 pub fn read_8(&mut self, qemu: Qemu, pc: GuestAddr, addr: GuestAddr) {
► 868 if self.enabled() && AsanGiovese::is_invalid_access_8(qemu, addr) {
869 self.rt.report_or_crash(qemu, pc, AsanError::Read(addr, 8));
870 }
871 }
872
873 pub fn read_n(&mut self, qemu: Qemu, pc: GuestAddr, addr: GuestAddr, size: usize) {
─────────────────────────────────────────────────────[ STACK ]──────────────────────────────────────────────────────
00:0000│ rsp 0x7fffffffa3b8 —▸ 0x7fffe8000273 (code_gen_buffer+582) ◂— mov rbx, qword ptr [rbp + 0x40] /* 0x49e38b4c405d8b48 */
01:0008│ 0x7fffffffa3c0 —▸ 0x5555591b9218 (tcg_init_ctx+2008) —▸ 0x6201010203 ◂— 0
02:0010│ 0x7fffffffa3c8 ◂— 0
03:0018│ 0x7fffffffa3d0 —▸ 0x5555591ba210 (tcg_init_ctx+6096) —▸ 0x800101000c ◂— 0
04:0020│ 0x7fffffffa3d8 ◂— 0x1530
05:0028│ 0x7fffffffa3e0 ◂— 0x5030 /* '0P' */
06:0030│ 0x7fffffffa3e8 ◂— 0
07:0038│ 0x7fffffffa3f0 ◂— 7
───────────────────────────────────────────────────[ BACKTRACE ]────────────────────────────────────────────────────
► 0 0x55555564efce libafl_qemu::modules::usermode::asan::trace_read8_asan+30
1 0x55555564efce libafl_qemu::modules::usermode::asan::trace_read8_asan+30
2 0x7fffe8000273 code_gen_buffer+582
3 0x555555b92470 cpu_tb_exec+80
4 0x555555b93055 cpu_exec_loop.constprop+805
5 0x555555b93055 cpu_exec_loop.constprop+805
6 0x555555b93639 cpu_exec_setjmp.isra+41
7 0x555555b936cb cpu_exec+107
───────────────────────────────────────────────[ THREADS (2 TOTAL) ]────────────────────────────────────────────────
► 1 "qemu_launcher-a" stopped: 0x55555564efce
2 "qemu_launcher-a" stopped: 0x7ffff7b1e88d
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
```
Here, it crashes at accessing [rsi + 0x7fff8000], which looks the same as the issue before.
```
pwndbg> x/x (0x155555561fec+0x7fff8000)
0x1555d5559fec: Cannot access memory at address 0x1555d5559fec

=====================================================
0x00005555556445fd <+13>: lea rsi,[rip+0x2b44bc4] # 0x5555581891c8
0x0000555555644604 <+20>: mov rsi,QWORD PTR [rsi]
0x0000555555644607 <+23>: add rsi,rcx
0x000055555564460a <+26>: sar rsi,0x3
=> 0x000055555564460e <+30>: cmp BYTE PTR [rsi+0x7fff8000],0x0
```

I am new to qasan, so now I am trying to figure out why this happened.
Can you offer some help to this issue? Thank you very much!

**To Reproduce**

- Steps to reproduce the android fuzzer behavior:

I do totally the same as the instruction in [libafl_qemu_artifact](https://github.com/AFLplusplus/libafl_qemu_artifacts/tree/main/android_fuzzer).

- Steps to reproduce the qemu_launcher behavior:

```
git clone https://github.com/AFLplusplus/LibAFL.git
cd LibAFL/fuzzers/qemu/qemu_launcher
export LLVM_CONFIG="llvm-config-15"
export QEMU_LD_PREFIX=/path/to/aarch64-linux-gnu/
cargo make aarch64
```
I modified the Makefile.toml to add the feature `simplemgr` in the case of clarity.

- Steps to debug qemu_launcher:

```
gdb-multiarch target/aarch64/release/qemu_launcher-aarch64
pwndbg> set args --input ./corpus/ --output target/aarch64/output/ --cores 0-1 --asan-cores 0 --cmplog-cores 1 -- target/aarch64/libpng-harness-aarch64
```

My environment info:
```
lsb_release -a && \
arch && \
llvm-config --version && \
rustup toolchain list && \
rustc -V
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 22.04.2 LTS
Release: 22.04
Codename: jammy
x86_64
14.0.0 (I export LLVM_CONFIG=llvm-config-15 when building the fuzzer's project)
stable-x86_64-unknown-linux-gnu (default)
nightly-x86_64-unknown-linux-gnu
rustc 1.80.1 (3f5fd8dd4 2024-08-06)
```

**Expected behavior**
The fuzzer works well as in x86_64 architecture.

Guide de contribution

Ouvrir le guide de contribution

Évaluation

Cette issue n'a pas encore été évaluée.

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.