From 579bd2cf0e59c86779bc113734d583590341301c Mon Sep 17 00:00:00 2001 From: Zach Reizner Date: Fri, 14 Sep 2018 15:43:33 -0700 Subject: 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 Tested-by: Zach Reizner Reviewed-by: Stephen Barber --- src/linux.rs | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'src/linux.rs') 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 -- cgit 1.4.1