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 when built with MRB_WORD_BOXING #3396

Closed
clayton-shopify opened this Issue Jan 11, 2017 · 4 comments

Comments

Projects
None yet
2 participants
@clayton-shopify
Contributor

clayton-shopify commented Jan 11, 2017

When MRuby is built with MRB_WORD_BOXING, the following input to mirb demonstrates a crash:

a = [0.0]
loop { [0].to_s }

According to ASAN, at the time of the crash some memory that had originally been allocated for a float was freed by mrb_irep_free during a garbage collection:

Claytons-MacBook-Pro:mruby clayton$ bin/mirb
mirb - Embeddable Interactive Ruby Shell

> a = [0.0]
 => [0]
> loop { [0].to_s }
=================================================================
==43645==ERROR: AddressSanitizer: heap-use-after-free on address 0x603000005b60 at pc 0x0001034d7e84 bp 0x7fff5c7857b0 sp 0x7fff5c7857a8
READ of size 4 at 0x603000005b60 thread T0
    #0 0x1034d7e83 in mrb_type boxing_word.h:90
    #1 0x1034e16dd in gc_mark_children gc.c:663
    #2 0x1034e068f in gc_gray_mark gc.c:880
    #3 0x1034deb16 in incremental_marking_phase gc.c:975
    #4 0x1034ddd73 in incremental_gc gc.c:1079
    #5 0x1034da89c in incremental_gc_step gc.c:1114
    #6 0x1034d9aac in mrb_incremental_gc gc.c:1158
    #7 0x1034d9434 in mrb_obj_alloc gc.c:507
    #8 0x10352a333 in mrb_proc_new proc.c:22
    #9 0x10352a61c in mrb_closure_new proc.c:69
    #10 0x1035b1c03 in mrb_vm_exec vm.c:2277
    #11 0x10358e127 in mrb_vm_run vm.c:772
    #12 0x103473195 in main mirb.c:549
    #13 0x7fff8dfff254 in start (libdyld.dylib+0x5254)

0x603000005b60 is located 0 bytes inside of 32-byte region [0x603000005b60,0x603000005b80)
freed by thread T0 here:
    #0 0x1037aadb9 in wrap_free (libclang_rt.asan_osx_dynamic.dylib+0x4adb9)
    #1 0x10353724b in mrb_default_allocf state.c:56
    #2 0x1034d64d9 in mrb_free gc.c:268
    #3 0x10353798d in mrb_irep_free state.c:151
    #4 0x10353750c in mrb_irep_decref state.c:133
    #5 0x1034d75f6 in obj_free gc.c:794
    #6 0x1034df309 in incremental_sweep_phase gc.c:1022
    #7 0x1034dddbc in incremental_gc gc.c:1088
    #8 0x1034da89c in incremental_gc_step gc.c:1114
    #9 0x1034d9aac in mrb_incremental_gc gc.c:1158
    #10 0x1034d9434 in mrb_obj_alloc gc.c:507
    #11 0x10353b58e in str_new string.c:59
    #12 0x103540e26 in mrb_str_plus string.c:798
    #13 0x1035a506a in mrb_vm_exec vm.c:1845
    #14 0x10358e127 in mrb_vm_run vm.c:772
    #15 0x103473195 in main mirb.c:549
    #16 0x7fff8dfff254 in start (libdyld.dylib+0x5254)

previously allocated by thread T0 here:
    #0 0x1037aaf87 in wrap_realloc (libclang_rt.asan_osx_dynamic.dylib+0x4af87)
    #1 0x103537265 in mrb_default_allocf state.c:60
    #2 0x1034d5038 in mrb_realloc_simple gc.c:201
    #3 0x1034d571e in mrb_realloc gc.c:215
    #4 0x1034d6363 in mrb_malloc gc.c:236
    #5 0x1034cfd78 in mrb_word_boxing_float_pool etc.c:162
    #6 0x103639f7e in new_lit codegen.c:489
    #7 0x10362398a in codegen codegen.c:2223
    #8 0x103636340 in gen_values codegen.c:839
    #9 0x10361b007 in codegen codegen.c:1604
    #10 0x10361bb7a in codegen codegen.c:1657
    #11 0x103616aed in codegen codegen.c:1247
    #12 0x10362df26 in scope_body codegen.c:730
    #13 0x10361a60a in codegen codegen.c:1548
    #14 0x103613ef1 in mrb_generate_code codegen.c:2950
    #15 0x103472fba in main mirb.c:537
    #16 0x7fff8dfff254 in start (libdyld.dylib+0x5254)

