googleprojectzero/SkCodecFuzzer

Segment fault is occurred

KeuntaeShin opened this issue · 1 comments

With ndk-r21b, skia for android 9 and capstone-4.0.2, i got successfully a binary named loader.

file loader
loader: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /git/SkCodecFuzzer/deps/android/system/bin/linker64, not stripped

When i execute ./run.sh which is included, "Invalid argument" against prctl is raised in my case, while another arm64 binary is working well (Also, It is working well after compilation without dynamic linker option README.md mentions) . Anything else i could do?

In case of Another arm64 binary:
qemu-aarch64 -strace ./f
20221 brk(NULL) = 0x0000000000569000
20221 brk(0x0000000000569fc8) = 0x0000000000569fc8
20221 uname(0x40007ffe88) = 0
20221 readlinkat(AT_FDCWD,"/proc/self/exe",0x00000040007fef80,4096) = 11
20221 brk(0x000000000058afc8) = 0x000000000058afc8
20221 brk(0x000000000058b000) = 0x000000000058b000
20221 faccessat(AT_FDCWD,"/etc/ld.so.nohwcap",F_OK,0) = -1 errno=2 (No such file or directory)
20221 fstat(1,0x00000040007ffde8) = 0
20221 write(1,0x57c030,18)Hello from ARM64!
= 18
20221 exit_group(0)

In case of running the loader compiled without the dynamic linker on device:
./loader
Error: missing required --input (-i) option

Usage: [LIBC_HOOKS_ENABLE=1] ./loader [OPTION]...

Required arguments:
-i, --input specify input file path for decoding

Optional arguments:
-o, --output save raw decoded RGBA image colors to specified output file
-l, --log_malloc log heap allocator activity to stderr (LIBC_HOOKS_ENABLE=1 needed)
-d, --default_malloc use the default system heap allocator
-h, --help display this help and exit

