From b631202e66784e7d3cbcc2a3e8d4f243e784fd38 Mon Sep 17 00:00:00 2001 From: Ulf Nilsson Date: Sat, 9 Apr 2016 11:32:50 +0200 Subject: [PATCH] Fix sandboxing on OS X The main issue was resources_dir_path. Every time it was called it would start from the executable's path and walk up the hierarchy to find a directory named "resources". The sandbox was granted permission to read from the found resources dir, but after the sandbox had been activated resources_dir_path would again start from the executable's path and try to find the resources dir. It would then fail with "Operation not permitted" when trying to canonicalize the path because it didn't have permissions to read metadata under ./target. To fix this the resources dir path is now cached between resources_dir_path calls. --- components/compositing/sandboxing.rs | 4 ++- components/servo/lib.rs | 3 +- components/util/resource_files.rs | 49 ++++++++++++++-------------- 3 files changed, 30 insertions(+), 26 deletions(-) diff --git a/components/compositing/sandboxing.rs b/components/compositing/sandboxing.rs index 41273cad0a7..945e0605f09 100644 --- a/components/compositing/sandboxing.rs +++ b/components/compositing/sandboxing.rs @@ -16,7 +16,9 @@ pub fn content_process_sandbox_profile() -> Profile { Operation::FileReadAll(PathPattern::Subpath(PathBuf::from("/Library/Fonts"))), Operation::FileReadAll(PathPattern::Subpath(PathBuf::from("/System/Library/Fonts"))), Operation::FileReadAll(PathPattern::Subpath(PathBuf::from( - "/System/Library/Frameworks/ApplicationServices.framework/"))), + "/System/Library/Frameworks/ApplicationServices.framework"))), + Operation::FileReadAll(PathPattern::Subpath(PathBuf::from( + "/System/Library/Frameworks/CoreGraphics.framework"))), Operation::FileReadMetadata(PathPattern::Literal(PathBuf::from("/"))), Operation::FileReadMetadata(PathPattern::Literal(PathBuf::from("/Library"))), Operation::FileReadMetadata(PathPattern::Literal(PathBuf::from("/System"))), diff --git a/components/servo/lib.rs b/components/servo/lib.rs index 6ddcd58222a..66657543fb0 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -275,7 +275,8 @@ pub unsafe extern fn __errno_location() -> *mut i32 { #[cfg(not(target_os = "windows"))] fn create_sandbox() { - ChildSandbox::new(sandboxing::content_process_sandbox_profile()).activate().unwrap(); + ChildSandbox::new(sandboxing::content_process_sandbox_profile()).activate() + .expect("Failed to activate sandbox!"); } #[cfg(target_os = "windows")] diff --git a/components/util/resource_files.rs b/components/util/resource_files.rs index dcb9646f42c..9df1b2de89c 100644 --- a/components/util/resource_files.rs +++ b/components/util/resource_files.rs @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use std::env; use std::fs::File; use std::io::{self, Read}; use std::path::PathBuf; @@ -25,35 +26,35 @@ pub fn resources_dir_path() -> PathBuf { #[cfg(not(target_os = "android"))] pub fn resources_dir_path() -> PathBuf { - use std::env; + let mut dir = CMD_RESOURCE_DIR.lock().unwrap(); - match *CMD_RESOURCE_DIR.lock().unwrap() { - Some(ref path) => PathBuf::from(path), - None => { - // FIXME: Find a way to not rely on the executable being - // under `[/$target_triple]/target/debug` - // or `[/$target_triple]/target/release`. - let mut path = env::current_exe().expect("can't get exe path"); - // Follow symlink - path = path.canonicalize().expect("path does not exist"); + if let Some(ref path) = *dir { + return PathBuf::from(path); + } + + // FIXME: Find a way to not rely on the executable being + // under `[/$target_triple]/target/debug` + // or `[/$target_triple]/target/release`. + let mut path = env::current_exe().expect("can't get exe path"); + // Follow symlink + path = path.canonicalize().expect("path does not exist"); + path.pop(); + path.push("resources"); + if !path.is_dir() { // resources dir not in same dir as exe? + // exe is probably in target/{debug,release} so we need to go back to topdir + path.pop(); + path.pop(); + path.pop(); + path.push("resources"); + if !path.is_dir() { + // exe is probably in target/$target_triple/{debug,release} so go back one more + path.pop(); path.pop(); path.push("resources"); - if !path.is_dir() { // resources dir not in same dir as exe? - // exe is probably in target/{debug,release} so we need to go back to topdir - path.pop(); - path.pop(); - path.pop(); - path.push("resources"); - if !path.is_dir() { - // exe is probably in target/$target_triple/{debug,release} so go back one more - path.pop(); - path.pop(); - path.push("resources"); - } - } - path } } + *dir = Some(path.to_str().unwrap().to_owned()); + path } pub fn read_resource_file(relative_path_components: &[&str]) -> io::Result> {