Repository navigation
bug: sandbox bind-mount ownership breaks after host reboot (unpinned rootless userns mapping, no launch-time reconcile) #2336
Description
Summary
On the rootless Podman and Docker sandbox drivers, OpenShell attaches no user-namespace ID mapping to the container and mounts host state directories as plain (non-idmapped) rbinds. The host-side ownership of a bind-mounted state dir is therefore just the projection of a container-relative UID (e.g. sandbox) through whatever rootless subuid range the runtime happens to assign at create time. OpenShell never pins, persists, or reconciles that range. If the range shifts across a host reboot / runtime reconfig, previously-written inodes keep their old raw numbers and now resolve to unrelated host users — and OpenShell never repairs them.
Result: after a host reboot the sandbox's persisted state tree comes back owned by root / systemd-network / dnsmasq (group systemd-journal) with modes like drwx------ and -r--r--r--, and the sandbox process can no longer read/write its own state (readonly sqlite, EACCES). Reported downstream as NVIDIA/NemoClaw#6972 on a GB10 / Ubuntu 24.04 box: the agent could not recover the gateway and a rebuild's host-side backup could not read the mis-owned dirs.
Reproduction
- Launch a sandbox (rootless Podman driver) with a bind-mounted persistent state dir under
~/.../mounts/<sandbox>/. - Let the sandbox write state (owned, on the host, by the runtime's rootless subuid projection of the container
sandboxuser). - Reboot the host (or otherwise cause the rootless subuid base /
userns-remapto shift — daemon reconfig, storage//etc/subuidchange). - Re-launch / recover the sandbox. Observe on the host: the state tree is now owned by unrelated low-numbered users (
root,systemd-network,dnsmasq) with restrictive modes; inside the container the process hitsEACCES/attempt to write a readonly database.
Root cause (code)
Confirmed against current main:
- No userns / idmap on the container spec.
crates/openshell-driver-podman/src/container.rsContainerSpec(~L174–222) has nouserns/idmappingsfield and runs the supervisor asuser: "0:0"(~L908). The Docker driver sets noUsernsModeand also runs0:0(crates/openshell-driver-docker/src/lib.rs~L908). Mapping is fully delegated to the runtime default. - Bind mounts are plain rbinds, not idmapped. Podman:
crates/openshell-driver-podman/src/container.rs~L562–585 builds options["ro"|"rw","rbind"](+ optional SELinuxz/Z) — noidmap, noU. Docker:crates/openshell-driver-docker/src/lib.rs~L1794–1829 emitssource:target[:ro,z|Z]only. - No subuid base is pinned or persisted. The only subuid handling is
crates/openshell-driver-podman/src/driver.rscheck_subuid_range()(~L807, called ~L242), which is warn-only — it neither allocates, chooses, nor records a base. - Launch-time re-chown does not repair a persisted tree for these drivers.
crates/openshell-supervisor-process/src/process.rsprepare_filesystem()(~L1147): read-write paths are chowned only when newly created (~L1183–1194,prepare_read_write_pathreturns true only on create), and the recursive/sandboxre-chown (~L1201–1207 →chown_sandbox_home~L1105) runs only whenOPENSHELL_SANDBOX_UIDis set — which the rootless Podman/Docker path does not set (only K8s/VM drivers do). So an existing.hermestree with a shifted mapping is never re-owned. - No reboot/recreate reconcile exists anywhere for the bind-mounted tree.
Impact
- Permanent loss of access to sandbox state after a benign host reboot; user-visible as "impossible to recover the sandbox," data-loss on rebuild, and readonly-DB gateway failures.
- Security-adjacent: host ownership of sandbox-written files is non-deterministic and, on some runtimes, can collapse onto low host UIDs.
Proposed fix directions (for maintainer input)
- Durable / deterministic (preferred, architectural): attach an idmapped mount to the host state binds, or pass explicit deterministic
--uidmap/--gidmapto the container so the host-side ownership of the bind-mounted tree is stable and independent of the runtime's default rootless allocation across reboots. This pins the mapping OpenShell currently leaves implicit. - Mitigation (contained, self-healing at launch): extend the existing
prepare_filesystemre-chown so the sandbox state tree is reconciled to the configured sandbox identity on every launch for the Podman/Docker drivers too (not only whenOPENSHELL_SANDBOX_UIDis injected). This makes a mis-owned tree readable again under the current mapping without changing the mapping model. It heals the symptom each start but does not pin the mapping. - Make
check_subuid_range()fail-closed (or emit a clearer remediation) when the range is missing/ambiguous rather than warn-only.
Related: #1909 (rootless Podman UID-mapping issues on Fedora 44) touches adjacent territory but is a distinct scenario.
I'm happy to open a PR for the contained mitigation (#2) if that direction is acceptable, and defer the idmapped-mount design (#1) to maintainers.
Filed while triaging NVIDIA/NemoClaw#6972; root cause traced into OpenShell.
Activity
TonyLuo-NV commentedon Jul 17, 2026
Draft fix up for the contained mitigation (opt-in launch-time ownership reconcile): #2338. It's deliberately default-off so the existing create-only chown contract is unchanged; the durable fix (idmapped mounts / pinned uid/gid map) is left for maintainer direction as noted above. Downstream context: NVIDIA/NemoClaw#6972.
fix(supervisor): opt-in reconcile of drifted sandbox state ownership
TonyLuo-NV commentedon Aug 3, 2026
Status ping: the proposed mitigation in #2338 is rebased onto current
main, conflict-free, and green (tests + fmt + clippy; mirroredBranch Checkspassed). It's been open ~2 weeks without review and the stale bot has already flagged it once.The blocking question is a design call, not code: should the default-off
OPENSHELL_RECONCILE_SANDBOX_OWNERSHIPreconcile land as a stop-gap, or should this wait for the durable fix (idmapped mounts / pinned uid-gid map) described above? Either answer is fine — I'll close #2338 if the durable fix is preferred. Downstream users are currently hitting permanent state-access loss after a benign host reboot (NVIDIA/NemoClaw#6972).fix(supervisor): opt-in reconcile of drifted sandbox state ownership
krishicks commentedon Aug 14, 2026
github-actions commentedon Aug 29, 2026
This issue has had no activity for 14 days and is now marked stale. It may be closed in 7 days if there is no further activity. Comment or remove the state:stale label to keep it open.
github-actions commentedon Oct 13, 2026
Closing this issue after 14 days with no activity since it was marked stale. Reopen it if the work is still relevant.