Skip to content

nemoclaw-start.sh: symlink validation is one-shot at boot — no runtime monitoring (TOCTOU) #1019

@latenighthackathon

Description

@latenighthackathon

Description

In scripts/nemoclaw-start.sh lines 272–283, symlinks in /sandbox/.openclaw/ are validated once at boot to ensure they point to expected targets in /sandbox/.openclaw-data/. However, after this check completes and the gateway starts (line 289), the symlinks are never re-verified.

This creates a TOCTOU (time-of-check-time-of-use) window: between the validation loop completing and the gateway reading files through those symlinks, an attacker with write access to the sandbox filesystem could replace a symlink to point to a different target.

What happens: Symlinks are validated at startup but never monitored again. The gateway trusts the symlinks for the entire lifetime of the container.

What should happen: Either make the symlinks immutable after validation (e.g., chattr +i or mount read-only), or re-verify them periodically / before each use. The existing Landlock policy marks /sandbox/.openclaw as read_only, which provides defense-in-depth, but is best_effort and may not be enforced on all kernels.

Reproduction Steps

  1. Review scripts/nemoclaw-start.sh lines 272–283:
    for entry in /sandbox/.openclaw/*; do
      [ -L "$entry" ] || continue
      name="$(basename "$entry")"
      target="$(readlink -f "$entry" 2>/dev/null || true)"
      expected="/sandbox/.openclaw-data/$name"
      if [ "$target" != "$expected" ]; then
        echo "[SECURITY] Symlink $entry points to unexpected target..."
        exit 1
      fi
    done
  2. Line 289: gateway starts — no further symlink checks occur
  3. If Landlock enforcement is disabled (kernel < 5.13, or best_effort fallback), the sandbox user can modify symlinks after boot:
    # Inside sandbox, after boot:
    rm /sandbox/.openclaw/workspace
    ln -s /sandbox/.openclaw-data/identity /sandbox/.openclaw/workspace
  4. The gateway now reads identity data when it expects workspace data

Environment

  • Code review of main branch (commit HEAD as of 2026-03-26)
  • Affected file: scripts/nemoclaw-start.sh lines 272–283
  • Landlock enforcement: best_effort per openclaw-sandbox.yaml

Logs

Validation occurs once (lines 272–283), then gateway starts (line 289):

# Validate symlinks (ONE-SHOT)
for entry in /sandbox/.openclaw/*; do
  [ -L "$entry" ] || continue
  # ... check ...
done

# Gateway starts — symlinks never re-checked
nohup gosu gateway "$OPENCLAW" gateway run >/tmp/gateway.log 2>&1 &

Landlock is best_effort (from openclaw-sandbox.yaml):

filesystem_policy:
  landlock: best_effort

On kernels without Landlock support, the read_only policy on /sandbox/.openclaw is not enforced, and the symlink swap is possible.

Checklist

  • I confirmed this bug is reproducible
  • I searched existing issues and this is not a duplicate

Metadata

Metadata

Assignees

No one assigned

    Labels

    securityPotential vulnerability, unsafe behavior, or access risk

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions