LibAFL icon indicating copy to clipboard operation
LibAFL copied to clipboard

Crash in libafl_maps_next when iterating over qemu.mapping

Open celi0n opened this issue 10 months ago • 5 comments

Describe the bug My fuzzer crash every time a for map in qemu.mappings() { is done (in Snapshot helper, QemuMappingsViewer or when I do it in my code) . Same when I run the qemu_coverage example on latest LibAFL commit (it does let mappings = QemuMappingsViewer::new(&qemu);).

To Reproduce Steps to reproduce the behavior:

  1. Maybe this is related to my setup which affect the mapping ? But it is not that exotic: Linux pct 6.1.0-30-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.124-1 (2025-01-12) x86_64 GNU/Linux
  2. Do just run on qemu_coverage example:
Thread 3.1 "qemu_coverage" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff7aeb900 (LWP 81365)]
libafl_maps_next (pageflags_maps_node=0x55555600bc60, proc_maps_root=<optimized out>, ret=0x7fffffffae40) at ../linux-user/syscall.c:13826
13826           ret->offset = (target_ulong)e->offset;
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
────────────────────────────────────────────────────────────────────────[ REGISTERS / show-flags off / show-compact-regs off ]────────────────────────────────────────────────────────────────────────
 RAX  0x0
*RBX  0x7fffffffae40 ◂— 0xffffffffff600000
 RCX  0x0
*RDX  0x555555fe9298 (guest_base) ◂— 0x0
 RDI  0x0
 RSI  0x0
*R8   0x7ffff7d5cc60 (main_arena) ◂— 0x0
*R9   0x555556118ec0 ◂— 0x55500344e038
*R10  0xa0cb078db41b86e7
*R11  0x1d0
*R12  0xffffffffff600000
*R13  0xffffffffff601000
*R14  0x55555600bc60 —▸ 0x555556022880 —▸ 0x555556022611 ◂— 0x8000005555560225
*R15  0xffffffffff600fff
*RBP  0x4
*RSP  0x7fffffffada0 —▸ 0x555556111d10 —▸ 0x5555561199a0 ◂— 0x1
*RIP  0x555555763426 (libafl_maps_next+326) ◂— mov rcx, qword ptr [rax + 0x48]
─────────────────────────────────────────────────────────────────────────────────[ DISASM / x86-64 / set emulate on ]─────────────────────────────────────────────────────────────────────────────────
 ► 0x555555763426 <libafl_maps_next+326>    mov    rcx, qword ptr [rax + 0x48]
   0x55555576342a <libafl_maps_next+330>    mov    qword ptr [rbx + 0x10], rcx
   0x55555576342e <libafl_maps_next+334>    mov    rcx, qword ptr [rax + 0x50]
   0x555555763432 <libafl_maps_next+338>    mov    qword ptr [rbx + 0x18], rcx
   0x555555763436 <libafl_maps_next+342>    mov    dword ptr [rbx + 0x20], ebp
   0x555555763439 <libafl_maps_next+345>    movzx  eax, byte ptr [rax + 0x33]
   0x55555576343d <libafl_maps_next+349>    mov    dword ptr [rbx + 0x24], eax
   0x555555763440 <libafl_maps_next+352>    mov    rdi, r14
   0x555555763443 <libafl_maps_next+355>    xor    esi, esi
   0x555555763445 <libafl_maps_next+357>    mov    rdx, 0xffffffffffffffff
   0x55555576344c <libafl_maps_next+364>    add    rsp, 8
──────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]───────────────────────────────────────────────────────────────────────────────────────────
In file: /home/celian/Downloads/experimentation/last_LibAFl/LibAFL/fuzzers/binary_only/qemu_coverage/target/release/qemu-libafl-bridge/linux-user/syscall.c:13826
   13821         if (flags & PAGE_EXEC) libafl_flags |= PROT_EXEC;
   13822 
   13823         ret->is_valid = true;
   13824         ret->start = (target_ulong)h2g_nocheck(min);
   13825         ret->end = (target_ulong)h2g_nocheck(max);
 ► 13826         ret->offset = (target_ulong)e->offset;
   13827         ret->path = e->path;
   13828         ret->flags = libafl_flags;
   13829         ret->is_priv = e->is_priv;
   13830 
   13831         return interval_tree_iter_next(pageflags_maps_node, 0, -1);
