use anyhow::{Context, Result};
use nix::mount::{MsFlags, mount};
use nix::sched::{CloneFlags, unshare};
use std::fs;
pub fn enter_namespace() -> Result<()> {
let euid = nix::unistd::geteuid();
let uid = nix::unistd::getuid();
let gid = nix::unistd::getgid();
if euid.is_root() {
unshare(CloneFlags::CLONE_NEWNS).context(
"failed to create mount namespace; try running as root or with user namespace support",
)?;
} else {
unshare(CloneFlags::CLONE_NEWUSER | CloneFlags::CLONE_NEWNS).context(
"failed to create user+mount namespace; \
check that unprivileged user namespaces are enabled \
(sysctl kernel.unprivileged_userns_clone=1)",
)?;
fs::write("/proc/self/setgroups", "deny")
.context("failed to write /proc/self/setgroups")?;
fs::write("/proc/self/uid_map", format!("0 {} 1\n", uid))
.context("failed to write /proc/self/uid_map")?;
fs::write("/proc/self/gid_map", format!("0 {} 1\n", gid))
.context("failed to write /proc/self/gid_map")?;
}
mount(
None::<&str>,
"/",
None::<&str>,
MsFlags::MS_REC | MsFlags::MS_PRIVATE,
None::<&str>,
)
.context("failed to set mount propagation to private")?;
Ok(())
}