Skip to content

fix(linux): preserve shell literals in systemd scopes - #102

Merged
senamakel merged 14 commits into
mainfrom
tinybox-systemd-literal-env
Oct 19, 2026
Merged

senamakel merged 14 commits into
mainfrom
tinybox-systemd-literal-env

Conversation

@senamakel

Copy link
Copy Markdown
Member

When namespace limits are enabled, systemd-run --scope can expand ${VAR} in the shell command argument before /bin/sh evaluates its quoting. This changes literal shell input and can silently corrupt otherwise valid commands.

The namespace backend now probes systemd-run --help through the same Host used for launch, with LC_ALL=C. It adds --expand-environment=no when the option is advertised. A successful legacy help response without the option keeps the old argv; failed probes refuse resource-limited execution rather than risk expansion. Upstream tagged source shows the option first in v254; v249 lacks it, while scope expansion was backward-compatible/off by default through v257. The live regression was exercised on systemd 259.

Validation:

  • Red before the fix: live ${cgroup_path} payload produced only a newline (1 failed).
  • Green after the fix: live command preserved ${cgroup_path} byte-for-byte (1 passed).
  • Probe/argv tests cover supported, legacy, and failed-probe behavior; failed probes never launch the workload.
  • cargo fmt --all -- --check
  • cargo clippy --all-targets --all-features -- -D warnings
  • cargo build --all-targets --all-features
  • cargo test --all-features
  • scripts/check-coverage.sh (90% per-file gate)

This fixes the command-argument corruption slice of tinybox#27; it does not claim that the broader native resource-enforcement work is complete. Related OpenHuman epic: tinyhumansai/openhuman#7328.

…cope

Adds a live test that runs a shell command referencing a dollar literal
inside a cgroup-limited namespace sandbox and asserts the text is passed
through unchanged. This guards against the scope setup expanding or
mangling dollar references in the executed command.

Auto-committed-on: dragonfly
The live systemd scope test now checks that a braced shell variable
reference survives as a literal instead of the bare form. This widens
coverage to the syntax that is more likely to be mangled by quoting.

Auto-committed-on: dragonfly
…tinybox-linux/src/sandbox/mod_t

Auto-committed-on: dragonfly
The `--expand-environment=no` argument is only understood by systemd v254
and newer, so passing it unconditionally broke sandbox limits on older
releases. The flag is now added only when `systemd-run --help` reports
support for it, cached in a `OnceLock` to avoid repeated probes.

Auto-committed-on: dragonfly
Widen cgroup_prefix and systemd_supports_expand_environment to pub(super) so tests can call them directly. The scope test now asserts the flag against the detected capability instead of assuming support, and a new test checks that the flag is emitted only when systemd supports it.

Auto-committed-on: dragonfly
The expand-environment feature probe now returns a Result so that a
failed systemd-run invocation surfaces as an unsupported-capability
error instead of silently disabling resource limits. The help-output
parsing was split into its own function so the legacy and failure paths
can be tested directly.

Auto-committed-on: dragonfly
The exec argument builder now takes the expand-environment capability as a
parameter instead of probing systemd itself. This removes the cached probe and
its unused imports from the module, leaving the pure argument builders free of
process and global state.

Auto-committed-on: dragonfly
The systemd-run feature probe now runs through the sandbox host
abstraction instead of spawning a process directly, so the check is
observable and testable. The probe result is passed into argument
construction, and a failed probe still refuses to launch the workload.

Auto-committed-on: dragonfly
Reformatted the argument parsing signature and several call sites and
test assertions so they fit within the line width limit. No behaviour
changed.

Auto-committed-on: dragonfly
The `--expand-environment` byte literal used when probing systemd help output is now a module-level constant so the flag name lives in one place. The detection logic itself is unchanged.

Auto-committed-on: dragonfly
The systemd environment flag probe tests now compare full Ok and Err
results rather than unwrapping, so a failure reports the actual value
instead of panicking. The tests also return Result to propagate errors.

Auto-committed-on: dragonfly
The systemd environment flag probe test no longer returns a Result since its assertions cannot fail with an error, so the return type and trailing Ok(()) were removed.

Auto-committed-on: dragonfly
@tinysweeper

tinysweeper Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

Tiny Sweeper review

Tiny Sweeper reviewed this change across 5 lane(s) and found 0 active actionable finding(s). Detailed lane evidence and any incomplete work are listed below.

State: Incomplete
Priority: none
Reviewed head: cdb6a0830222
Updated: 2026-10-18T23:30:18Z

Review snapshot

Change surface Files Review signal Count
Production 2 Active findings 0
Tests 2 Noted findings 0
Documentation 0 Resolved findings 0
Configuration 0 Pending checks/questions 10

Completeness: Incomplete
Test assessment: No supported feature-to-test mapping was available; this does not mean tests are absent or passed.

Features

None identified with supported citations.

Tests

No supported feature-to-test mapping was produced. Test execution is not inferred.

  • Unreviewed: tinysweeper/tests

Findings

No active actionable findings.

Could not review: crates/tinybox-linux/src/sandbox/args.rs, crates/tinybox-linux/src/sandbox/mod.rs, crates/tinybox-linux/src/sandbox/mod_tests.rs, crates/tinybox-linux/tests/live_namespaces.rs, tinysweeper/description, tinysweeper/tests

