diff options
author | Dmitry Torokhov <dtor@chromium.org> | 2018-05-11 10:57:16 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-05-16 05:08:31 -0700 |
commit | 0f1770d3ef9469b23edbaaa5f977dc0bb59602c6 (patch) | |
tree | eb475ba24a350820e543f56c549d1074bab913ec /src | |
parent | 6051e7593a612d45549662b84a74c131b95c1af6 (diff) | |
download | crosvm-0f1770d3ef9469b23edbaaa5f977dc0bb59602c6.tar crosvm-0f1770d3ef9469b23edbaaa5f977dc0bb59602c6.tar.gz crosvm-0f1770d3ef9469b23edbaaa5f977dc0bb59602c6.tar.bz2 crosvm-0f1770d3ef9469b23edbaaa5f977dc0bb59602c6.tar.lz crosvm-0f1770d3ef9469b23edbaaa5f977dc0bb59602c6.tar.xz crosvm-0f1770d3ef9469b23edbaaa5f977dc0bb59602c6.tar.zst crosvm-0f1770d3ef9469b23edbaaa5f977dc0bb59602c6.zip |
crosvm/plugin: allow specifying root directory for plugin
Plugin often needs access to various objects on disk; let's allow caller to prepare root filesystem for the plugin to pivot to. BUG=None TEST=cargo test --features=plugin Change-Id: I4f91511c776a06e4c329fe5aa42df4bb613ab5ab Signed-off-by: Dmitry Torokhov <dtor@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1055666 Reviewed-by: Zach Reizner <zachr@chromium.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/main.rs | 9 | ||||
-rw-r--r-- | src/plugin/mod.rs | 28 |
2 files changed, 31 insertions, 6 deletions
diff --git a/src/main.rs b/src/main.rs index c723613..f8ed715 100644 --- a/src/main.rs +++ b/src/main.rs @@ -76,6 +76,7 @@ pub struct Config { seccomp_policy_dir: PathBuf, cid: Option<u64>, plugin: Option<PathBuf>, + plugin_root: Option<PathBuf>, } impl Default for Config { @@ -96,6 +97,7 @@ impl Default for Config { seccomp_policy_dir: PathBuf::from(SECCOMP_POLICY_DIR), cid: None, plugin: None, + plugin_root: None, } } } @@ -319,6 +321,9 @@ fn set_argument(cfg: &mut Config, name: &str, value: Option<&str>) -> argument:: } cfg.plugin = Some(plugin); }, + "plugin-root" => { + cfg.plugin_root = Some(PathBuf::from(value.unwrap().to_owned())); + }, "vhost-net" => { cfg.vhost_net = true }, @@ -368,6 +373,7 @@ fn run_vm(args: std::env::Args) -> std::result::Result<(), ()> { Argument::value("seccomp-policy-dir", "PATH", "Path to seccomp .policy files."), #[cfg(feature = "plugin")] Argument::value("plugin", "PATH", "Absolute path to plugin process to run under crosvm."), + Argument::value("plugin-root", "PATH", "Absolute path to a directory that will become root filesystem for the plugin process."), Argument::flag("vhost-net", "Use vhost for networking."), Argument::short_flag('h', "help", "Print help message.")]; @@ -387,6 +393,9 @@ fn run_vm(args: std::env::Args) -> std::result::Result<(), ()> { return Err(argument::Error::ExpectedArgument("`mac` missing from network config".to_owned())); } } + if cfg.plugin_root.is_some() && cfg.plugin.is_none() { + return Err(argument::Error::ExpectedArgument("`plugin-root` requires `plugin`".to_owned())); + } Ok(()) }); diff --git a/src/plugin/mod.rs b/src/plugin/mod.rs index 6a22494..750f22b 100644 --- a/src/plugin/mod.rs +++ b/src/plugin/mod.rs @@ -60,7 +60,7 @@ pub enum Error { MountPlugin(io_jail::Error), MountPluginLib(io_jail::Error), MountRoot(io_jail::Error), - NoVarEmpty, + NoRootDir, ParsePivotRoot(io_jail::Error), ParseSeccomp(io_jail::Error), PluginFailed(i32), @@ -76,6 +76,8 @@ pub enum Error { PluginWait(SysError), Poll(SysError), PollContextAdd(SysError), + RootNotAbsolute, + RootNotDir, SetGidMap(io_jail::Error), SetUidMap(io_jail::Error), SigChild { @@ -121,7 +123,7 @@ impl fmt::Display for Error { Error::MountPlugin(ref e) => write!(f, "failed to mount: {}", e), Error::MountPluginLib(ref e) => write!(f, "failed to mount: {}", e), Error::MountRoot(ref e) => write!(f, "failed to mount: {}", e), - Error::NoVarEmpty => write!(f, "no /var/empty for jailed process to pivot root into"), + Error::NoRootDir => write!(f, "no root directory for jailed process to pivot root into"), Error::ParsePivotRoot(ref e) => write!(f, "failed to set jail pivot root: {}", e), Error::ParseSeccomp(ref e) => write!(f, "failed to parse jail seccomp filter: {}", e), Error::PluginFailed(ref e) => write!(f, "plugin exited with error: {}", e), @@ -143,6 +145,8 @@ impl fmt::Display for Error { Error::PluginWait(ref e) => write!(f, "error waiting for plugin to exit: {:?}", e), Error::Poll(ref e) => write!(f, "failed to poll all FDs: {:?}", e), Error::PollContextAdd(ref e) => write!(f, "failed to add fd to poll context: {:?}", e), + Error::RootNotAbsolute => write!(f, "path to the root directory must be absolute"), + Error::RootNotDir => write!(f, "specified root directory is not a directory"), Error::SetGidMap(ref e) => write!(f, "failed to set gidmap for jail: {}", e), Error::SetUidMap(ref e) => write!(f, "failed to set uidmap for jail: {}", e), Error::SigChild { @@ -423,13 +427,25 @@ pub fn run_config(cfg: Config) -> Result<()> { let jail = if cfg.multiprocess { // An empty directory for jailed plugin pivot root. - let empty_root_path = Path::new("/var/empty"); - if !empty_root_path.exists() { - return Err(Error::NoVarEmpty); + let root_path = match cfg.plugin_root { + Some(ref dir) => Path::new(dir), + None => Path::new("/var/empty"), + }; + + if root_path.is_relative() { + return Err(Error::RootNotAbsolute); + } + + if !root_path.exists() { + return Err(Error::NoRootDir); + } + + if !root_path.is_dir() { + return Err(Error::RootNotDir); } let policy_path = cfg.seccomp_policy_dir.join("plugin.policy"); - let jail = create_plugin_jail(empty_root_path, &policy_path)?; + let jail = create_plugin_jail(root_path, &policy_path)?; Some(jail) } else { None |