allow erofs as the idmapped store filesystem
nspawn idmaps the store on erofs, which the VM test's store uses; the allowlist from the store check refused it and failed the namespaced-agent subtest in vm-nightly #7084. vm-nightly #7030 ran the same agent on the same erofs store green. The magic is EROFS_SUPER_MAGIC_V1 from the kernel's linux/magic.h; libc has no constant. Refs #5888
This commit is contained in:
parent
47ec47e25b
commit
a71e7cea75
2 changed files with 15 additions and 11 deletions
|
|
@ -488,13 +488,14 @@ hive-c0re can't read, or none, leaves the agent as it is.
|
||||||
user. hive-priv mounts the agent's `state/`, `harness/`, `work/` and
|
user. hive-priv mounts the agent's `state/`, `harness/`, `work/` and
|
||||||
`claude/` dirs and its socket dir with `owneridmap`, and every other bind too
|
`claude/` dirs and its socket dir with `owneridmap`, and every other bind too
|
||||||
(config, `/knowledge`, the runtime dir), whose owner shows as root inside.
|
(config, `/knowledge`, the runtime dir), whose owner shows as root inside.
|
||||||
- **`/nix/store` has to be on ext4, btrfs or xfs.** nspawn mounts the store
|
- **`/nix/store` has to be on ext4, btrfs, xfs or erofs.** nspawn mounts the
|
||||||
into a namespaced container idmapped, and the kernel refuses that on
|
store into a namespaced container idmapped, and the kernel refuses that on
|
||||||
overlayfs and on some other filesystems. `WriteNspawnFlags` for an opted-in
|
overlayfs and on some other filesystems. `WriteNspawnFlags` for an opted-in
|
||||||
agent checks the `statfs` type of `/nix/store` against an allowlist of those
|
agent checks the `statfs` type of `/nix/store` against an allowlist of those
|
||||||
three. The check refuses every other filesystem, zfs and tmpfs included, even
|
four; the VM test's erofs store idmaps on the hive's kernel. The check
|
||||||
where a newer kernel could idmap it, because the gate exists to stop a
|
refuses every other filesystem, zfs and tmpfs included, even where a newer
|
||||||
container that would not boot. The error names the type and the fix, and
|
kernel could idmap it, because the gate exists to stop a container that would
|
||||||
|
not boot. The error names the type and the fix, and
|
||||||
comes before anything moves. Check a host with
|
comes before anything moves. Check a host with
|
||||||
`findmnt -no FSTYPE /nix/store`.
|
`findmnt -no FSTYPE /nix/store`.
|
||||||
- **The container starts with `--private-users=pick --private-users-ownership=map`.**
|
- **The container starts with `--private-users=pick --private-users-ownership=map`.**
|
||||||
|
|
|
||||||
|
|
@ -51,8 +51,11 @@ const STORE: &str = "/nix/store";
|
||||||
type FsType = libc::__fsword_t;
|
type FsType = libc::__fsword_t;
|
||||||
|
|
||||||
/// `f_type` of the filesystems that support idmapped mounts and that a store
|
/// `f_type` of the filesystems that support idmapped mounts and that a store
|
||||||
/// can sit on: ext4, btrfs and xfs. Nothing else is accepted.
|
/// can sit on: ext4, btrfs, xfs and erofs (`EROFS_SUPER_MAGIC_V1` in the
|
||||||
const IDMAP_FS: [FsType; 3] = [0xEF53, 0x9123_683E, 0x5846_5342];
|
/// kernel's `linux/magic.h`; `libc` has no constant for it). Nothing else is
|
||||||
|
/// accepted. A namespaced agent ran idmapped binds on the VM test's erofs
|
||||||
|
/// store, so erofs idmaps on our kernel.
|
||||||
|
const IDMAP_FS: [FsType; 4] = [0xEF53, 0x9123_683E, 0x5846_5342, 0xE0F5_E1E2];
|
||||||
|
|
||||||
/// The dirs under `<AGENT_STATE_ROOT>/<agent>` the agent writes into. `config`
|
/// The dirs under `<AGENT_STATE_ROOT>/<agent>` the agent writes into. `config`
|
||||||
/// is not one of them: hive-core writes it and the agent only reads it. `state`
|
/// is not one of them: hive-core writes it and the agent only reads it. `state`
|
||||||
|
|
@ -111,7 +114,7 @@ fn fs_type(path: &Path) -> std::io::Result<FsType> {
|
||||||
Ok(buf.f_type)
|
Ok(buf.f_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Refuse a store whose filesystem is not ext4, btrfs or xfs. nspawn clones a
|
/// Refuse a store whose filesystem is not ext4, btrfs, xfs or erofs. nspawn clones a
|
||||||
/// namespaced container's `/nix/store` bind with an idmap, which the kernel
|
/// namespaced container's `/nix/store` bind with an idmap, which the kernel
|
||||||
/// refuses on other filesystems, so the container would not boot. Others are
|
/// refuses on other filesystems, so the container would not boot. Others are
|
||||||
/// refused even where a newer kernel could idmap them.
|
/// refused even where a newer kernel could idmap them.
|
||||||
|
|
@ -122,7 +125,7 @@ fn check_store(agent: &str, f_type: std::io::Result<FsType>) -> Result<()> {
|
||||||
}
|
}
|
||||||
bail!(
|
bail!(
|
||||||
"{agent} sets privateUsers, but {STORE} is on a filesystem (f_type {f_type:#x}) other \
|
"{agent} sets privateUsers, but {STORE} is on a filesystem (f_type {f_type:#x}) other \
|
||||||
than ext4, btrfs or xfs, the only ones accepted; move {STORE} to one of them, or leave \
|
than ext4, btrfs, xfs or erofs, the only ones accepted; move {STORE} to one of them, or leave \
|
||||||
privateUsers off for this agent"
|
privateUsers off for this agent"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -686,14 +689,14 @@ mod tests {
|
||||||
/// looks.
|
/// looks.
|
||||||
#[test]
|
#[test]
|
||||||
fn the_store_has_to_be_on_a_filesystem_that_can_be_idmapped() {
|
fn the_store_has_to_be_on_a_filesystem_that_can_be_idmapped() {
|
||||||
for t in [0xEF53, 0x9123_683E, 0x5846_5342] {
|
for t in [0xEF53, 0x9123_683E, 0x5846_5342, 0xE0F5_E1E2] {
|
||||||
check_store("a", Ok(t)).unwrap();
|
check_store("a", Ok(t)).unwrap();
|
||||||
}
|
}
|
||||||
// overlayfs and tmpfs
|
// overlayfs and tmpfs
|
||||||
for t in [0x794c_7630, 0x0102_1994] {
|
for t in [0x794c_7630, 0x0102_1994] {
|
||||||
let msg = format!("{:#}", check_store("a", Ok(t)).unwrap_err());
|
let msg = format!("{:#}", check_store("a", Ok(t)).unwrap_err());
|
||||||
assert!(
|
assert!(
|
||||||
msg.contains(&format!("{t:#x}")) && msg.contains("ext4, btrfs or xfs"),
|
msg.contains(&format!("{t:#x}")) && msg.contains("ext4, btrfs, xfs or erofs"),
|
||||||
"{msg}"
|
"{msg}"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue