|
|
|
@ -9,6 +9,8 @@ pub enum Mapping {
|
|
|
|
|
Device(PathBuf),
|
|
|
|
|
Dir(PathBuf, DirOpts),
|
|
|
|
|
Special(PathBuf, PathBuf, DirOpts),
|
|
|
|
|
Link(PathBuf, PathBuf),
|
|
|
|
|
Copy(PathBuf, PathBuf),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Default)]
|
|
|
|
@ -47,6 +49,18 @@ impl DirOpts {
|
|
|
|
|
|
|
|
|
|
pub enum MappingHandle {
|
|
|
|
|
Mount(UnmountDrop<Mount>),
|
|
|
|
|
Link(LinkDrop),
|
|
|
|
|
None,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub struct LinkDrop {
|
|
|
|
|
path: PathBuf,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Drop for LinkDrop {
|
|
|
|
|
fn drop(&mut self) {
|
|
|
|
|
std::fs::remove_file(&self.path).unwrap();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Mapping {
|
|
|
|
@ -62,11 +76,21 @@ impl Mapping {
|
|
|
|
|
Self::Special(src.into(), dst.into(), opt)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn link<P1: Into<PathBuf>, P2: Into<PathBuf>>(src: P1, dst: P2) -> Self {
|
|
|
|
|
Self::Link(src.into(), dst.into())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn copy<P1: Into<PathBuf>, P2: Into<PathBuf>>(src: P1, dst: P2) -> Self {
|
|
|
|
|
Self::Copy(src.into(), dst.into())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub async fn create_mapping(&self, root_path: &Path) -> Result<MappingHandle, ChrootError> {
|
|
|
|
|
match &self {
|
|
|
|
|
Mapping::Device(d) => self.map_dev(d, &root_path.join(d)).await,
|
|
|
|
|
Mapping::Dir(d, opt) => self.map_dir(d, &root_path.join(d), opt).await,
|
|
|
|
|
Mapping::Special(src, dst, opt) => self.map_dir(src, &root_path.join(dst), opt).await,
|
|
|
|
|
Mapping::Link(src, dst) => self.map_link(src, &root_path.join(dst)).await,
|
|
|
|
|
Mapping::Copy(src, dst) => self.copy_file(src, &root_path.join(dst)).await,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -112,6 +136,32 @@ impl Mapping {
|
|
|
|
|
|
|
|
|
|
Ok(MappingHandle::Mount(mount))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async fn map_link(&self, src: &Path, dst: &Path) -> Result<MappingHandle, ChrootError> {
|
|
|
|
|
if dst.exists() && dst.is_symlink() {
|
|
|
|
|
fs::remove_file(dst).await.map_err(ChrootError::Unlink)?;
|
|
|
|
|
}
|
|
|
|
|
fs::symlink(src, dst)
|
|
|
|
|
.await
|
|
|
|
|
.map_err(|e| ChrootError::Link(dst.to_owned(), e))?;
|
|
|
|
|
Ok(MappingHandle::Link(LinkDrop {
|
|
|
|
|
path: dst.to_owned(),
|
|
|
|
|
}))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async fn copy_file(&self, src: &Path, dst: &Path) -> Result<MappingHandle, ChrootError> {
|
|
|
|
|
if dst.exists() && dst.is_file() {
|
|
|
|
|
fs::remove_file(dst)
|
|
|
|
|
.await
|
|
|
|
|
.map_err(|e| ChrootError::Copy(dst.to_owned(), e))?;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fs::copy(src, dst)
|
|
|
|
|
.await
|
|
|
|
|
.map_err(|e| ChrootError::Copy(dst.to_owned(), e))?;
|
|
|
|
|
|
|
|
|
|
Ok(MappingHandle::None)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn default_mappings() -> Vec<Mapping> {
|
|
|
|
@ -162,6 +212,11 @@ pub fn default_mappings() -> Vec<Mapping> {
|
|
|
|
|
Mapping::dev("/dev/tty"),
|
|
|
|
|
Mapping::dev("/dev/urandom"),
|
|
|
|
|
Mapping::dev("/dev/zero"),
|
|
|
|
|
Mapping::link("/proc/self/fd", "dev/fd"),
|
|
|
|
|
Mapping::link("/proc/self/fd/0", "dev/stdin"),
|
|
|
|
|
Mapping::link("/proc/self/fd/1", "dev/stdout"),
|
|
|
|
|
Mapping::link("/proc/self/fd/2", "dev/stderr"),
|
|
|
|
|
Mapping::copy("/etc/resolv.conf", "etc/resolv.conf"),
|
|
|
|
|
Mapping::dir(
|
|
|
|
|
"/run",
|
|
|
|
|
DirOpts::default().fs_type("tmpfs").flags(NOSUID | NODEV),
|
|
|
|
|