Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Buffer Overflow in Capstone Next #1596

Open
daehee87 opened this issue Mar 6, 2020 · 0 comments
Open

Buffer Overflow in Capstone Next #1596

daehee87 opened this issue Mar 6, 2020 · 0 comments

Comments

@daehee87
Copy link

daehee87 commented Mar 6, 2020

Hi, I am reporting a bug in capstonenext PPCDisassembler engine found by libfuzzer.
you can reproduce the bug with the following testcase file I attached.
libfuzzer-capstone-globaloob-e06b654beea96c44cc2023698b5a97177940bf71.zip

you will get the following bug. (out-of-bound array read access)
daehee@skyfire:~/fuzzcoin/master/aiohttp-libfuzzer/oss-fuzz/build/out/capstone$ ./fuzz_disasmnext ~/fuzzcoin/bugs/libfuzzer-capstone-globaloob-e06b654beea96c44cc2023698b5a97177940bf71 
INFO: Seed: 604472281
INFO: Loaded 1 modules   (36397 inline 8-bit counters): 36397 [0x1311280, 0x131a0ad), 
INFO: Loaded 1 PC tables (36397 PCs): 36397 [0xf173b0,0xfa5680), 
./fuzz_disasmnext: Running 1 inputs 1 time(s) each.
Running: /home/daehee/fuzzcoin/bugs/libfuzzer-capstone-globaloob-e06b654beea96c44cc2023698b5a97177940bf71
=================================================================
==2835==ERROR: AddressSanitizer: global-buffer-overflow on address 0x0000009920d0 at pc 0x00000068473e bp 0x7fff20d31130 sp 0x7fff20d31128
READ of size 4 at 0x0000009920d0 thread T0
    #0 0x68473d in decodeRegisterClass /src/capstonenext/arch/PowerPC/PPCDisassembler.c:225:29
    #1 0x683e95 in DecodeCRRC0RegisterClass /src/capstonenext/arch/PowerPC/PPCDisassembler.c:238:9
    #2 0x68182d in decodeToMCInst_4 /src/capstonenext/arch/PowerPC/PPCGenDisassemblerTables.inc:6686:1
    #3 0x6805a2 in decodeInstruction_4 /src/capstonenext/arch/PowerPC/PPCGenDisassemblerTables.inc:6687:1
    #4 0x67fd20 in getInstruction /src/capstonenext/arch/PowerPC/PPCDisassembler.c:565:11
    #5 0x67f9f8 in PPC_getInstruction /src/capstonenext/arch/PowerPC/PPCDisassembler.c:582:24
    #6 0x552270 in cs_disasm /src/capstonenext/cs.c:891:7
    #7 0x55019d in LLVMFuzzerTestOneInput /src/capstonenext/suite/fuzz/fuzz_disasm.c:56:20
    #8 0x457fb4 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:563:15
    #9 0x443512 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:293:6
    #10 0x448e86 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:783:9
    #11 0x472362 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:19:10
    #12 0x7f6a9c897b96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310
    #13 0x41dd48 in _start (/home/daehee/fuzzcoin/master/aiohttp-libfuzzer/oss-fuzz/build/out/capstone/fuzz_disasmnext+0x41dd48)

0x0000009920d0 is located 16 bytes to the left of global variable 'GP0Regs' defined in '/src/capstonenext/arch/PowerPC/PPCDisassembler.c:158:23' (0x9920e0) of size 128
0x0000009920d0 is located 16 bytes to the right of global variable 'CRRegs' defined in '/src/capstonenext/arch/PowerPC/PPCDisassembler.c:38:23' (0x9920a0) of size 32
SUMMARY: AddressSanitizer: global-buffer-overflow /src/capstonenext/arch/PowerPC/PPCDisassembler.c:225:29 in decodeRegisterClass
Shadow bytes around the buggy address:
  0x00008012a3c0: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
  0x00008012a3d0: f9 f9 f9 f9 f9 f9 f9 f9 00 00 00 00 00 00 00 00
  0x00008012a3e0: 00 00 00 00 00 00 00 00 f9 f9 f9 f9 00 00 00 00
  0x00008012a3f0: 00 00 00 00 00 00 00 00 00 00 00 00 f9 f9 f9 f9
  0x00008012a400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x00008012a410: f9 f9 f9 f9 00 00 00 00 f9 f9[f9]f9 00 00 00 00
  0x00008012a420: 00 00 00 00 00 00 00 00 00 00 00 00 f9 f9 f9 f9
  0x00008012a430: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00008012a440: f9 f9 f9 f9 00 00 00 00 00 00 00 00 00 00 00 00
  0x00008012a450: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00008012a460: 00 00 00 00 f9 f9 f9 f9 f9 f9 f9 f9 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==2835==ABORTING

I checked the bug and looks like the reason is super simple.
the array bound check assertion is commented out (maybe you commented out for debug and forgot to restore).

static DecodeStatus decodeRegisterClass(MCInst *Inst, uint64_t RegNo,
                const unsigned *Regs)
{
        // assert(RegNo < N && "Invalid register number");
        MCOperand_CreateReg0(Inst, Regs[RegNo]);
        return MCDisassembler_Success;
}

In case this report gets credit, please add the following nicknames.
"fuzzcoin, zzoru, Jordy Zomer, Taesoo Kim"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant