googleprojectzero / SkCodecFuzzer

Fuzzing harness for testing proprietary image codecs supported by Skia on Android
Apache License 2.0
330 stars 77 forks source link

Segment fault is occurred #5

Closed KeuntaeShin closed 2 years ago

KeuntaeShin commented 4 years ago

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 4 years ago

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:

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.