diff --git a/specs/threat-model.md b/specs/threat-model.md index 21bb5fa9..406018d4 100644 --- a/specs/threat-model.md +++ b/specs/threat-model.md @@ -280,7 +280,7 @@ max_ast_depth: 100, // Parser recursion (TM-DOS-022) | TM-DOS-054 | `glob --files` inherits ExtGlob blowup | `glob --files "+(a|aa)" /dir` dispatches to `glob_match` with same exponential cost as TM-DOS-031 | Same as TM-DOS-031 — `glob_match_impl` recursion-depth cap covers `glob --files` callers | **MITIGATED** | | TM-DOS-055 | `split` file count amplification | `split -l 1 bigfile` creates one output file per line; bounded by `max_file_count` FS limit | FS limits (TM-DOS-006) | **MITIGATED** | | TM-DOS-056 | `source` self-recursion stack overflow | Script that sources itself causes unbounded recursion; function depth limit doesn't apply to `source` | `source` increments the same call-depth counter as functions, so self- and mutual-recursion hit the configured `max_function_depth` and return a clean error rather than a SIGABRT | **MITIGATED** | -| TM-DOS-057 | `sleep` bypasses execution timeout | `sleep`, `(sleep N)`, `echo x \| sleep N`, `sleep N & wait`, `timeout N sleep N` all ignore `ExecutionLimits::timeout` | `Bash::exec_impl` wraps the whole execution in `tokio::time::timeout(limits.timeout, …)`, so subshell, pipeline, background+wait, and the `timeout` builtin all surface a timeout error within the configured budget | **MITIGATED** | +| TM-DOS-057 | `sleep` bypasses execution timeout | `sleep`, `(sleep N)`, `echo x \| sleep N`, `sleep N & wait`, `timeout N sleep N` all ignore `ExecutionLimits::timeout` | `Bash::exec_impl` wraps execution in `tokio::time::timeout(limits.timeout, …)` on non-WASM targets; WASM currently executes without that global timeout wrapper (`#[cfg(target_family = "wasm")]`) | **PARTIAL** | | TM-DOS-058 | Single-builtin unbounded output | `seq 1 1000000` produces 1M lines despite command limit; single builtin call generates unbounded output (see also #648) | `ExecutionLimits::max_stdout_bytes` and `max_stderr_bytes` truncate captured output (defaults set in `ExecutionLimits::new()`); see #648 | **MITIGATED** | | TM-DOS-059 | Parameter expansion replacement bomb | `${x//a/$(printf 'b%.0s' {1..1000})}` on large `x` amplifies output multiplicatively (10K × 1K = 10MB) | `max_total_variable_bytes` + `max_stdout_bytes` | **MITIGATED** | | TM-DOS-060 | Sparse array huge-index allocation | `arr[999999999]=x` could allocate ~1B empty slots if arrays are Vec-backed; negative indices could cause OOB | HashMap-based arrays; `max_array_entries` caps total entries | **MITIGATED** |