──────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]───────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ rsp 0x7fffffffada0 —▸ 0x555556111d10 —▸ 0x5555561199a0 ◂— 0x1
01:0008│     0x7fffffffada8 —▸ 0x555556111d10 —▸ 0x5555561199a0 ◂— 0x1
02:0010│     0x7fffffffadb0 —▸ 0x55555600bc60 —▸ 0x555556022880 —▸ 0x555556022611 ◂— 0x8000005555560225
03:0018│     0x7fffffffadb8 ◂— 0x1
04:0020│     0x7fffffffadc0 ◂— 0x0
05:0028│     0x7fffffffadc8 ◂— 0xa /* '\n' */
06:0030│     0x7fffffffadd0 —▸ 0x5555557632e0 (libafl_maps_next) ◂— push rbp
07:0038│     0x7fffffffadd8 —▸ 0x555555690831 (libafl_qemu::qemu::usermode::QemuMappingsViewer::new::h801b422b998f9e44+241) ◂— mov r12, rax
────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]─────────────────────────────────────────────────────────────────────────────────────────────
 ► 0   0x555555763426 libafl_maps_next+326
   1   0x555555690831 libafl_qemu::qemu::usermode::QemuMappingsViewer::new::h801b422b998f9e44+241
   2   0x555555690831 libafl_qemu::qemu::usermode::QemuMappingsViewer::new::h801b422b998f9e44+241
   3   0x5555556721ba core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &mut F>::call_once::hbb3b3b29ada4d9a1+1546
   4   0x5555556721ba core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &mut F>::call_once::hbb3b3b29ada4d9a1+1546
   5   0x555555655f2a libafl::events::launcher::Launcher<CF,MT,SP>::launch_with_hooks::h6740f8b6fd95a8ab+3690
   6   0x5555556788b8 qemu_coverage::fuzzer::fuzz::h69d9a4d74fbf47fa+2728
   7   0x5555556788b8 qemu_coverage::fuzzer::fuzz::h69d9a4d74fbf47fa+2728
────────────────────────────────────────────────────────────────────────────────────────[ THREADS (2 TOTAL) ]─────────────────────────────────────────────────────────────────────────────────────────
  ► 5   "qemu_coverage" stopped: 0x555555763426 <libafl_maps_next+326> 
    6   "qemu_coverage" stopped: 0x7ffff7c8b799 <syscall+25> 
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

The issue is in libalf-qemu-bridge I think. e is NULL but I don't know if it is due to a bug or just that it should be checked for NULL as the comment says:

 // Should we check for NULL? Not sure, but if an inteval is in pageflags, then it should be in proc_maps too
        proc_map_interval_node = interval_tree_iter_first(proc_maps_root, min, min);
        e = container_of(proc_map_interval_node, MapInfo, itree);

The result I get when I do a for loop:

