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

Use-after-free during cleanup #3425

Closed
clayton-shopify opened this Issue Feb 2, 2017 · 0 comments

Comments

Projects
None yet
1 participant
@clayton-shopify
Contributor

clayton-shopify commented Feb 2, 2017

If MRuby is built with clang's Address Sanitizer (CFLAGS=-fsanitize=address LDFLAGS=-fsanitize=address make) then a use-after-free bug can be observed when the following code is executed:

10000.times { [0].zip [0] }

The problem occurs during cleanup, while freeing a fiber:

mruby/src/gc.c

Lines 761 to 762 in 6420951

struct REnv *e = ci->env;
if (e && !is_dead(&mrb->gc, e) &&

That code tries to access the fiber's environment, but it was freed earlier in free_heap. If the fiber and the environment happen to belong to two different heap pages, then the heap memory containing the environment will have been freed by the time the fiber is freed, and ASAN detects this use-after-free.

This issue was reported by https://hackerone.com/fms

ASAN report:

==17932==ERROR: AddressSanitizer: heap-use-after-free on address 0x62f00008a400 at pc 0x00010e03027f bp 0x7fff51c4dad0 sp 0x7fff51c4dac8
READ of size 4 at 0x62f00008a400 thread T0
    #0 0x10e03027e in obj_free gc.c:762
    #1 0x10e02fd55 in free_heap gc.c:384
    #2 0x10e030a4c in mrb_gc_destroy gc.c:393
    #3 0x10e0ac76e in mrb_close state.c:253
    #4 0x10dfb48f3 in cleanup mruby.c:166
    #5 0x10dfb34c9 in main mruby.c:256
    #6 0x7fffb4357254 in start (libdyld.dylib+0x5254)

0x62f00008a400 is located 49152 bytes inside of 49200-byte region [0x62f00007e400,0x62f00008a430)
freed by thread T0 here:
    #0 0x10e353db9 in wrap_free (libclang_rt.asan_osx_dynamic.dylib+0x4adb9)
    #1 0x10e0aa5ab in mrb_default_allocf state.c:56
    #2 0x10e02f5f9 in mrb_free gc.c:268
    #3 0x10e02fd7b in free_heap gc.c:386
    #4 0x10e030a4c in mrb_gc_destroy gc.c:393
    #5 0x10e0ac76e in mrb_close state.c:253
    #6 0x10dfb48f3 in cleanup mruby.c:166
    #7 0x10dfb34c9 in main mruby.c:256
    #8 0x7fffb4357254 in start (libdyld.dylib+0x5254)

previously allocated by thread T0 here:
    #0 0x10e353f87 in wrap_realloc (libclang_rt.asan_osx_dynamic.dylib+0x4af87)
    #1 0x10e0aa5c5 in mrb_default_allocf state.c:60
    #2 0x10e02e328 in mrb_realloc_simple gc.c:201
    #3 0x10e02ea0e in mrb_realloc gc.c:215
    #4 0x10e02f483 in mrb_malloc gc.c:236
    #5 0x10e02f51d in mrb_calloc gc.c:254
    #6 0x10e02fac9 in add_heap gc.c:324
    #7 0x10e032c37 in mrb_obj_alloc gc.c:510
    #8 0x10e0998e3 in mrb_proc_new proc.c:22
    #9 0x10e099bcc in mrb_closure_new proc.c:69
    #10 0x10e13b6cc in mrb_vm_exec vm.c:2307
    #11 0x10e113ea9 in mrb_vm_run vm.c:794
    #12 0x10e1448d9 in mrb_top_run vm.c:2526
    #13 0x10e211a55 in mrb_load_exec parse.y:5755
    #14 0x10e212865 in mrb_load_file_cxt parse.y:5764
    #15 0x10dfb30ba in main mruby.c:232
    #16 0x7fffb4357254 in start (libdyld.dylib+0x5254)

SUMMARY: AddressSanitizer: heap-use-after-free gc.c:762 in obj_free
Shadow bytes around the buggy address:
  0x1c5e00011430: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x1c5e00011440: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x1c5e00011450: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x1c5e00011460: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x1c5e00011470: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x1c5e00011480:[fd]fd fd fd fd fd fa fa fa fa fa fa fa fa fa fa
  0x1c5e00011490: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c5e000114a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c5e000114b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c5e000114c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c5e000114d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
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
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  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
==17932==ABORTING
Abort trap: 6

@matz matz closed this in 8f52b88 Feb 4, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment