From be8f01604210d82e8da3b57e7be1aaffd4368e97 Mon Sep 17 00:00:00 2001 From: Masato Imai Date: Mon, 21 Oct 2024 05:00:27 +0000 Subject: [PATCH] add fs isolation --- Cargo.toml | 2 +- src/bin/izoli.rs | 22 ++++------------ src/izolibox.rs | 67 +++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 72 insertions(+), 19 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6f802c4..5d663aa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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"] } diff --git a/src/bin/izoli.rs b/src/bin/izoli.rs index 09f2136..5330312 100644 --- a/src/bin/izoli.rs +++ b/src/bin/izoli.rs @@ -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 = vec![ + //CString::new("containered bash").unwrap(), + //CString::new("-l").unwrap(), ]; if let Err(e) = execvp(&cmd, &args.as_ref()) { eprintln!("execvp failed: {:?}", e); diff --git a/src/izolibox.rs b/src/izolibox.rs index 4524a2e..d2088ef 100644 --- a/src/izolibox.rs +++ b/src/izolibox.rs @@ -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> { + 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>( + 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) + } }