Skip to content

fix(sandbox): preserve argv value boundaries - #713

Open
gouhongshen wants to merge 5 commits into
matrixorigin:moi-devfrom
gouhongshen:codex/fix-argv-boundaries-moid
Open

fix(sandbox): preserve argv value boundaries#713
gouhongshen wants to merge 5 commits into
matrixorigin:moi-devfrom
gouhongshen:codex/fix-argv-boundaries-moid

Conversation

@gouhongshen

@gouhongshen gouhongshen commented Sep 5, 2026

Copy link
Copy Markdown
Collaborator

What type of PR is this?

  • feat (new feature)
  • fix (bug fix)
  • docs (documentation)
  • style (formatting, no code change)
  • refactor (code change that neither fixes a bug nor adds a feature)
  • perf (performance improvement)
  • test (adding or updating tests)
  • chore (maintenance, tooling)
  • build / ci (build or CI changes)

Which issue(s) this PR fixes

N/A — synchronizes the latest argv-boundary corrections from main PR #697 after moi-dev PR #711 merged.

What this PR does / why we need it

The AST resolver advanced across some source words without proving they remain one runtime argv entry, and several GNU xargs/find execution semantics were modeled incorrectly.

This change:

  • centralizes single-argv consumption and fails closed when an unquoted dynamic option value or required operand may split;
  • applies the shared rule to nested shells, launcher grammars, fixed leading operands, and xargs value-bearing options;
  • models GNU xargs --eof[=END], --replace[=R], and --max-lines[=MAX-LINES] as optional inline-value forms;
  • treats xargs --show-limits as nonterminal and continues resolving its child; only --help and --version terminate dispatch;
  • rejects a dynamic find word that could become a predicate even when quoted, unless a literal ./, ../, or / prefix proves it is a path;
  • keeps quoted scalar option values valid single argv entries and does not restore the removed raw-text scanner.

Architecture and complexity delta

  • Canonical owner changed or extended: the existing astra-sandbox Bash AST executable resolver.
  • Existing implementations/callers searched: nested shell parsing, launcher parsing, fixed operands, xargs/find dispatch resolution, and public execute_bash validation.
  • Superseded code, states, tables, shims, and self-only tests removed: duplicated unchecked argv advancement is replaced by one shared consumer.
  • Net code/state/table delta: two existing Rust files; no protocol, persistence, schema, configuration, fallback, or compatibility layer.
  • Parallel implementations: none for the affected argv boundaries; all use the shared resolver.

Production wiring and verification

  • Public product entrypoint exercised: execute_bash validation.
  • Unhappy paths exercised: dynamic shell/launcher/xargs values, dynamic leading operands, GNU xargs optional-value and nonterminal modes, quoted dynamic find predicate injection, benign proven-path and child controls, and terminal modes.
  • Database verification: N/A; this is in-memory command validation.

Verification:

  • cargo fmt --check -- crates/astra-sandbox/src/bash_ast.rs crates/astra-tools/src/shell_ops.rs
  • cargo test -p astra-sandbox --lib — 153 passed
  • cargo test -p astra-tools validate_execute_bash --lib — 12 passed
  • cargo clippy -p astra-sandbox -p astra-tools --all-targets -- -D warnings
  • Linux CI also executes harmless GNU xargs --show-limits, bare --max-lines, and quoted dynamic find -print probes so the registry is checked against real utility dispatch semantics.

@gouhongshen
gouhongshen marked this pull request as ready for review September 5, 2026 22:25
@mergify

mergify Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Tick the box to add this pull request to the merge queue (same as @mergifyio queue).

  • Queue this pull request

@XuPeng-SH XuPeng-SH left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deep review of ed0a3ff against its moi-dev base 2de0e7c.

Requesting changes for one confirmed P1 regression: GNU xargs --show-limits is not a no-dispatch mode. Returning Safe at that flag prevents the resolver from inspecting a child command that xargs will execute.

Independent reproduction:

  • GNU findutils 4.9.0: printf 'data\n' | xargs --show-limits printf 'REVIEW713_CHILD_RAN:%s\n' prints the limits and then REVIEW713_CHILD_RAN:data.
  • Compiled the actual base and head bash_ast modules with the locked tree-sitter 0.24.7 / tree-sitter-bash 0.23.3 dependencies and the repository's CommandRisk enum.
  • For xargs --show-limits truncate -s 0 important.db, the base returns [DestructiveCommand("truncate")]; this head returns []. The same regression occurs with --no-run-if-empty after --show-limits; nonempty input still permits execution.
  • A benign printf child remains safe on both versions. The --help and --version controls correctly become safe on this head.

Only the harmless printf command was executed. Destructive command examples were passed as strings to the analyzer, never run. I traced the production path from analyze_command_risks_in_workspace into execute_bash validation: destructive-command rejection depends on this classification. This is a regression in that check, not a claim that OS isolation or every independent permission layer is bypassed.

The central single-argv consumer is otherwise a sensible improvement: the changed shell-option, launcher-option, and leading-operand paths reuse the existing may_split model; quoted scalar controls remain supported. The optional inline-only --eof/--replace distinction also preserves the intended child boundary. I reviewed both changed files and found no other independently substantiated blocker.

Validation: all 11 existing tests in the actual bash_ast module passed in an isolated Cargo harness, and git diff --check passed. I did not independently run the full astra-sandbox/astra-tools suites or workspace Clippy. The new terminal-mode tests cover --help and --version but omit --show-limits; add a rejecting analyzer/public-validator regression for a destructive child and a harmless real-xargs dispatch check before treating an option as terminal.

Comment thread crates/astra-sandbox/src/bash_ast.rs Outdated
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.

2 participants