servo: Merge #10496 - Fix sandboxing on OS X (from kaksmet:fix-sandbox); r=pcwalton
authorUlf Nilsson <kaksmet@gmail.com>
Mon, 11 Apr 2016 23:24:57 +0500
changeset 338476 dbebb6aa5a0eb85475574dd211d3002de1ecc48d
parent 338475 39a8bea6d01b9debe27900245827cbf1dba6ff8b
child 338477 f4f278bd0b2020fbcf5164e698a851fbfc43d51b
push id31307
push usergszorc@mozilla.com
push dateSat, 04 Feb 2017 00:59:06 +0000
treeherdermozilla-central@94079d43835f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspcwalton
servo: Merge #10496 - Fix sandboxing on OS X (from kaksmet:fix-sandbox); r=pcwalton 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. Source-Repo: https://github.com/servo/servo Source-Revision: a162cfe45cceab123504289a7afc7bf06a4eeec8
servo/components/compositing/sandboxing.rs
servo/components/servo/lib.rs
servo/components/util/resource_files.rs
--- a/servo/components/compositing/sandboxing.rs
+++ b/servo/components/compositing/sandboxing.rs
@@ -11,17 +11,19 @@ use util::resource_files;
 pub fn content_process_sandbox_profile() -> Profile {
     use gaol::platform;
     Profile::new(vec![
         Operation::FileReadAll(PathPattern::Literal(PathBuf::from("/dev/urandom"))),
         Operation::FileReadAll(PathPattern::Subpath(resource_files::resources_dir_path())),
         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"))),
         Operation::FileReadMetadata(PathPattern::Literal(PathBuf::from("/etc"))),
         Operation::SystemInfoRead,
         Operation::PlatformSpecific(platform::macos::Operation::MachLookup(
                 b"com.apple.FontServer".to_vec())),
     ]).expect("Failed to create sandbox profile!")
--- a/servo/components/servo/lib.rs
+++ b/servo/components/servo/lib.rs
@@ -270,15 +270,16 @@ pub fn run_content_process(token: String
 #[no_mangle]
 pub unsafe extern fn __errno_location() -> *mut i32 {
     extern { fn __errno() -> *mut i32; }
     __errno()
 }
 
 #[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")]
 fn create_sandbox() {
     panic!("Sandboxing is not supported on Windows.");
 }
--- a/servo/components/util/resource_files.rs
+++ b/servo/components/util/resource_files.rs
@@ -1,12 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * 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;
 use std::sync::{Arc, Mutex};
 
 lazy_static! {
     static ref CMD_RESOURCE_DIR: Arc<Mutex<Option<String>>> = {
         Arc::new(Mutex::new(None))
@@ -20,45 +21,45 @@ pub fn set_resources_path(path: Option<S
 
 #[cfg(target_os = "android")]
 pub fn resources_dir_path() -> PathBuf {
     PathBuf::from("/sdcard/servo/")
 }
 
 #[cfg(not(target_os = "android"))]
 pub fn resources_dir_path() -> PathBuf {
-    use std::env;
+    let mut dir = CMD_RESOURCE_DIR.lock().unwrap();
+
+    if let Some(ref path) = *dir {
+        return PathBuf::from(path);
+    }
 
-    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 `<servo source>[/$target_triple]/target/debug`
-            // or `<servo source>[/$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");
+    // FIXME: Find a way to not rely on the executable being
+    // under `<servo source>[/$target_triple]/target/debug`
+    // or `<servo source>[/$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<Vec<u8>> {
     let mut path = resources_dir_path();
     for component in relative_path_components {
         path.push(component);
     }
     let mut file = try!(File::open(&path));