diff --git a/src/error.rs b/src/error.rs index aaae4a68b..a04df4137 100644 --- a/src/error.rs +++ b/src/error.rs @@ -18,6 +18,9 @@ pub enum JailError { #[fail(display = "jail_set syscall failed. The error message returned was: {}", _0)] JailSetError(String), + #[fail(display = "jail_attach syscall failed. The error message returned was: {}", _0)] + JailAttachError(#[cause] io::Error), + #[fail(display = "invalid return code from jail_remove")] JailRemoveFailed, diff --git a/src/process.rs b/src/process.rs index 72316f2d9..90d321177 100644 --- a/src/process.rs +++ b/src/process.rs @@ -1,12 +1,10 @@ //! Jail-Specific extensions to the `std::process` module -use libc; - use std::process; -use std::io::{Error, ErrorKind}; use std::os::unix::process::CommandExt; +use JailError; use RunningJail; /// Extension to the `std::process::Command` builder to run the command in a @@ -45,17 +43,12 @@ pub trait Jailed { #[cfg(target_os = "freebsd")] impl Jailed for process::Command { fn jail(&mut self, jail: &RunningJail) -> &mut process::Command { - let jid = jail.jid; + let jail = *jail; self.before_exec(move || { - let ret = unsafe { libc::jail_attach(jid) }; - match ret { - 0 => Ok(()), - -1 => Err(Error::last_os_error()), - _ => Err(Error::new( - ErrorKind::Other, - "invalid return value from jail_attach", - )), - } + jail.attach().map_err(|err| match err { + JailError::JailAttachError(e) => e, + _ => panic!("jail.attach() failed with unexpected error"), + }) }); self diff --git a/src/running.rs b/src/running.rs index 1e87b897b..3803451c6 100644 --- a/src/running.rs +++ b/src/running.rs @@ -1,3 +1,4 @@ +use libc; use param; use rctl; use sys; @@ -5,11 +6,12 @@ use JailError; use StoppedJail; use std::collections::HashMap; +use std::io::{Error, ErrorKind}; use std::net; use std::path; /// Represents a running jail. -#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)] +#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)] #[cfg(target_os = "freebsd")] pub struct RunningJail { /// The `jid` of the jail @@ -408,6 +410,19 @@ impl RunningJail { .usage() .map_err(JailError::RctlError) } + + /// Jail the current process into the given jail. + pub fn attach(&self) -> Result<(), JailError> { + let ret = unsafe { libc::jail_attach(self.jid) }; + match ret { + 0 => Ok(()), + -1 => Err(Error::last_os_error()), + _ => Err(Error::new( + ErrorKind::Other, + "invalid return value from jail_attach", + )), + }.map_err(JailError::JailAttachError) + } } /// An Iterator over running Jails