Skip to content

fix(interpreter): add max_subst_depth limit to prevent OOM from nested $()#1107

Merged
chaliy merged 1 commit intomainfrom
fix/issue-1088-subst-oom
Apr 6, 2026
Merged

fix(interpreter): add max_subst_depth limit to prevent OOM from nested $()#1107
chaliy merged 1 commit intomainfrom
fix/issue-1088-subst-oom

Conversation

@chaliy
Copy link
Copy Markdown
Contributor

@chaliy chaliy commented Apr 6, 2026

Summary

  • Add dedicated max_subst_depth limit (default 32) to ExecutionLimits to prevent OOM from deeply nested command substitutions
  • Each $(...) level clones the full interpreter state — memory grows as depth × state_size
  • Previously shared max_function_depth counter (default 100) was too generous for expensive state-cloning operations
  • Harden arithmetic_fuzz target with tighter resource limits

Changes

  • limits.rs: new max_subst_depth field, subst_depth counter, push_subst/pop_subst methods, MaxSubstDepth error variant
  • interpreter/mod.rs: switch both command substitution paths from push_function/pop_function to push_subst/pop_subst
  • arithmetic_fuzz.rs: add max_function_depth(10), max_subst_depth(5), max_stdout_bytes(4096), max_stderr_bytes(4096)
  • blackbox_security_tests.rs: set max_subst_depth in tight_bash() and dos_bash() helpers
  • New subst_depth_limit_tests.rs: 3 regression tests including decoded fuzz crash input
  • specs/006-threat-model.md: add TM-DOS-088

Test plan

  • cargo test --test subst_depth_limit_tests — 3 new tests pass
  • cargo test --test blackbox_security_tests — 78 tests pass (previously stack-overflowed)
  • cargo test --all-features -- --skip ssh_supabase — all pass
  • cargo clippy --all-targets --all-features -- -D warnings — clean
  • cargo fmt --check — clean

Closes #1088

…d $()

Each command substitution level clones the full interpreter state
(variables, arrays, functions, etc.), so memory grows as depth × state_size.
Previously, command substitution shared the function depth counter
(max_function_depth=100), which allowed deep nesting to exhaust memory.

Add a dedicated max_subst_depth limit (default 32) with its own counter.
This bounds memory consumption from nested $(...) chains while keeping
the function depth limit independent.

- Add max_subst_depth field to ExecutionLimits (default 32)
- Add subst_depth counter to ExecutionCounters with push_subst/pop_subst
- Switch CommandSubstitution handler to use subst depth tracking
- Harden arithmetic_fuzz target with tighter limits
- Update blackbox_security_tests to set max_subst_depth
- Add regression tests with fuzz crash input from #1088
- Add TM-DOS-088 to threat model

Closes #1088
@chaliy chaliy merged commit 6b9c38c into main Apr 6, 2026
22 of 33 checks passed
@chaliy chaliy deleted the fix/issue-1088-subst-oom branch April 6, 2026 10:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fuzz: arithmetic_fuzz OOM — unbounded memory in command substitution

1 participant