SUMMARY: AddressSanitizer: heap-use-after-free boxing_word.h:90 in mrb_type
Shadow bytes around the buggy address:
  0x1c0600000b10: fa fa fd fd fd fd fa fa fd fd fd fd fa fa fd fd
  0x1c0600000b20: fd fa fa fa fd fd fd fd fa fa fd fd fd fd fa fa
  0x1c0600000b30: fd fd fd fd fa fa fd fd fd fa fa fa fd fd fd fd
  0x1c0600000b40: fa fa fd fd fd fd fa fa 00 00 02 fa fa fa fd fd
  0x1c0600000b50: fd fa fa fa fd fd fd fd fa fa fd fd fd fa fa fa
=>0x1c0600000b60: fd fd fd fd fa fa fd fd fd fd fa fa[fd]fd fd fd
  0x1c0600000b70: fa fa 00 00 04 fa fa fa 00 00 04 fa fa fa 00 00
  0x1c0600000b80: 04 fa fa fa 00 00 04 fa fa fa 00 00 03 fa fa fa
  0x1c0600000b90: 00 00 07 fa fa fa 00 00 00 01 fa fa 00 00 07 fa
  0x1c0600000ba0: fa fa 00 00 07 fa fa fa 00 00 07 fa fa fa 00 00
  0x1c0600000bb0: 07 fa fa fa 00 00 07 fa fa fa 00 00 07 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
==43645==ABORTING
Abort trap: 6
Claytons-MacBook-Pro:mruby clayton$ git diff
diff --git a/include/mrbconf.h b/include/mrbconf.h
index 4796919..930235b 100644
--- a/include/mrbconf.h
+++ b/include/mrbconf.h
@@ -41,7 +41,7 @@
 //#define MRB_ENDIAN_BIG

 /* represent mrb_value as a word (natural unit of data for the processor) */
-//#define MRB_WORD_BOXING
+#define MRB_WORD_BOXING

 /* string class to handle UTF-8 encoding */
 //#define MRB_UTF8_STRING

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

@clayton-shopify

This comment has been minimized.

Show comment
Hide comment
@clayton-shopify

clayton-shopify Jan 24, 2017

Contributor

A simpler way to demonstrate the crash:

a = 0.0
GC.start

Again, only works in mirb, and only when the two lines are executed separately (i.e. a = 0.0 ; GC.start doesn't cause a crash). Maybe something to do with the float pool (that is only used by MRB_WORD_BOXING) and the fact that mirb executes each input in a separate proc? It seems that the 0.0 gets garbage collected too soon.

Contributor

clayton-shopify commented Jan 24, 2017

A simpler way to demonstrate the crash:

a = 0.0
GC.start

Again, only works in mirb, and only when the two lines are executed separately (i.e. a = 0.0 ; GC.start doesn't cause a crash). Maybe something to do with the float pool (that is only used by MRB_WORD_BOXING) and the fact that mirb executes each input in a separate proc? It seems that the 0.0 gets garbage collected too soon.

matz added a commit that referenced this issue Jan 25, 2017

@matz

This comment has been minimized.

Show comment
Hide comment
@matz

matz Jan 25, 2017

Member

I couldn't reproduce the problem, but I changed the suspicious code.
I hope it works.

Member

matz commented Jan 25, 2017

I couldn't reproduce the problem, but I changed the suspicious code.
I hope it works.

@clayton-shopify

This comment has been minimized.

Show comment
Hide comment
@clayton-shopify

clayton-shopify Jan 25, 2017

Contributor

I did a couple quick tests just now, and the crash went away after your commits.

Contributor

clayton-shopify commented Jan 25, 2017

I did a couple quick tests just now, and the crash went away after your commits.

@matz

This comment has been minimized.

Show comment
Hide comment
@matz

matz Jan 25, 2017

Member

Reopen the issue when you see any problem.

Member

matz commented Jan 25, 2017

Reopen the issue when you see any problem.

@matz matz closed this Jan 25, 2017

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