Add ChrootedTask to run all tasks in a different (curently hardcoded) root
parent
29a12c5e5e
commit
8e2029cbb0
@ -0,0 +1,61 @@
|
|||||||
|
use std::{
|
||||||
|
ffi::{c_int, CString},
|
||||||
|
io,
|
||||||
|
os::unix::prelude::OsStrExt,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
};
|
||||||
|
|
||||||
|
use libc::CLONE_FS;
|
||||||
|
use tokio::task::JoinHandle;
|
||||||
|
|
||||||
|
use crate::error::ChrootError;
|
||||||
|
|
||||||
|
pub struct ChrootedTask {
|
||||||
|
root_path: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ChrootedTask {
|
||||||
|
/// Creates a new chrooted thread with the given path
|
||||||
|
pub fn new<P: Into<PathBuf>>(root_path: P) -> Self {
|
||||||
|
Self {
|
||||||
|
root_path: root_path.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Runs the given future in a new chroot
|
||||||
|
pub fn run<F, T>(self, call: F) -> JoinHandle<Result<T, ChrootError>>
|
||||||
|
where
|
||||||
|
F: FnOnce() -> T + Send + 'static,
|
||||||
|
T: Send + 'static,
|
||||||
|
{
|
||||||
|
let root_path = self.root_path;
|
||||||
|
let handle = std::thread::spawn(move || {
|
||||||
|
unsafe {
|
||||||
|
init_chroot(&root_path)?;
|
||||||
|
}
|
||||||
|
Ok(call())
|
||||||
|
});
|
||||||
|
tokio::task::spawn_blocking(|| handle.join().unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn init_chroot(path: &Path) -> Result<(), ChrootError> {
|
||||||
|
handle_err_code(libc::unshare(CLONE_FS)).map_err(ChrootError::Unshare)?;
|
||||||
|
let path_str = CString::new(path.as_os_str().as_bytes().to_vec()).unwrap();
|
||||||
|
handle_err_code(libc::chroot(
|
||||||
|
path_str.as_bytes_with_nul().as_ptr() as *const libc::c_char
|
||||||
|
))
|
||||||
|
.map_err(ChrootError::Chroot)?;
|
||||||
|
std::env::set_current_dir(path).map_err(ChrootError::ChDir)?;
|
||||||
|
std::env::set_var("PWD", "/");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_err_code(code: c_int) -> Result<(), io::Error> {
|
||||||
|
if code != 0 {
|
||||||
|
Err(io::Error::last_os_error())
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue