summary refs log tree commit diff
path: root/src/plugin/mod.rs
diff options
context:
space:
mode:
authorDmitry Torokhov <dtor@chromium.org>2019-01-30 23:02:25 -0800
committerchrome-bot <chrome-bot@chromium.org>2019-02-16 04:14:51 -0800
commitea3302895784a020fc4fa4c70dbe5f68d79c3b86 (patch)
tree503739aa6fa07d22dcae93265622c4ec5b03fb4f /src/plugin/mod.rs
parentfa70171dfcef8685faab2508f12514c05ea9453f (diff)
downloadcrosvm-ea3302895784a020fc4fa4c70dbe5f68d79c3b86.tar
crosvm-ea3302895784a020fc4fa4c70dbe5f68d79c3b86.tar.gz
crosvm-ea3302895784a020fc4fa4c70dbe5f68d79c3b86.tar.bz2
crosvm-ea3302895784a020fc4fa4c70dbe5f68d79c3b86.tar.lz
crosvm-ea3302895784a020fc4fa4c70dbe5f68d79c3b86.tar.xz
crosvm-ea3302895784a020fc4fa4c70dbe5f68d79c3b86.tar.zst
crosvm-ea3302895784a020fc4fa4c70dbe5f68d79c3b86.zip
crosvm: mount minimal set of devices in plugin jail
PluginVm uses /dev/urandom, so we need to mount it, along with
/dev/zero, /dev/null, and /dev/full.

Note that we are not using minijail's mount_dev() API because it will
try to create tmpfs without using MS_NODEV flag and, since crovm may not
have CAP_SYS_ADMIN capability, Chrome OS LSM will stop it. So we rely on
the parent process to have minimal set of devices present and bind-mount
those into the jail.

BUG=b:117989168
TEST=cargo test --features=plugin

Change-Id: I6d8ab122c56614a8f7dbfe3d0eb8ed33532dc6a7
Signed-off-by: Dmitry Torokhov <dtor@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1447551
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Zach Reizner <zachr@chromium.org>
Diffstat (limited to 'src/plugin/mod.rs')
-rw-r--r--src/plugin/mod.rs11
1 files changed, 11 insertions, 0 deletions
diff --git a/src/plugin/mod.rs b/src/plugin/mod.rs
index 32ea4bb..d886f0d 100644
--- a/src/plugin/mod.rs
+++ b/src/plugin/mod.rs
@@ -61,6 +61,7 @@ pub enum Error {
     DecodeRequest(ProtobufError),
     EncodeResponse(ProtobufError),
     Mount(io_jail::Error),
+    MountDev(io_jail::Error),
     MountLib(io_jail::Error),
     MountLib64(io_jail::Error),
     MountPlugin(io_jail::Error),
@@ -129,6 +130,7 @@ impl fmt::Display for Error {
             Error::DecodeRequest(ref e) => write!(f, "failed to decode plugin request: {}", e),
             Error::EncodeResponse(ref e) => write!(f, "failed to encode plugin response: {}", e),
             Error::Mount(ref e) => write!(f, "failed to mount: {}", e),
+            Error::MountDev(ref e) => write!(f, "failed to mount: {}", e),
             Error::MountLib(ref e) => write!(f, "failed to mount: {}", e),
             Error::MountLib64(ref e) => write!(f, "failed to mount: {}", e),
             Error::MountPlugin(ref e) => write!(f, "failed to mount: {}", e),
@@ -496,6 +498,15 @@ pub fn run_config(cfg: Config) -> Result<()> {
         let policy_path = cfg.seccomp_policy_dir.join("plugin.policy");
         let mut jail = create_plugin_jail(root_path, &policy_path)?;
 
+        // Mount minimal set of devices (full, zero, urandom, etc). We can not use
+        // jail.mount_dev() here because crosvm may not be running with CAP_SYS_ADMIN.
+        let device_names = ["full", "null", "urandom", "zero"];
+        for name in device_names.iter() {
+            let device = Path::new("/dev").join(&name);
+            jail.mount_bind(&device, &device, true)
+                .map_err(Error::MountDev)?;
+        }
+
         for bind_mount in &cfg.plugin_mounts {
             jail.mount_bind(&bind_mount.src, &bind_mount.dst, bind_mount.writable)
                 .map_err(Error::Mount)?;