summary refs log tree commit diff
path: root/src/linux.rs
diff options
context:
space:
mode:
authorZach Reizner <zachr@google.com>2018-09-14 15:43:33 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-09-17 21:35:02 -0700
commit579bd2cf0e59c86779bc113734d583590341301c (patch)
treef3a6f9aebe58fab758dbafd83abce97fabe0e6f0 /src/linux.rs
parenta99954cb7c076c9585aba416afdcb86f67e3676f (diff)
downloadcrosvm-579bd2cf0e59c86779bc113734d583590341301c.tar
crosvm-579bd2cf0e59c86779bc113734d583590341301c.tar.gz
crosvm-579bd2cf0e59c86779bc113734d583590341301c.tar.bz2
crosvm-579bd2cf0e59c86779bc113734d583590341301c.tar.lz
crosvm-579bd2cf0e59c86779bc113734d583590341301c.tar.xz
crosvm-579bd2cf0e59c86779bc113734d583590341301c.tar.zst
crosvm-579bd2cf0e59c86779bc113734d583590341301c.zip
linux: bind wayland directory in virtio-wayland sandbox
For example, if the wayland socket is given as /run/wayland-0, the
entire /run/ directory will be bind mounted into the sandbox as
/wayland/. The wayland device will then be told to open the socket at
/wayland/wayland-0. If the /run/wayland-0 file is removed and a new
socket is opened in its place, as in a chrome crash, the
/wayland/wayland-0 socket will open the new socket rather than the one
belonging to the expire process.

TEST=vmc start termina; chrome://inducebrowsercrashforrealz;
    vsh termina; start wayland application
BUG=chromium:884398

Change-Id: I259eb2f7e29ee6b61836133ec1c3a110c5575957
Reviewed-on: https://chromium-review.googlesource.com/1227063
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Stephen Barber <smbarber@chromium.org>
Diffstat (limited to 'src/linux.rs')
-rw-r--r--src/linux.rs21
1 files changed, 15 insertions, 6 deletions
diff --git a/src/linux.rs b/src/linux.rs
index a5c87de..5b46663 100644
--- a/src/linux.rs
+++ b/src/linux.rs
@@ -65,6 +65,7 @@ pub enum Error {
     FailedCLOEXECCheck,
     FailedToDupFd,
     InvalidFdPath,
+    InvalidWaylandPath,
     NetDeviceNew(devices::virtio::NetError),
     NoVarEmpty,
     OpenKernel(PathBuf, io::Error),
@@ -119,6 +120,9 @@ impl fmt::Display for Error {
             }
             &Error::FailedToDupFd => write!(f, "failed to dup fd from /proc/self/fd"),
             &Error::InvalidFdPath => write!(f, "failed parsing a /proc/self/fd/*"),
+            &Error::InvalidWaylandPath => {
+                write!(f, "wayland socket path has no parent or file name")
+            }
             &Error::NetDeviceNew(ref e) => write!(f, "failed to set up virtio networking: {:?}", e),
             &Error::NoVarEmpty => write!(f, "/var/empty doesn't exist, can't jail devices."),
             &Error::OpenKernel(ref p, ref e) => {
@@ -363,7 +367,10 @@ fn create_virtio_devs(cfg: VirtIoDeviceInfo,
     }
 
     if let Some(wayland_socket_path) = cfg.wayland_socket_path.as_ref() {
-        let jailed_wayland_path = Path::new("/wayland-0");
+        let wayland_socket_dir = wayland_socket_path.parent().ok_or(Error::InvalidWaylandPath)?;
+        let wayland_socket_name = wayland_socket_path.file_name().ok_or(Error::InvalidWaylandPath)?;
+        let jailed_wayland_dir = Path::new("/wayland");
+        let jailed_wayland_path = jailed_wayland_dir.join(wayland_socket_name);
 
         let wl_box = Box::new(devices::virtio::Wl::new(if cfg.multiprocess {
                                                            &jailed_wayland_path
@@ -377,16 +384,18 @@ fn create_virtio_devs(cfg: VirtIoDeviceInfo,
             let policy_path: PathBuf = cfg.seccomp_policy_dir.join("wl_device.policy");
             let mut jail = create_base_minijail(empty_root_path, &policy_path)?;
 
-            // Create a tmpfs in the device's root directory so that we can bind mount the
-            // wayland socket into it.  The size=67108864 is size=64*1024*1024 or size=64MB.
+            // Create a tmpfs in the device's root directory so that we can bind mount the wayland
+            // socket directory into it. The size=67108864 is size=64*1024*1024 or size=64MB.
             jail.mount_with_data(Path::new("none"), Path::new("/"), "tmpfs",
                                  (libc::MS_NOSUID | libc::MS_NODEV | libc::MS_NOEXEC) as usize,
                                  "size=67108864")
                 .unwrap();
 
-            // Bind mount the wayland socket into jail's root. This is necessary since each
-            // new wayland context must open() the socket.
-            jail.mount_bind(wayland_socket_path.as_path(), jailed_wayland_path, true)
+            // Bind mount the wayland socket's directory into jail's root. This is necessary since
+            // each new wayland context must open() the socket. If the wayland socket is ever
+            // destroyed and remade in the same host directory, new connections will be possible
+            // without restarting the wayland device.
+            jail.mount_bind(wayland_socket_dir, jailed_wayland_dir, true)
                 .unwrap();
 
             // Set the uid/gid for the jailed process, and give a basic id map. This