support user mount

This commit is contained in:
mii
2024-10-31 17:31:45 +09:00
parent d9842c5f64
commit 8346a7165f
2 changed files with 72 additions and 18 deletions

View File

@ -5,7 +5,7 @@ use izolilib::{
cgroup::CGroup, cgroup_option::CGroupOption, cpu_limit::CpuLimit, cgroup::CGroup, cgroup_option::CGroupOption, cpu_limit::CpuLimit,
limit_value::CGroupLimitValue, limit_value::CGroupLimitValue,
}, },
izolibox::{IzoliBox, IzoliBoxOptions}, izolibox::{IzoliBox, IzoliBoxOptions, Mount},
}; };
use nix::{sys::wait::waitpid, unistd::execvp}; use nix::{sys::wait::waitpid, unistd::execvp};
use tracing::Level; use tracing::Level;
@ -35,6 +35,14 @@ fn main() {
..Default::default() ..Default::default()
}), }),
new_net: false, new_net: false,
mounts: vec![
Mount::new("/bin", "/bin", true, false),
Mount::new("/usr/bin", "/usr/bin", true, false),
Mount::new("/lib", "/lib", true, false),
Mount::new("/lib64", "/lib64", true, false),
Mount::new("/usr/lib", "/usr/lib", true, false),
Mount::new("/usr/lib64", "/usr/lib64", true, false),
],
}, },
); );

View File

@ -6,7 +6,7 @@ use nix::{
sched::{self, CloneCb, CloneFlags}, sched::{self, CloneCb, CloneFlags},
unistd::{sethostname, Pid}, unistd::{sethostname, Pid},
}; };
use tracing::info; use tracing::{info, trace};
use crate::cgroup::{cgroup::CGroup, cgroup_option::CGroupOption}; use crate::cgroup::{cgroup::CGroup, cgroup_option::CGroupOption};
@ -21,6 +21,26 @@ pub struct IzoliBox {
pub struct IzoliBoxOptions { pub struct IzoliBoxOptions {
pub cgroup_option: Option<CGroupOption>, pub cgroup_option: Option<CGroupOption>,
pub new_net: bool, pub new_net: bool,
pub mounts: Vec<Mount>,
}
#[derive(Debug, Clone, Default)]
pub struct Mount {
pub target: String,
pub source: String,
pub readonly: bool,
pub no_exec: bool,
}
impl Mount {
pub fn new(target: &str, source: &str, readonly: bool, no_exec: bool) -> Self {
Self {
target: target.to_string(),
source: source.to_string(),
readonly,
no_exec,
}
}
} }
impl IzoliBox { impl IzoliBox {
@ -62,6 +82,7 @@ impl IzoliBox {
fn prelude(&self) -> Result<(), Box<dyn std::error::Error>> { fn prelude(&self) -> Result<(), Box<dyn std::error::Error>> {
info!("box prelude"); info!("box prelude");
let root = self.get_root(); let root = self.get_root();
let _ = fs::remove_dir(Path::new(&root));
fs::create_dir_all(Path::new(&root))?; fs::create_dir_all(Path::new(&root))?;
self.prelude_mount()?; self.prelude_mount()?;
@ -107,22 +128,34 @@ impl IzoliBox {
)?; )?;
} }
// readonly monut for Mount {
let mounts = [ target,
("bin", "/bin"), source,
("usr/bin", "/usr/bin"), readonly,
("usr/lib", "/usr/lib"), no_exec,
("lib", "/usr/lib"), } in self.options.mounts.clone()
("lib64", "/usr/lib64"), {
]; let target: &str = &target;
let source: &str = &source;
let flag_noexec = if no_exec {
MsFlags::MS_NOEXEC
} else {
MsFlags::empty()
};
let flag_rdonly = if readonly {
MsFlags::MS_RDONLY
} else {
MsFlags::empty()
};
let full_target: &str = &format!("{}/{}", root, target.trim_start_matches("/"));
info!("mounting {} to {}", source, full_target);
fs::create_dir_all(full_target)?;
for (target, source) in mounts.iter() {
let target: &str = &format!("{}/{}", root, target);
info!("mounting {} to {} readonly", source, target);
fs::create_dir_all(target)?;
mount( mount(
Some(*source), Some(source),
target, full_target,
Some("none"), Some("none"),
MsFlags::MS_BIND | MsFlags::MS_REC, MsFlags::MS_BIND | MsFlags::MS_REC,
None::<&str>, None::<&str>,
@ -130,12 +163,25 @@ impl IzoliBox {
mount( mount(
None::<&str>, None::<&str>,
target, full_target,
None::<&str>, None::<&str>,
MsFlags::MS_BIND | MsFlags::MS_REMOUNT | MsFlags::MS_RDONLY | MsFlags::MS_REC, MsFlags::MS_BIND
| MsFlags::MS_REMOUNT
| MsFlags::MS_REC
| flag_rdonly
| flag_noexec,
None::<&str>, None::<&str>,
)?; )?;
trace!(
"{:?}",
MsFlags::MS_BIND
| MsFlags::MS_REMOUNT
| MsFlags::MS_REC
| flag_rdonly
| flag_noexec
);
} }
Ok(()) Ok(())
} }