INFO: Mapping: 0x00007ffff637a000-0x00007ffff63a0000, /usr/lib/x86_64-linux-gnu/libc.so.6
INFO: Mapping: 0x00007ffff63a0000-0x00007ffff64f5000, /usr/lib/x86_64-linux-gnu/libc.so.6
INFO: Mapping: 0x00007ffff64f5000-0x00007ffff6548000, /usr/lib/x86_64-linux-gnu/libc.so.6
INFO: Mapping: 0x00007ffff6548000-0x00007ffff654c000, /usr/lib/x86_64-linux-gnu/libc.so.6
INFO: Mapping: 0x00007ffff654c000-0x00007ffff654e000, /usr/lib/x86_64-linux-gnu/libc.so.6
INFO: Mapping: 0x00007ffff654e000-0x00007ffff655b000, 
INFO: Mapping: 0x00007ffff6576000-0x00007ffff6577000, /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
INFO: Mapping: 0x00007ffff6577000-0x00007ffff659c000, /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
INFO: Mapping: 0x00007ffff659c000-0x00007ffff65a6000, /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
INFO: Mapping: 0x00007ffff65a6000-0x00007ffff65a8000, /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
INFO: Mapping: 0x00007ffff65a8000-0x00007ffff65aa000, /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
INFO: Mapping: 0x00007ffff65aa000-0x00007ffff65ab000, 
INFO: Mapping: 0x00007ffff65ab000-0x00007ffff6dab000, 
INFO: Mapping: 0x00007ffff6dfc000-0x00007ffff6dfe000, /home/celian/fuzzer/bin/test_lib
INFO: Mapping: 0x00007ffff6dfe000-0x00007ffff71f8000, /home/celian/fuzzer/bin/test_lib
INFO: Mapping: 0x00007ffff71f8000-0x00007ffff7266000, /home/celian/fuzzer/bin/test_lib
INFO: Mapping: 0x00007ffff7266000-0x00007ffff7267000, /home/celian/fuzzer/bin/test_lib
INFO: Mapping: 0x00007ffff7267000-0x00007ffff7269000, /home/celian/fuzzer/bin/test_lib
INFO: Mapping: 0x00007ffff7fb8000-0x00007ffff7fbf000, 
INFO: Mapping: 0x00007ffff7fbf000-0x00007ffff7fc0000, 

Thread 1 "fuzzer" received signal SIGSEGV, Segmentation fault.

The mapping I get from gdb at crash point is:

