vnmakarov / mir

A lightweight JIT compiler based on MIR (Medium Internal Representation) and C11 JIT compiler and interpreter based on MIR
MIT License
2.24k stars 145 forks source link

heap-buffer-overflow in `VARR_token_tpush` and `VARR_token_tpop` #366

Open clesmian opened 11 months ago

clesmian commented 11 months ago

When executing c2m on poc.txt, a segfault occurs

POC

#define _00i0d00(E,X)X
_00i0d00(,()
#define _00i0d00(E,X)0)
_00i0d00(,)

ASAN Output

poc:2:1: warning -- different macro redefinition of _00i0d00
poc:1:9: warning -- previous definition of _00i0d00
=================================================================
==2537102==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x62900000f1f8 at pc 0x564864fb5680 bp 0x7f57afcfe0b0 sp 0x7f57afcfe0a0
WRITE of size 8 at 0x62900000f1f8 thread T1
    #0 0x564864fb567f in VARR_token_tpush c2mir/c2mir.c:103
    #1 0x564864fb567f in out_token c2mir/c2mir.c:2885
    #2 0x56486502b42a in processing c2mir/c2mir.c:3670
    #3 0x56486507e533 in pre c2mir/c2mir.c:3801
    #4 0x56486507e533 in c2mir_compile c2mir/c2mir.c:13468
    #5 0x564865081d6a in compile c2mir/c2mir-driver.c:498
    #6 0x7f57b32c0608 in start_thread /build/glibc-SzIz7B/glibc-2.31/nptl/pthread_create.c:477
    #7 0x7f57b31e5132 in __clone (/lib/x86_64-linux-gnu/libc.so.6+0x11f132)

0x62900000f1f8 is located 8 bytes to the left of 16384-byte region [0x62900000f200,0x629000013200)
allocated by thread T1 here:
    #0 0x7f57b353d808 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:144
    #1 0x564864ff7056 in VARR_token_tcreate c2mir/c2mir.c:103
    #2 0x564864ff7056 in pre_init c2mir/c2mir.c:2149

Thread T1 created by T0 here:
    #0 0x7f57b346a815 in __interceptor_pthread_create ../../../../src/libsanitizer/asan/asan_interceptors.cc:208
    #1 0x564864f966f8 in init_compilers c2mir/c2mir-driver.c:540
    #2 0x564864f966f8 in main c2mir/c2mir-driver.c:656

SUMMARY: AddressSanitizer: heap-buffer-overflow c2mir/c2mir.c:103 in VARR_token_tpush
Shadow bytes around the buggy address:
  0x0c527fff9de0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c527fff9df0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c527fff9e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c527fff9e10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c527fff9e20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c527fff9e30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa[fa]
  0x0c527fff9e40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c527fff9e50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c527fff9e60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c527fff9e70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c527fff9e80: 00 00 00 00 00 00 00 00 00 00 00 00 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
==2537102==ABORTING

Found while fuzzing https://github.com/vnmakarov/mir/commit/d51b45f6c76d2ca03a5b2e1968c195b867eaed30, verified with https://github.com/vnmakarov/mir/commit/cf3c9c106afdda59c402bdd40e61241aa20a755d

clesmian commented 11 months ago

Please excuse the issue spam, I found it easier to keep track of the stuff I found, while fuzzing in different issues. If you find that these issues are not relevant due to the state of the project, feel free to say so

clesmian commented 11 months ago

The following file leads to a heap-buffer-overflow in VARR_macro_call_tpop

POC

#define _00i0dN0(E,X)0##X
#define _00i0d00 _00
_00i0dN0(,0
#define _00)_00i0d00
_00

ASAN Output

=================================================================
==3938138==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6210000118f8 at pc 0x5602f325b098 bp 0x7fa756cfe100 sp 0x7fa756cfe0f0
READ of size 8 at 0x6210000118f8 thread T1
    #0 0x5602f325b097 in VARR_macro_call_tpop c2mir/c2mir.c:1961
    #1 0x5602f325b097 in pop_macro_call c2mir/c2mir.c:2552
    #2 0x5602f325b097 in processing c2mir/c2mir.c:3590
    #3 0x5602f32a6533 in pre c2mir/c2mir.c:3801
    #4 0x5602f32a6533 in c2mir_compile c2mir/c2mir.c:13468
    #5 0x5602f32a9d6a in compile c2mir/c2mir-driver.c:498
    #6 0x7fa75a329608 in start_thread /build/glibc-SzIz7B/glibc-2.31/nptl/pthread_create.c:477
    #7 0x7fa75a24e132 in __clone (/lib/x86_64-linux-gnu/libc.so.6+0x11f132)

0x6210000118f8 is located 8 bytes to the left of 4096-byte region [0x621000011900,0x621000012900)
allocated by thread T1 here:
    #0 0x7fa75a5a6808 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:144
    #1 0x5602f32218e4 in VARR_macro_call_tcreate c2mir/c2mir.c:1961
    #2 0x5602f32218e4 in pre_init c2mir/c2mir.c:2152

Thread T1 created by T0 here:
    #0 0x7fa75a4d3815 in __interceptor_pthread_create ../../../../src/libsanitizer/asan/asan_interceptors.cc:208
    #1 0x5602f31be6f8 in init_compilers c2mir/c2mir-driver.c:540
    #2 0x5602f31be6f8 in main c2mir/c2mir-driver.c:656

SUMMARY: AddressSanitizer: heap-buffer-overflow c2mir/c2mir.c:1961 in VARR_macro_call_tpop
Shadow bytes around the buggy address:
  0x0c427fffa2c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c427fffa2d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c427fffa2e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c427fffa2f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c427fffa300: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c427fffa310: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa[fa]
  0x0c427fffa320: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c427fffa330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c427fffa340: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c427fffa350: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c427fffa360: 00 00 00 00 00 00 00 00 00 00 00 00 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
==3938138==ABORTING
vnmakarov commented 11 months ago

This was fixed by https://github.com/vnmakarov/mir/commit/9f20cf357c9c9fba8ef01a0795c2b9e2661f94a9