Before merge

  • Complete the critique review for crates/tinybox-linux/src/sandbox/args.rs, crates/tinybox-linux/src/sandbox/mod.rs, crates/tinybox-linux/src/sandbox/mod_tests.rs, crates/tinybox-linux/tests/live_namespaces.rs.
  • Complete the security review for crates/tinybox-linux/src/sandbox/args.rs, crates/tinybox-linux/src/sandbox/mod.rs, crates/tinybox-linux/src/sandbox/mod_tests.rs, crates/tinybox-linux/tests/live_namespaces.rs.
  • Complete the tests review for tinysweeper/tests.
  • Complete the description review for tinysweeper/description.

How this fits together

flowchart LR
  n0["NamespaceSandbox<br/>changed"]:::changed
  n1["RecordingHost<br/>changed"]:::changed
  n2["limits_wrap_the_sandbox_in_a_systemd_scope<br/>changed"]:::changed
  n3["live_a_memory_limit_is_actually_enforced<br/>changed"]:::changed
  n4["sandbox"]:::impacted
  n5["spec"]:::impacted
  n6["last"]:::impacted
  n7["spec"]:::impacted
  n8["enabled"]:::impacted
  n9["sandbox"]:::impacted
  n2 -->|calls| n5
  n2 -->|tests| n5
  n2 -->|calls| n6
  n2 -->|tests| n6
  n3 -->|calls| n7
  n3 -->|calls| n8
  n4 -->|uses| n0
  n4 -->|uses| n1
  n9 -->|uses| n0
  classDef changed fill:#0d4429,stroke:#238636,color:#e6edf3
  classDef impacted fill:#161b22,stroke:#6e7681,color:#c9d1d9
  classDef flagged fill:#5a1e02,stroke:#d93f0b,color:#ffffff
  classDef blocking fill:#67060c,stroke:#f85149,color:#ffffff
Loading
Agent review details

critique

  • Conclusion: Neutral
  • Scope reviewed: incomplete; unanswered: crates/tinybox-linux/src/sandbox/args.rs, crates/tinybox-linux/src/sandbox/mod.rs, crates/tinybox-linux/src/sandbox/mod_tests.rs, crates/tinybox-linux/tests/live_namespaces.rs
  • Lane summary: Reviewed 0 files; 0 findings. 4 files could not be reviewed: crates/tinybox-linux/src/sandbox/args.rs, crates/tinybox-linux/src/sandbox/mod.rs, crates/tinybox-linux/src/sandbox/mod_tests.rs, crates/tinybox-linux/tests/live_namespaces.rs.

security

  • Conclusion: Neutral
  • Scope reviewed: incomplete; unanswered: crates/tinybox-linux/src/sandbox/args.rs, crates/tinybox-linux/src/sandbox/mod.rs, crates/tinybox-linux/src/sandbox/mod_tests.rs, crates/tinybox-linux/tests/live_namespaces.rs
  • Lane summary: Reviewed 0 files; 0 findings. 4 files could not be reviewed: crates/tinybox-linux/src/sandbox/args.rs, crates/tinybox-linux/src/sandbox/mod.rs, crates/tinybox-linux/src/sandbox/mod_tests.rs, crates/tinybox-linux/tests/live_namespaces.rs.

tests

  • Conclusion: Neutral
  • Scope reviewed: incomplete; unanswered: tinysweeper/tests
  • Lane summary: No reviewer produced a usable response.

commits

  • Conclusion: Neutral
  • Scope reviewed: all assigned evidence
  • Lane summary: Nothing sensitive found in what this pull request commits.

description

  • Conclusion: Neutral
  • Scope reviewed: incomplete; unanswered: tinysweeper/description
  • Lane summary: No reviewer produced a usable response.
Evidence and run details
  • Models: ladder/vectors-oai3
  • Spend: $0.000054
  • Tokens: 0 input · 0 output · 0 cached · 416 embedding
Head State Pass summary
cdb6a0830222 incomplete 0 active finding(s), 0 resolved finding(s) (at 2026-10-18T23:30:18Z)

tinysweeper 0.1.2

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ⚠️ Failed 2026-10-18T23:29:58.365808Z cdb6a08 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@coderabbitai

coderabbitai Bot commented Oct 18, 2026

Copy link
Copy Markdown

Warning

Review limit reached

  • Run on-demand review

This review includes 4 billable files and costs up to $1.00.

Or wait 7 minutes for your next included review.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: d08dc027-2e5c-40e4-87e6-d00aba25770c
📥 Commits

Reviewing files that changed from the base of the PR and between 3cbd5d1 and cdb6a08.

📒 Files selected for processing: 4
  • crates/tinybox-linux/src/sandbox/args.rs
  • crates/tinybox-linux/src/sandbox/mod.rs
  • crates/tinybox-linux/src/sandbox/mod_tests.rs
  • crates/tinybox-linux/tests/live_namespaces.rs
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@tinysweeper tinysweeper Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

tinysweeper found nothing blocking, but could not review everything, so this is not an approval: crates/tinybox-linux/src/sandbox/args.rs, crates/tinybox-linux/src/sandbox/mod.rs, crates/tinybox-linux/src/sandbox/mod_tests.rs, crates/tinybox-linux/tests/live_namespaces.rs, tinysweeper/description, tinysweeper/tests.

$0.0001 · 0 in / 0 out · 416 embedded · ladder/vectors-oai3

@tinysweeper tinysweeper Bot added the priority: p3 Whenever. Cosmetic, a nicety, or a cleanup with no user visible effect. label Oct 18, 2026
@senamakel
senamakel merged commit 8bc0764 into main Oct 19, 2026
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

priority: p3 Whenever. Cosmetic, a nicety, or a cleanup with no user visible effect.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant