# Certain inputs cause tight C-level recursion leading to process stack overflow

Overriding to_i on Object causes tight C-level recursion in mruby with minimal Ruby stack use, bypassing stack-overflow protection and segfaulting the interpreter.

- Payout: $10,000
- Severity: high
- Program: shopify-scripts
- Credited: dkasak
- Disclosed: 2017-03-14
- Write-up quality: 8/10
- Original: https://hackerone.com/reports/189633
- Library page: https://bugbountylibrary.com/r/h1%3A189633
- Tags: domain:oss impact:dos kind:bounty platform:hackerone sev:high tech:ruby technique:source-review vuln:dos vuln:memory-corruption vuln:sandbox-escape

**Target:** mruby interpreter / mruby-engine sandbox
**Root cause:** mruby uses to_i for implicit Integer conversion and recurses at C level (mrb_vm_run) without tracking C-level recursion depth, so Ruby-level stack overflow protection never triggers before the process stack is exhausted.
**Steps:**
1. Write `def to_i; '' * self; end` then call `to_i` in recursive_to_i.rb
2. Run `mruby recursive_to_i.rb` or `sandbox recursive_to_i.rb`
3. Observe segfault from process stack overflow
4. Alternate PoCs: `def nil.m; m a ensure m + a; end; nil.m` and `def a; Module.new do; a; end; end; a`
**How found:** Noticed that certain legal Ruby programs recurse at C level without eval while spending little Ruby stack, so the Ruby stack overflow exception never fires; measured stack consumption between recursive mrb_vm_run calls and derived a crash threshold formula.
**Exploitation:** Attacker submits a crafted Ruby script to the sandboxed mruby-engine; the tight C recursion consumes ~3200 bytes of process stack per mrb_vm_run call while using only ~80 bytes of Ruby stack, crashing the interpreter process (DoS).
**Insight:** When auditing sandboxed interpreters, look for implicit-conversion hooks (to_i, to_s, coerce) and ensure/block constructs that re-enter the VM at C level; measure per-frame C stack usage to see if Ruby-level depth limits can be bypassed.
