add fs isolation

This commit is contained in:
Masato Imai
2024-10-21 05:00:27 +00:00
parent 1c187b3bd1
commit be8f016042
3 changed files with 72 additions and 19 deletions

View File

@ -12,4 +12,4 @@ name = "izoli"
path = "src/bin/izoli.rs"
[dependencies]
nix = { version = "0.29.0", features = ["sched", "hostname"] }
nix = { version = "0.29.0", features = ["sched", "hostname", "mount"] }

View File

@ -11,17 +11,6 @@ use nix::{
fn main() {
let cgroup = CGroup::new("izoli").unwrap();
println!("{:?}", cgroup.get_root_path());
println!("{}", cgroup.check_status());
println!("{:?}", cgroup.read("cgroup.type"));
println!("{:?}", cgroup.get_controllers());
println!("{:?}", cgroup.get_subtree_control());
println!("{:?}", cgroup.get_procs());
println!("{:?}", cgroup.get_threads());
println!("{:?}", cgroup.get_stat());
println!("{:?}", cgroup.get_max_depth());
println!("{:?}", cgroup.get_max_descendants());
println!("{:?}", cgroup.get_cpu_max());
cgroup
.add_subtree_control(cgroup.get_controllers().unwrap())
@ -38,14 +27,13 @@ fn main() {
);
let pid = izolibox
.enter(Box::new(|| {
sethostname(format!("IzoliBox")).unwrap();
IzoliBox::prelude(1).unwrap();
println!("Isolated process: {}", std::process::id());
println!("cgroup: {:?}", CGroup::get_self_cgroup());
let cmd = CString::new("bash").unwrap();
let args = vec![
CString::new("containered bash").unwrap(),
CString::new("-l").unwrap(),
let cmd = CString::new("/usr/bin/bash").unwrap();
let args: Vec<CString> = vec![
//CString::new("containered bash").unwrap(),
//CString::new("-l").unwrap(),
];
if let Err(e) = execvp(&cmd, &args.as_ref()) {
eprintln!("execvp failed: {:?}", e);

View File

@ -1,7 +1,11 @@
use std::{env::set_current_dir, fs, os::unix::fs::chroot, path::Path};
use nix::{
errno::Errno,
libc::SIGCHLD,
mount::{mount, umount, MsFlags},
sched::{self, CloneCb, CloneFlags},
unistd::Pid,
unistd::{sethostname, Pid},
};
use crate::cgroup::{cgroup::CGroup, cgroup_option::CGroupOption};
@ -33,4 +37,65 @@ impl IzoliBox {
unsafe { sched::clone(callback, &mut stack, flags, Some(SIGCHLD)) }
}
pub fn prelude(id: usize) -> Result<(), Box<dyn std::error::Error>> {
let root = format!("/var/local/lib/izoli/{}", id);
fs::create_dir_all(Path::new(&root))?;
Self::umount_mount(
Some("none"),
"/",
None::<&str>,
MsFlags::MS_REC | MsFlags::MS_PRIVATE,
None::<&str>,
)?;
for dir in &[
"/proc", "/dev", "/tmp", "/lib", "/usr", "/bin", "/lib64", "/usr/lib", "/usr/bin",
] {
fs::create_dir_all(format!("{}{}", root, dir))?;
}
let mounts = [
("tmp", "tmpfs", MsFlags::empty()),
("proc", "proc", MsFlags::empty()),
("dev", "devtmpfs", MsFlags::empty()),
("lib", "/lib", MsFlags::MS_BIND | MsFlags::MS_REC),
("usr/lib", "/usr/lib", MsFlags::MS_BIND | MsFlags::MS_REC),
("usr/bin", "/usr/bin", MsFlags::MS_BIND | MsFlags::MS_REC),
("bin", "/bin", MsFlags::MS_BIND | MsFlags::MS_REC),
("lib64", "/lib64", MsFlags::MS_BIND | MsFlags::MS_REC),
];
for (target, source, flags) in mounts.iter() {
let full_target = format!("{}/{}", root, target);
Self::umount_mount(
Some(source),
&full_target,
Some(source),
*flags,
None::<&str>,
)?;
}
chroot(&root)?;
set_current_dir("/")?;
sethostname(format!("IzoliBox"))?;
Ok(())
}
fn umount_mount<P: AsRef<Path>>(
source: Option<&str>,
target: P,
fstype: Option<&str>,
flags: MsFlags,
data: Option<&str>,
) -> Result<(), nix::Error> {
let target_path = target.as_ref();
let _ = umount(target_path);
mount(source, target_path, fstype, flags, data)
}
}