In case of running the loader compiled with the dynamic linker extracted from device:
./run.sh
19930 mmap(NULL,20480,PROT_NONE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0) = 0x0000004001032000
19930 prctl(1398164801,0,274894888960,20480,274894482102,0) = -1 errno=22 (Invalid argument)
19930 mprotect(0x0000004001033000,12288,PROT_READ|PROT_WRITE) = 0
19930 prctl(1398164801,0,274894893056,12288,274894482168,0) = -1 errno=22 (Invalid argument)
19930 set_tid_address(274894861656,0,274894893056,12288,274894482168,0) = 19930
19930 faccessat(-100,"/dev/urandom",R_OK,0) = 0
19930 futex(0x0000004001027fc8,FUTEX_PRIVATE_FLAG|FUTEX_WAKE,2147483647,NULL,NULL,0) = 0
19930 getrandom(274893454368,40,1,0,0,0) = 40
19930 mmap(NULL,1104,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0) = 0x0000004001037000
19930 prctl(1398164801,0,274894909440,1104,274894480656,0) = -1 errno=22 (Invalid argument)
19930 sched_getscheduler(0,0,8,3885048629,274894909568,274894861640) = 0
19930 mmap(NULL,20480,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0) = 0x0000004001038000
19930 mprotect(0x0000004001038000,4096,PROT_NONE) = 0
19930 sigaltstack(0x4000ed3ca0,(nil)) = 0
19930 prctl(1398164801,0,274894917632,16384,274894482179,0) = -1 errno=22 (Invalid argument)
19930 prctl(1398164801,0,274894913536,4096,274894482199,0) = -1 errno=22 (Invalid argument)
19930 mprotect(0x000000400101a000,49152,PROT_READ) = 0
19930 mprotect(0x000000400102a000,4096,PROT_READ) = 0
19930 mprotect(0x000000400102a000,4096,PROT_READ|PROT_WRITE) = 0
19930 mprotect(0x000000400102a000,4096,PROT_READ) = 0
19930 mmap(NULL,4096,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0) = 0x000000400103d000
19930 prctl(1398164801,0,274894934016,4096,274894482791,0) = -1 errno=22 (Invalid argument)
19930 mprotect(0x000000400103d000,4096,PROT_READ) = 0
19930 mprotect(0x000000400103d000,4096,PROT_READ|PROT_WRITE) = 0
19930 mprotect(0x000000400103d000,4096,PROT_READ) = 0
19930 mprotect(0x000000400103d000,4096,PROT_READ|PROT_WRITE) = 0
19930 mprotect(0x000000400103d000,4096,PROT_READ) = 0
19930 mprotect(0x000000400103d000,4096,PROT_READ|PROT_WRITE) = 0
19930 mprotect(0x000000400103d000,4096,PROT_READ) = 0
19930 mprotect(0x000000400103d000,4096,PROT_READ|PROT_WRITE) = 0
19930 mprotect(0x000000400103d000,4096,PROT_READ) = 0
19930 mprotect(0x000000400103d000,4096,PROT_READ|PROT_WRITE) = 0
19930 mprotect(0x000000400103d000,4096,PROT_READ) = 0
19930 mprotect(0x000000400103d000,4096,PROT_READ|PROT_WRITE) = 0
19930 mprotect(0x000000400103d000,4096,PROT_READ) = 0
19930 mprotect(0x000000400103d000,4096,PROT_READ|PROT_WRITE) = 0
19930 mprotect(0x000000400103d000,4096,PROT_READ) = 0
19930 mprotect(0x000000400103d000,4096,PROT_READ|PROT_WRITE) = 0
19930 mprotect(0x000000400103d000,4096,PROT_READ) = 0
19930 mprotect(0x000000400103d000,4096,PROT_READ|PROT_WRITE) = 0
19930 mprotect(0x000000400103d000,4096,PROT_READ) = 0
19930 mprotect(0x000000400103d000,4096,PROT_READ|PROT_WRITE) = 0
19930 mprotect(0x000000400103d000,4096,PROT_READ) = 0
19930 mprotect(0x000000400103d000,4096,PROT_READ|PROT_WRITE) = 0
19930 mprotect(0x000000400103d000,4096,PROT_READ) = 0
19930 mprotect(0x000000400103d000,4096,PROT_READ|PROT_WRITE) = 0
19930 mprotect(0x000000400103d000,4096,PROT_READ) = 0
19930 mmap(NULL,4096,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0) = 0x000000400103e000
19930 prctl(1398164801,0,274894938112,4096,274894470243,0) = -1 errno=22 (Invalid argument)
19930 mmap(NULL,24,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0) = 0x000000400103f000
19930 prctl(1398164801,0,274894942208,24,274894470409,0) = -1 errno=22 (Invalid argument)
19930 mmap(NULL,4096,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0) = 0x0000004001040000
19930 prctl(1398164801,0,274894946304,4096,274894470243,0) = -1 errno=22 (Invalid argument)
19930 mmap(NULL,24,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0) = 0x0000004001041000
19930 prctl(1398164801,0,274894950400,24,274894470409,0) = -1 errno=22 (Invalid argument)
19930 mmap(NULL,4096,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0) = 0x0000004001042000
19930 prctl(1398164801,0,274894954496,4096,274894434791,0) = -1 errno=22 (Invalid argument)
19930 mprotect(0x0000004001042000,4096,PROT_READ|PROT_WRITE) = 0
--- SIGSEGV {si_signo=SIGSEGV, si_code=1, si_addr=0x000000000000014e} ---
qemu: uncaught target signal 11 (Segmentation fault) - core dumped
./run.sh: line 19: 19930 Segmentation fault (core dumped) LD_LIBRARY_PATH=$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android:$ANDROID_PATH/lib64 qemu-aarch64 -strace ./loader "$@"
root@babo-400B4C-400B5C-200B4C-200B5C:/git/SkCodecFuzzer/source#

j00ru commented

I haven't encountered such a crash before. It might be related to the prctl(PR_SET_VMA) call made by the libclang_rt.ubsan_standalone-aarch64-android.so library, which is not supported outside of Android. I mentioned this in the SkCodecFuzzer README and the MMS Exploit Part 2 blog post. In my case, the problem only manifested with libraries extracted from Android 10, so I swapped the one .so file from an older Android 9 and that fixed it.

If this is the cause of the problem, you might try:

  • Starting the harness with a UBSAN_OPTIONS=decorate_proc_maps=0 environment variable,
  • Replacing the libclang_rt.ubsan_standalone-aarch64-android.so file with an older one that doesn't have the prctl call or,
  • Manually patching out the prctl call in the .so file you have.

If that doesn't help, I'd recommend attaching gdb to the harness to see exactly how/where the code is crashing. In my testing, the failed prctl call generated an abort signal, so the SIGSEGV you're seeing is quite strange.