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

Heap use-after-free in mrb_yield_with_class #3500

Closed
clayton-shopify opened this Issue Mar 10, 2017 · 0 comments

Comments

Projects
None yet
1 participant
@clayton-shopify
Contributor

clayton-shopify commented Mar 10, 2017

The following input demonstrates a crash:

def a(n)
  if n > 0
    instance_exec(0) {}
    a(n-1)
  end
end

a(100)

ASAN report:

==50561==ERROR: AddressSanitizer: heap-use-after-free on address 0x6210000164b0 at pc 0x00010ca699eb bp 0x7fff5352dfa0 sp 0x7fff5352d760
READ of size 16 at 0x6210000164b0 thread T0
    #0 0x10ca699ea in __asan_memcpy (libclang_rt.asan_osx_dynamic.dylib+0x419ea)
    #1 0x10c81fcd9 in stack_copy (mruby+0x100157cd9)
    #2 0x10c82bfd2 in mrb_yield_with_class (mruby+0x100163fd2)
    #3 0x10c8c3fdd in mrb_obj_instance_exec (mruby+0x1001fbfdd)
    #4 0x10c837d34 in mrb_vm_exec (mruby+0x10016fd34)
    #5 0x10c82da19 in mrb_vm_run (mruby+0x100165a19)
    #6 0x10c85f299 in mrb_top_run (mruby+0x100197299)
    #7 0x10c92dd85 in mrb_load_exec (mruby+0x100265d85)
    #8 0x10c92eb95 in mrb_load_file_cxt (mruby+0x100266b95)
    #9 0x10c6c9ca6 in main mruby.c:227
    #10 0x7fffb4357254 in start (libdyld.dylib+0x5254)

0x6210000164b0 is located 4016 bytes inside of 4096-byte region [0x621000015500,0x621000016500)
freed by thread T0 here:
    #0 0x10ca72f87 in wrap_realloc (libclang_rt.asan_osx_dynamic.dylib+0x4af87)
    #1 0x10c7c2c75 in mrb_default_allocf (mruby+0x1000fac75)
    #2 0x10c744828 in mrb_realloc_simple gc.c:201
    #3 0x10c744f0e in mrb_realloc gc.c:215
    #4 0x10c85fd11 in stack_extend_alloc (mruby+0x100197d11)
    #5 0x10c825d47 in stack_extend (mruby+0x10015dd47)
    #6 0x10c82bd0d in mrb_yield_with_class (mruby+0x100163d0d)
    #7 0x10c8c3fdd in mrb_obj_instance_exec (mruby+0x1001fbfdd)
    #8 0x10c837d34 in mrb_vm_exec (mruby+0x10016fd34)
    #9 0x10c82da19 in mrb_vm_run (mruby+0x100165a19)
    #10 0x10c85f299 in mrb_top_run (mruby+0x100197299)
    #11 0x10c92dd85 in mrb_load_exec (mruby+0x100265d85)
    #12 0x10c92eb95 in mrb_load_file_cxt (mruby+0x100266b95)
    #13 0x10c6c9ca6 in main mruby.c:227
    #14 0x7fffb4357254 in start (libdyld.dylib+0x5254)

previously allocated by thread T0 here:
    #0 0x10ca72f87 in wrap_realloc (libclang_rt.asan_osx_dynamic.dylib+0x4af87)
    #1 0x10c7c2c75 in mrb_default_allocf (mruby+0x1000fac75)
    #2 0x10c744828 in mrb_realloc_simple gc.c:201
    #3 0x10c744f0e in mrb_realloc gc.c:215
    #4 0x10c85fd11 in stack_extend_alloc (mruby+0x100197d11)
    #5 0x10c825d47 in stack_extend (mruby+0x10015dd47)
    #6 0x10c838b77 in mrb_vm_exec (mruby+0x100170b77)
    #7 0x10c82da19 in mrb_vm_run (mruby+0x100165a19)
    #8 0x10c85f299 in mrb_top_run (mruby+0x100197299)
    #9 0x10c92dd85 in mrb_load_exec (mruby+0x100265d85)
    #10 0x10c92eb95 in mrb_load_file_cxt (mruby+0x100266b95)
    #11 0x10c6c9ca6 in main mruby.c:227
    #12 0x7fffb4357254 in start (libdyld.dylib+0x5254)

SUMMARY: AddressSanitizer: heap-use-after-free (libclang_rt.asan_osx_dynamic.dylib+0x419ea) in __asan_memcpy
Shadow bytes around the buggy address:
  0x1c4200002c40: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x1c4200002c50: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x1c4200002c60: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x1c4200002c70: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x1c4200002c80: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x1c4200002c90: fd fd fd fd fd fd[fd]fd fd fd fd fd fd fd fd fd
  0x1c4200002ca0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c4200002cb0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c4200002cc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c4200002cd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c4200002ce0: 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
==50561==ABORTING
Abort trap: 6

This appears to happen because the stack_extend call in mrb_yield_with_class (

mruby/src/vm.c

Line 689 in ff262f2

stack_extend(mrb, ci->nregs, argc+2);
) can cause the arguments in argv to be relocated. The old address of argv is then passed into stack_copy here:

mruby/src/vm.c

Line 694 in ff262f2

stack_copy(mrb->c->stack+1, argv, argc);

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

@matz matz closed this in 191ee25 Mar 13, 2017

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