pwndbg> info proc mapping
process 14915
Mapped address spaces:

          Start Addr           End Addr       Size     Offset  Perms  objfile
       0x5e4c8000000      0x5e4ca000000  0x2000000        0x0  rw-p   
      0x555555554000     0x555555604000    0xb0000        0x0  r--p   /home/fuzzer
      0x555555604000     0x555555b1d000   0x519000    0xb0000  r-xp   /home/fuzzer
      0x555555b1d000     0x555555cd4000   0x1b7000   0x5c9000  r--p   /home/fuzzer
      0x555555cd4000     0x555555d3f000    0x6b000   0x780000  r--p   /home/fuzzer
      0x555555d3f000     0x555555d6c000    0x2d000   0x7eb000  rw-p   /home/fuzzer
      0x555555d6c000     0x55555605b000   0x2ef000        0x0  rw-p   [heap]
      0x55555605b000     0x555556159000    0xfe000        0x0  rw-p   [heap]
      0x7fffe8000000     0x7fffeffff000  0x7fff000        0x0  rwxp   
      0x7fffeffff000     0x7ffff0000000     0x1000        0x0  ---p   
      0x7ffff0000000     0x7ffff0021000    0x21000        0x0  rw-p   
      0x7ffff0021000     0x7ffff4000000  0x3fdf000        0x0  ---p   
      0x7ffff637a000     0x7ffff6548000   0x1ce000        0x0  r--p   /usr/lib/x86_64-linux-gnu/libc.so.6
      0x7ffff6548000     0x7ffff654c000     0x4000   0x1ce000  r--p   /usr/lib/x86_64-linux-gnu/libc.so.6
      0x7ffff654c000     0x7ffff654e000     0x2000   0x1d2000  rw-p   /usr/lib/x86_64-linux-gnu/libc.so.6
      0x7ffff654e000     0x7ffff655b000     0xd000        0x0  rw-p   
      0x7ffff6576000     0x7ffff65a6000    0x30000        0x0  r--p   /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
      0x7ffff65a6000     0x7ffff65a8000     0x2000    0x30000  r--p   /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
      0x7ffff65a8000     0x7ffff65aa000     0x2000    0x32000  rw-p   /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
      0x7ffff65aa000     0x7ffff65ab000     0x1000        0x0  ---p   
      0x7ffff65ab000     0x7ffff6dc4000   0x819000        0x0  rw-p   
      0x7ffff6dcd000     0x7ffff6dfc000    0x2f000        0x0  rw-p   
      0x7ffff6dfc000     0x7ffff7266000   0x46a000        0x0  r--p   /home/celian/bin/fuzzer/test_lib
      0x7ffff7266000     0x7ffff7267000     0x1000   0x469000  r--p   /home/celian/bin/fuzzer/test_lib
      0x7ffff7267000     0x7ffff7269000     0x2000   0x46a000  rw-p   /home/celian/bin/fuzzer/test_lib
      0x7ffff7269000     0x7ffff72ea000    0x81000        0x0  rw-p   
      0x7ffff72ea000     0x7ffff72eb000     0x1000        0x0  ---p   
      0x7ffff72eb000     0x7ffff7aee000   0x803000        0x0  rw-p   
      0x7ffff7aee000     0x7ffff7af0000     0x2000        0x0  r--p   /usr/lib/x86_64-linux-gnu/libpcre2-8.so.0.11.2
      0x7ffff7af0000     0x7ffff7b5b000    0x6b000     0x2000  r-xp   /usr/lib/x86_64-linux-gnu/libpcre2-8.so.0.11.2
      0x7ffff7b5b000     0x7ffff7b86000    0x2b000    0x6d000  r--p   /usr/lib/x86_64-linux-gnu/libpcre2-8.so.0.11.2
      0x7ffff7b86000     0x7ffff7b87000     0x1000    0x98000  r--p   /usr/lib/x86_64-linux-gnu/libpcre2-8.so.0.11.2
      0x7ffff7b87000     0x7ffff7b88000     0x1000    0x99000  rw-p   /usr/lib/x86_64-linux-gnu/libpcre2-8.so.0.11.2
      0x7ffff7b88000     0x7ffff7b8a000     0x2000        0x0  rw-p   
      0x7ffff7b8a000     0x7ffff7bb0000    0x26000        0x0  r--p   /usr/lib/x86_64-linux-gnu/libc.so.6
      0x7ffff7bb0000     0x7ffff7d05000   0x155000    0x26000  r-xp   /usr/lib/x86_64-linux-gnu/libc.so.6
      0x7ffff7d05000     0x7ffff7d58000    0x53000   0x17b000  r--p   /usr/lib/x86_64-linux-gnu/libc.so.6
      0x7ffff7d58000     0x7ffff7d5c000     0x4000   0x1ce000  r--p   /usr/lib/x86_64-linux-gnu/libc.so.6
      0x7ffff7d5c000     0x7ffff7d5e000     0x2000   0x1d2000  rw-p   /usr/lib/x86_64-linux-gnu/libc.so.6
      0x7ffff7d5e000     0x7ffff7d6b000     0xd000        0x0  rw-p   
      0x7ffff7d6b000     0x7ffff7d6e000     0x3000        0x0  r--p   /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
      0x7ffff7d6e000     0x7ffff7d85000    0x17000     0x3000  r-xp   /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
      0x7ffff7d85000     0x7ffff7d89000     0x4000    0x1a000  r--p   /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
      0x7ffff7d89000     0x7ffff7d8a000     0x1000    0x1d000  r--p   /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
      0x7ffff7d8a000     0x7ffff7d8b000     0x1000    0x1e000  rw-p   /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
      0x7ffff7d8b000     0x7ffff7d8c000     0x1000        0x0  r--p   /usr/lib/x86_64-linux-gnu/libgmodule-2.0.so.0.7400.6
      0x7ffff7d8c000     0x7ffff7d8e000     0x2000     0x1000  r-xp   /usr/lib/x86_64-linux-gnu/libgmodule-2.0.so.0.7400.6
      0x7ffff7d8e000     0x7ffff7d8f000     0x1000     0x3000  r--p   /usr/lib/x86_64-linux-gnu/libgmodule-2.0.so.0.7400.6
      0x7ffff7d8f000     0x7ffff7d90000     0x1000     0x3000  r--p   /usr/lib/x86_64-linux-gnu/libgmodule-2.0.so.0.7400.6
      0x7ffff7d90000     0x7ffff7d91000     0x1000     0x4000  rw-p   /usr/lib/x86_64-linux-gnu/libgmodule-2.0.so.0.7400.6
      0x7ffff7d91000     0x7ffff7dae000    0x1d000        0x0  r--p   /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7400.6
      0x7ffff7dae000     0x7ffff7e3b000    0x8d000    0x1d000  r-xp   /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7400.6
      0x7ffff7e3b000     0x7ffff7ec6000    0x8b000    0xaa000  r--p   /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7400.6
      0x7ffff7ec6000     0x7ffff7ec7000     0x1000   0x135000  r--p   /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7400.6
      0x7ffff7ec7000     0x7ffff7ec8000     0x1000   0x136000  rw-p   /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7400.6
      0x7ffff7ec8000     0x7ffff7ec9000     0x1000        0x0  rw-p   
      0x7ffff7ec9000     0x7ffff7ed9000    0x10000        0x0  r--p   /usr/lib/x86_64-linux-gnu/libm.so.6
      0x7ffff7ed9000     0x7ffff7f4c000    0x73000    0x10000  r-xp   /usr/lib/x86_64-linux-gnu/libm.so.6
      0x7ffff7f4c000     0x7ffff7fa6000    0x5a000    0x83000  r--p   /usr/lib/x86_64-linux-gnu/libm.so.6
      0x7ffff7fa6000     0x7ffff7fa7000     0x1000    0xdc000  r--p   /usr/lib/x86_64-linux-gnu/libm.so.6
      0x7ffff7fa7000     0x7ffff7fa8000     0x1000    0xdd000  rw-p   /usr/lib/x86_64-linux-gnu/libm.so.6
      0x7ffff7fb8000     0x7ffff7fbf000     0x7000        0x0  rw-p   
      0x7ffff7fbf000     0x7ffff7fc0000     0x1000        0x0  r--p   
      0x7ffff7fc0000     0x7ffff7fc1000     0x1000        0x0  ---p    <= CRASHES HERE ???
      0x7ffff7fc1000     0x7ffff7fc5000     0x4000        0x0  rw-p   
      0x7ffff7fc5000     0x7ffff7fc9000     0x4000        0x0  r--p   [vvar]
      0x7ffff7fc9000     0x7ffff7fcb000     0x2000        0x0  r-xp   [vdso]
      0x7ffff7fcb000     0x7ffff7fcc000     0x1000        0x0  r--p   /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
      0x7ffff7fcc000     0x7ffff7ff1000    0x25000     0x1000  r-xp   /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
      0x7ffff7ff1000     0x7ffff7ffb000     0xa000    0x26000  r--p   /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
      0x7ffff7ffb000     0x7ffff7ffd000     0x2000    0x30000  r--p   /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
      0x7ffff7ffd000     0x7ffff7fff000     0x2000    0x32000  rw-p   /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
      0x7ffffffdd000     0x7ffffffff000    0x22000        0x0  rw-p   [stack]

celi0n avatar Feb 20 '25 09:02 celi0n

can you run cat /proc/self/maps | grep vyscall? what do you see?

literally anything process is ok. i just want to check if you have vsyscall page

tokatoka avatar Feb 20 '25 13:02 tokatoka

if vsyscall is not there, then it's a problem. (idk if you omit the end of mappings, but if you didn't then vsyscall is apparently missing) I had the exact same problem as you.

You should compile your kernel again and enable vsyscall (just to make ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] appear) then it is fixed

tokatoka avatar Feb 20 '25 13:02 tokatoka

yeah rbx is pointing to 0xffffffffff600000. so 100% its vsyscall page missing 😄

tokatoka avatar Feb 20 '25 13:02 tokatoka

Thank you for the answer, yes vsyscall is off by default now. So there is no way to use these Libafl-qemu features with a recent OS @tokatoka ? I don't understand why the issue is my kernel and not this code that does not check for null value (or something else). Everything is working well except this qemu.mapping but I need the SnapshotModule and it is not possible for me to tell every user of my fuzzer to compile a specific kernel just for this...

celi0n avatar Feb 20 '25 14:02 celi0n

yes we should fix. @rmalmain

tokatoka avatar Feb 20 '25 15:02 tokatoka