Crash in libafl_maps_next when iterating over qemu.mapping
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:
- 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 - Do
just runon 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]
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
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
yeah rbx is pointing to 0xffffffffff600000. so 100% its vsyscall page missing 😄
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...
yes we should fix. @rmalmain