-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
IMPORTANT
- You have verified that the issue to be present in the current
dev
branch. - Please supply the command line options and relevant environment variables,
e.g., a copy-paste of the contents ofout/default/fuzzer_setup
.
Yes
Thank you for making AFL++ better!
Describe the bug
The program instrumented with ngram-16 crashes
To Reproduce
we can use libaom to reproduce
https://github.com/google/fuzzbench/tree/SBFT'23/benchmarks/libaom_av1_dec_fuzzer
- Clone the repo and make build dir
git clone https://aomedia.googlesource.com/aom
mkdir aom_build && cd aom_build
- Setup env vars
export CC=~/AFLplusplus/afl-cc
export CXX=~/AFLplusplus/afl-c++
export AFL_LLVM_INSTRUMENT=NGRAM-16
- Build
cmake ../aom -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS_RELEASE='-O3 -g' -DCMAKE_CXX_FLAGS_RELEASE='-O3 -g' -DCONFIG_PIC=1 -DCONFIG_LOWBITDEPTH=1 -DCONFIG_AV1_ENCODER=0 -DENABLE_EXAMPLES=0 -DENABLE_DOCS=0 -DENABLE_TESTS=0 -DCONFIG_SIZE_LIMIT=1 -DDECODE_HEIGHT_LIMIT=12288 -DDECODE_WIDTH_LIMIT=12288 -DAOM_EXTRA_C_FLAGS="" -DENABLE_TOOLS=0 -DAOM_EXTRA_CXX_FLAGS=""
make -j$(nproc)
$CXX $CXXFLAGS -std=c++11 -I../aom -I. -Wl,--start-group ../libAFLDriver.a ../aom/examples/av1_dec_fuzzer.cc -o ../av1_dec_fuzzer ./libaom.a -Wl,--end-group
- Prepare random input and run
toka@toka:~/AFLplusplus$ python3 -c "print('A' * 1024)" > input
toka@toka:~/AFLplusplus$ ./av1_dec_fuzzer ./input
Reading 1025 bytes from ./input
Segmentation fault
Expected behavior
The program should not crash
Screen output/Screenshots
If applicable, add copy-paste of the screen output or screenshot that shows the issue. Please ensure the output is in English and not in Chinese, Russian, German, etc.
Additional context
I debugged it a bit and found why the program crashes
This is the very instruction where the instrumented program crashes
pwndbg> r ./input
Starting program: /home/toka/AFLplusplus/av1_dec_fuzzer ./input
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Reading 1025 bytes from ./input
Program received signal SIGSEGV, Segmentation fault.
0x00005555557af4bb in aom_convolve_copy_avx2 (src=0x555555bf093c <wedge_mask_obl+34588> "@@@??><:5.%\033\022\v\006\004\002\001\001", src_stride=64, dst=0x555555bf4220 <wedge_mask_buf> "", dst_stride=8, w=8, h=8) at /home/toka/AFLplusplus/aom/aom_dsp/x86/aom_convolve_copy_avx2.c:34
34 if (w == 2) {
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
─────────────────────────────────────────────────────────────────────────[ REGISTERS / show-flags off / show-compact-regs off ]─────────────────────────────────────────────────────────────────────────
*RAX 0x7ffff7e9c750 ◂— 0x2a20046e4c3e5aaf
*RBX 0x555555bf093c (wedge_mask_obl+34588) ◂— 0x3a3c3e3f3f404040 ('@@@??><:')
*RCX 0x8
*RDX 0x555555bf4220 (wedge_mask_buf) ◂— 0x0
*RDI 0x555555bf093c (wedge_mask_obl+34588) ◂— 0x3a3c3e3f3f404040 ('@@@??><:')
*RSI 0x40
*R8 0x8
*R9 0x8
*R10 0x7ffff7811f10 ◂— 0xf001a00001b36
*R11 0x7ffff79aef40 (__memmove_evex_unaligned_erms) ◂— endbr64
*R12 0x555555bf4220 (wedge_mask_buf) ◂— 0x0
*R13 0x8
*R14 0x40
*R15 0x8
*RBP 0x8
*RSP 0x7fffffffd990 ◂— 0xfffffffffffffffc
*RIP 0x5555557af4bb (aom_convolve_copy_avx2+347) ◂— vmovdqa ymm0, ymmword ptr [rax]
──────────────────────────────────────────────────────────────────────────────────[ DISASM / x86-64 / set emulate on ]──────────────────────────────────────────────────────────────────────────────────
► 0x5555557af4bb <aom_convolve_copy_avx2+347> vmovdqa ymm0, ymmword ptr [rax]
0x5555557af4bf <aom_convolve_copy_avx2+351> vmovdqa xmm1, xmmword ptr [rax]
0x5555557af4c3 <aom_convolve_copy_avx2+355> vpxor xmm1, xmm1, xmmword ptr [rax + 0x10]
0x5555557af4c8 <aom_convolve_copy_avx2+360> vpshufd xmm2, xmm1, 0xee
The problem is rax = 0x7ffff7e9c750 is not a 32 bytes aligned value. However, vmovdqa moves ymm0 (256 bits = 32bytes) register into memory and it expects the destination memory location to be 32bytes = aligned.
This rax is AFLPrevLoc
, and it is setup here https://github.com/AFLplusplus/AFLplusplus/blob/stable/instrumentation/afl-llvm-pass.so.cc#L432
Unfortunately, calling AFLPrevLoc->setAlignment(Align(32))
does not work in this case. It does align the AFLPrevLoc for the ELF executable, however, when it is mapped to the TLS (the memory region where RAX 0x7ffff7e9c750
is mapped), then the alignment is broken.