lifecycle: chown per-agent socket dir to the agent user
Replace the 0777 fallback with a chown to the in-container agent's uid/gid (resolvable via agent_uid_gid since nspawn shares uids with the host). Keeps the dir at the default 0755 mode and avoids world-writability. Falls back to 0777 only when the agent uid is unavailable (first-spawn race before /etc/passwd is rendered).
This commit is contained in:
parent
30328a5184
commit
21213be1b6
1 changed files with 21 additions and 12 deletions
|
|
@ -1219,18 +1219,27 @@ fn set_nspawn_flags(
|
||||||
let socket_dir = crate::agent_sockets::agent_dir_for(agent_name);
|
let socket_dir = crate::agent_sockets::agent_dir_for(agent_name);
|
||||||
std::fs::create_dir_all(&socket_dir)
|
std::fs::create_dir_all(&socket_dir)
|
||||||
.with_context(|| format!("create {}", socket_dir.display()))?;
|
.with_context(|| format!("create {}", socket_dir.display()))?;
|
||||||
// 0777 so the in-container agent user (`sock`, `iris`, …) can
|
// chown to the in-container agent user so its harness can
|
||||||
// `bind(2)` the `web.sock` file here. `create_dir_all` lands
|
// `bind(2)` web.sock here. `create_dir_all` lands the dir at
|
||||||
// the dir at 0755 root:root; the harness runs as the non-root
|
// 0755 root:root and the harness runs as the non-root agent
|
||||||
// agent user inside the container and otherwise fails the
|
// user; without this chown the bind fails with EACCES, the
|
||||||
// bind with EACCES — silently, since web_ui::serve's spawn
|
// gateway's agent-sockets.json stays empty, and the agent
|
||||||
// drops its JoinHandle (the gateway then sees an empty
|
// looks unreachable. uid resolution can return None on the
|
||||||
// agent-sockets.json and the agent appears unreachable).
|
// very first spawn (container's /etc/passwd not yet rendered)
|
||||||
// Per-agent dir + per-agent bind-mount means no other
|
// — fall back to a permissive 0777 in that window so the
|
||||||
// container ever sees this path, so the wide mode is contained.
|
// first harness boot still binds. nspawn shares uids with the
|
||||||
use std::os::unix::fs::PermissionsExt;
|
// host (no PrivateUsers), so the in-container uid is the same
|
||||||
std::fs::set_permissions(&socket_dir, std::fs::Permissions::from_mode(0o777))
|
// uid we chown to here.
|
||||||
.with_context(|| format!("chmod 0777 {}", socket_dir.display()))?;
|
if let Some((uid, gid)) = agent_uid_gid(agent_name) {
|
||||||
|
std::os::unix::fs::chown(&socket_dir, Some(uid), Some(gid))
|
||||||
|
.with_context(|| format!("chown {} to {uid}:{gid}", socket_dir.display()))?;
|
||||||
|
} else {
|
||||||
|
use std::os::unix::fs::PermissionsExt;
|
||||||
|
std::fs::set_permissions(&socket_dir, std::fs::Permissions::from_mode(0o777))
|
||||||
|
.with_context(|| {
|
||||||
|
format!("chmod 0777 {} (uid lookup failed)", socket_dir.display())
|
||||||
|
})?;
|
||||||
|
}
|
||||||
let _ = write!(
|
let _ = write!(
|
||||||
binds,
|
binds,
|
||||||
" --bind={socket_dir}:{socket_dir}",
|
" --bind={socket_dir}:{socket_dir}",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue