# Broken handling of maximum number of method call arguments leads to segfault

mruby codegen mishandles exactly 127 method-call arguments, leaving first arg as fixnum instead of array, causing null-pointer deref and segfault in mruby and MRI.

- Payout: $10,000
- Severity: high
- Program: shopify-scripts
- Credited: dkasak
- Disclosed: 2016-12-21
- Write-up quality: 7/10
- Original: https://hackerone.com/reports/182484
- Library page: https://bugbountylibrary.com/r/h1%3A182484
- Tags: domain:oss impact:dos kind:bounty platform:hackerone sev:high tech:ruby technique:source-review vuln:dos vuln:memory-corruption

**Target:** mruby compiler codegen (gen_values) / mruby_engine array.c
**Root cause:** In gen_values, when exactly 127 args are present, n reaches CALL_MAXARGS only after t becomes null, so the loop exits before the special-case array wrapping runs; downstream code treats the first fixnum arg as an array and dereferences a null pointer.
**Steps:**
1. Write crash.rb calling `x` with exactly 127 zero arguments
2. Run `mruby crash.rb` or `sandbox crash.rb`
3. Observe segfault at array.c:473 in ARY_SHARED_P(a) with a==NULL
4. Confirm >127 args instead raise ArgumentError 'wrong number of arguments (-1 for 0)'
**How found:** Reading codegen.c gen_values while reasoning about CALL_MAXARGS handling; noticed the special-case check for array splat/overflow only triggers inside the loop, and that with exactly 127 args the loop exits via t=t->cdr becoming null before the check, then traced the resulting null deref to array.c ARY_SHARED_P.
**Exploitation:** Attacker submits a Shopify Script containing a method call with exactly 127 arguments; the sandboxed mruby interpreter segfaults, crashing the process (DoS).
**Insight:** Off-by-one boundary bugs in compiler argument-count handling: test exactly the sentinel value (CALL_MAXARGS) rather than just above/below it, since the special-case branch can be skipped precisely at the boundary when the AST list terminates.
