-
Notifications
You must be signed in to change notification settings - Fork 3
plat 451
| Coordination | Value |
|---|---|
| State | fixed on main, not deployed; the root-owned slottmux frontend must be deployed with the matching release |
| Priority | P1 |
| Date | 2026-10-04 |
| Owner | security-sandbox |
PLAT-442 commit 892c86cfe documents that a launch script naming one slot
and a working folder naming another is refused. ExecConfig.SlotForLaunch
logs the mismatch and returns an empty string. slottmux.run interprets the
same empty string as an ordinary non-slot launch and calls passthrough.
That invokes the system tmux with the app account's identity/environment.
A mismatch therefore does not stop the launch; it removes the slot routing.
Landlock is a separate layer and does not make this OS identity equivalent.
Reviewed AgentWorks a04b393c9. The existing
TestSlotForLaunchFollowsTheScriptsRunFolder passes the row "script says A,
folder is B's tree: refused, not run as either" while asserting only that the
selector returns empty. Source trace: workspace/slots/config.go:161-163 →
workspace/cmd/slottmux/main_linux.go:328 → 344-345 → passthrough (:30).
The Muse branch also passes through for the same empty result.
Workspace slot tests passed on macOS. The Linux tmux launch itself was not executed during review, so this is a verified control-flow finding, not a live OS-account exploit demonstration. PLAT-449 supplies a reachable source of script/folder disagreement through mutable owner metadata.
-
workspace/slots:SlotForLaunchreturns(slot, error); a script/folder disagreement is a*SlotMismatchError(errors.Is(err, ErrSlotMismatch)), separate from "no slot requested" ("", nil).SlotForDiris a folder rule with no mismatch notion and is unchanged. -
workspace/cmd/slottmux: on a mismatch it prints[SLOT_EXPLICIT_MISMATCH] launch refused ...to stderr and exits 126 before anything is executed, ahead of the forget/Muse/passthrough/slot branches. The file is nowmain.go(no build tag) withpassthroughFn/asSlotFn/runAsSlotFnhooks so the decision is testable on macOS. App-account launches, hosts without slots and every other tmux command are unchanged. - Provider
e5790ce(internal/slotfs): when the application declares a user and a slot for a launch, the canary covers that user, and the host table says another slot, has none, or (no table) the name is not a slot name, the launch is refused withslotfs.ErrLaunchBlocked(*LaunchBlockedError) instead of falling back to the app account (or silently using the table's other slot). A declared app account, a user the canary does not cover, and a user named without a slot that the host does not hold one for keep today's "no slot".[SLOT_FALLBACK]logging for path-inferred slots is unchanged. Propagation:slotfs.CreateTemp,MkdirTemp,WrapCmd(all return the error),shelllaunch.CommandWithEnv/CommandWithScopedEnv(soCommandWithFinalEnvand every adapter that calls them),clisandbox.LandlockArgs, and the plain compatibility launch inclisandbox.PrepareCodexCommandScoped. - Tests:
TestSlotForLaunchFollowsTheScriptsRunFoldernow asserts the error (mismatch rows: A script/B tree, B script/A tree, A script/slot B state folder, A script/slot B run folder); slottmuxTestRunDecision...(hooks, runs everywhere) andTestBuiltFrontendRefusesAMismatchBeforeTmux(builds and executes the binary; Linux only, ran in a golang:1.26 Linux container with no tmux, so the app-account row proves it reached the exec of the system tmux); providerTestExplicitMismatchIsARefusalNotNoSlotand the end-to-end launch tests inshelllaunchandclisandbox. The 13-row identity table and the workspace table are unchanged and green.
- Deploy: the root-owned slottmux frontend (
workspace/cmd/slottmux) and the application/provider release (ae8e204->e5790cepinned inagent_go/go.mod) go together. An old frontend with a new provider is safe (the provider refuses first); a new frontend with an old provider still lets the provider fall back to the app account for a declared-but-unconfirmed slot. - Provider helpers that cannot return an error (
slotfs.SlotOf,IsSlotLaunch,Mode,TempDir, and the test-onlyclaudeInteractiveShellCommand/codexInteractiveShellCommandwrappers aroundshelllaunch.Command) still report "no slot" for a blocked launch; they are always preceded by the checked launch functions above, but a new launch path must callslotfs.CheckLaunchfirst. -
agent_gowas not rebuilt here (its replace points at the main checkouts); the provider change is additive API.
Auto-synced from docs/ on main. Edit there, not here.