Summary
atelet builds host filesystem paths from several Run/Restore/Checkpoint request fields without validating them. Since atelet listens on an insecure hostPort (bypassing the API server), any reachable caller can smuggle a path separator or .. through these fields and make atelet read / RemoveAll / write outside the intended actor tree, or collide bundles.
Unvalidated fields
-
target_ateom_uid → /run/netns/ateom:<uid> and .../ateoms/<uid>/ateom.sock. Separators or .. redirect the netns/socket paths.
internal/ateompath/ateompath.go:45,56 (AteomSocketPath, AteomNetNSPath)
-
spec.containers[].name → OCIBundlePath(ns, tmpl, id, name), where atelet runs os.RemoveAll / os.MkdirAll / writes config.json. / or .. escapes the bundle dir.
pkg/api/v1alpha1/actortemplate_types.go:43 (no constraint on Container.Name)
internal/ateompath/ateompath.go:96 (OCIBundlePath)
-
Reserved / duplicate container names — prepareOCIBundles builds the pause bundle and app bundles (keyed by name) concurrently. An app container named pause writes the same path as the sandbox-infra container (nondeterministic race / corruption); two app containers with the same name clobber each other.
cmd/atelet/main.go (prepareOCIBundles), cmd/ateom-gvisor/main.go:459 (hard-coded pause)
Suggested fix
Validate all path-constructing inputs at the three RPC boundaries before any path is built:
target_ateom_uid and each container name as DNS-1123 labels (UUIDs and normal names qualify; separators/.. rejected).
- Reject the reserved name
pause and duplicate container names.
- Optional defense-in-depth:
+kubebuilder:validation:Pattern on Container.Name.
Note: PR #184 already validates namespace/template/actor-id this way; this extends the same mechanism to the remaining path-constructing fields.
Summary
atelet builds host filesystem paths from several
Run/Restore/Checkpointrequest fields without validating them. Since atelet listens on an insecure hostPort (bypassing the API server), any reachable caller can smuggle a path separator or..through these fields and make atelet read /RemoveAll/ write outside the intended actor tree, or collide bundles.Unvalidated fields
target_ateom_uid→/run/netns/ateom:<uid>and.../ateoms/<uid>/ateom.sock. Separators or..redirect the netns/socket paths.internal/ateompath/ateompath.go:45,56(AteomSocketPath,AteomNetNSPath)spec.containers[].name→OCIBundlePath(ns, tmpl, id, name), where atelet runsos.RemoveAll/os.MkdirAll/ writesconfig.json./or..escapes the bundle dir.pkg/api/v1alpha1/actortemplate_types.go:43(no constraint onContainer.Name)internal/ateompath/ateompath.go:96(OCIBundlePath)Reserved / duplicate container names —
prepareOCIBundlesbuilds thepausebundle and app bundles (keyed by name) concurrently. An app container namedpausewrites the same path as the sandbox-infra container (nondeterministic race / corruption); two app containers with the same name clobber each other.cmd/atelet/main.go(prepareOCIBundles),cmd/ateom-gvisor/main.go:459(hard-codedpause)Suggested fix
Validate all path-constructing inputs at the three RPC boundaries before any path is built:
target_ateom_uidand each container name as DNS-1123 labels (UUIDs and normal names qualify; separators/..rejected).pauseand duplicate container names.+kubebuilder:validation:PatternonContainer.Name.