Commit c382e2ae authored by Greg Kerr's avatar Greg Kerr Committed by Commit Bot

macOS V2 Sandbox: Sandbox utility processes.

This sandboxes utility processes with the V2 sandbox on macOS.

Bug: 689306
Change-Id: Ie7cca11834f060a4c0f59862f68de95c79893288
Reviewed-on: https://chromium-review.googlesource.com/817515Reviewed-by: default avatarRobert Sesek <rsesek@chromium.org>
Reviewed-by: default avatarNasko Oskov <nasko@chromium.org>
Commit-Queue: Greg Kerr <kerrnel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#524233}
parent 9f6510f2
......@@ -659,8 +659,13 @@ class ContentMainRunnerImpl : public ContentMainRunner {
service_manager::SandboxTypeFromCommandLine(command_line),
params.sandbox_info));
#elif defined(OS_MACOSX)
// Do not initialize the sandbox at this point if the V2
// sandbox is enabled for the process type.
bool v2_enabled = base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableV2Sandbox);
if (process_type == switches::kRendererProcess ||
process_type == switches::kPpapiPluginProcess ||
process_type == switches::kPpapiPluginProcess || v2_enabled ||
(delegate_ && delegate_->DelaySandboxInitialization(process_type))) {
// On OS X the renderer sandbox needs to be initialized later in the
// startup sequence in RendererMainPlatformDelegate::EnableSandbox().
......
......@@ -21,7 +21,10 @@
#include "content/public/common/sandboxed_process_launcher_delegate.h"
#include "mojo/edk/embedder/scoped_platform_handle.h"
#include "sandbox/mac/seatbelt_exec.h"
#include "services/service_manager/sandbox/mac/common_v2.sb.h"
#include "services/service_manager/sandbox/mac/renderer_v2.sb.h"
#include "services/service_manager/sandbox/mac/utility.sb.h"
#include "services/service_manager/sandbox/sandbox.h"
namespace content {
namespace internal {
......@@ -54,19 +57,42 @@ void ChildProcessLauncherHelper::BeforeLaunchOnLauncherThread(
options->environ = delegate_->GetEnvironment();
bool no_sandbox = command_line_->HasSwitch(switches::kNoSandbox);
auto sandbox_type =
service_manager::SandboxTypeFromCommandLine(*command_line_);
bool no_sandbox = command_line_->HasSwitch(switches::kNoSandbox) ||
service_manager::IsUnsandboxedSandboxType(sandbox_type);
bool v2_process = GetProcessType() == switches::kRendererProcess ||
GetProcessType() == switches::kUtilityProcess;
bool use_v2 =
v2_process && base::FeatureList::IsEnabled(features::kMacV2Sandbox);
if (use_v2 && !no_sandbox) {
// Generate the profile string.
std::string profile =
std::string(service_manager::kSeatbeltPolicyString_common_v2);
if (GetProcessType() == switches::kRendererProcess) {
profile += service_manager::kSeatbeltPolicyString_renderer_v2;
} else if (GetProcessType() == switches::kUtilityProcess) {
profile += service_manager::kSeatbeltPolicyString_utility;
}
if (base::FeatureList::IsEnabled(features::kMacV2Sandbox) &&
GetProcessType() == switches::kRendererProcess && !no_sandbox) {
// Disable os logging to com.apple.diagnosticd which is a performance
// problem.
options->environ.insert(std::make_pair("OS_ACTIVITY_MODE", "disable"));
seatbelt_exec_client_ = std::make_unique<sandbox::SeatbeltExecClient>();
seatbelt_exec_client_->SetProfile(
service_manager::kSeatbeltPolicyString_renderer_v2);
SetupRendererSandboxParameters(seatbelt_exec_client_.get());
seatbelt_exec_client_->SetProfile(profile);
if (GetProcessType() == switches::kRendererProcess) {
SetupRendererSandboxParameters(seatbelt_exec_client_.get());
} else {
SetupUtilitySandboxParameters(seatbelt_exec_client_.get(),
*command_line_.get());
}
int pipe = seatbelt_exec_client_->SendProfileAndGetFD();
......
......@@ -5,17 +5,24 @@
#ifndef CONTENT_BROWSER_SANDBOX_PARAMETERS_MAC_H_
#define CONTENT_BROWSER_SANDBOX_PARAMETERS_MAC_H_
namespace base {
class CommandLine;
}
namespace sandbox {
class SeatbeltExecClient;
}
namespace content {
// Populates the |client| with the parameters that the sandbox needs to
// resolve information that cannot be known at build time, such as
// the user's home directory.
// All of the below functions populate the |client| with the parameters that the
// sandbox needs to resolve information that cannot be known at build time, such
// as the user's home directory.
void SetupRendererSandboxParameters(sandbox::SeatbeltExecClient* client);
void SetupUtilitySandboxParameters(sandbox::SeatbeltExecClient* client,
const base::CommandLine& command_line);
} // namespace content
#endif // CONTENT_BROWSER_SANDBOX_PARAMETERS_MAC_H_
......@@ -39,9 +39,7 @@ std::string GetOSVersion() {
return std::to_string(final_os_version);
}
} // namespace
void SetupRendererSandboxParameters(sandbox::SeatbeltExecClient* client) {
void SetupCommonSandboxParameters(sandbox::SeatbeltExecClient* client) {
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
bool enable_logging =
......@@ -53,14 +51,6 @@ void SetupRendererSandboxParameters(sandbox::SeatbeltExecClient* client) {
service_manager::SandboxMac::kSandboxDisableDenialLogging,
!enable_logging));
std::string homedir =
service_manager::SandboxMac::GetCanonicalPath(base::GetHomeDir()).value();
CHECK(client->SetParameter(
service_manager::SandboxMac::kSandboxHomedirAsLiteral, homedir));
CHECK(client->SetParameter(service_manager::SandboxMac::kSandboxOSVersion,
GetOSVersion()));
std::string bundle_path =
service_manager::SandboxMac::GetCanonicalPath(base::mac::MainBundlePath())
.value();
......@@ -89,6 +79,36 @@ void SetupRendererSandboxParameters(sandbox::SeatbeltExecClient* client) {
CHECK(client->SetParameter(service_manager::SandboxMac::kSandboxComponentPath,
component_path_canonical));
#endif
CHECK(client->SetParameter(service_manager::SandboxMac::kSandboxOSVersion,
GetOSVersion()));
std::string homedir =
service_manager::SandboxMac::GetCanonicalPath(base::GetHomeDir()).value();
CHECK(client->SetParameter(
service_manager::SandboxMac::kSandboxHomedirAsLiteral, homedir));
}
} // namespace
void SetupRendererSandboxParameters(sandbox::SeatbeltExecClient* client) {
SetupCommonSandboxParameters(client);
}
void SetupUtilitySandboxParameters(sandbox::SeatbeltExecClient* client,
const base::CommandLine& command_line) {
SetupCommonSandboxParameters(client);
base::FilePath permitted_dir =
command_line.GetSwitchValuePath(switches::kUtilityProcessAllowedDir);
if (!permitted_dir.empty()) {
std::string permitted_dir_canonical =
service_manager::SandboxMac::GetCanonicalPath(permitted_dir).value();
CHECK(
client->SetParameter(service_manager::SandboxMac::kSandboxPermittedDir,
permitted_dir_canonical));
}
}
} // namespace content
......@@ -24,6 +24,7 @@
#include "content/test/test_content_client.h"
#include "sandbox/mac/sandbox_compiler.h"
#include "sandbox/mac/seatbelt_exec.h"
#include "services/service_manager/sandbox/mac/common_v2.sb.h"
#include "services/service_manager/sandbox/mac/renderer_v2.sb.h"
#include "services/service_manager/sandbox/mac/sandbox_mac.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -91,8 +92,10 @@ class SandboxV2Test : public base::MultiProcessTest {};
MULTIPROCESS_TEST_MAIN(SandboxProfileProcess) {
TestContentClient content_client;
sandbox::SandboxCompiler compiler(
service_manager::kSeatbeltPolicyString_renderer_v2);
const std::string profile =
std::string(service_manager::kSeatbeltPolicyString_common_v2) +
service_manager::kSeatbeltPolicyString_renderer_v2;
sandbox::SandboxCompiler compiler(profile);
// Create the logging file and pass /bin/ls as the executable path.
base::ScopedTempDir temp_dir;
......
......@@ -7,6 +7,7 @@ action_foreach("package_sb_files") {
sources = [
"cdm.sb",
"common.sb",
"common_v2.sb",
"gpu.sb",
"nacl_loader.sb",
"ppapi.sb",
......
; Copyright 2017 The Chromium Authors. All rights reserved.
; Use of this source code is governed by a BSD-style license that can be
; found in the LICENSE file.
(version 1)
; Helper function to check if a param is set to true.
(define (param-true? str) (string=? (param str) "TRUE"))
; Helper function to determine if a parameter is defined or not.
(define (param-defined? str) (string? (param str)))
; Define constants for all of the parameter strings passed in.
(define browser-pid "BROWSER_PID")
(define bundle-id "BUNDLE_ID")
(define bundle-path "BUNDLE_PATH")
(define component-path "COMPONENT_PATH")
(define current-pid "CURRENT_PID")
(define disable-sandbox-denial-logging "DISABLE_SANDBOX_DENIAL_LOGGING")
(define enable-logging "ENABLE_LOGGING")
(define executable-path "EXECUTABLE_PATH")
(define homedir-as-literal "USER_HOMEDIR_AS_LITERAL")
(define log-file-path "LOG_FILE_PATH")
(define os-version (string->number (param "OS_VERSION")))
(define permitted-dir "PERMITTED_DIR")
; Backwards compatibility for 10.9
(if (not (defined? 'path))
(define path literal))
(if (not (defined? 'iokit-registry-entry-class))
(define iokit-registry-entry-class iokit-user-client-class))
; --enable-sandbox-logging causes the sandbox to log failures to the syslog.
(if (param-true? disable-sandbox-denial-logging)
(deny default (with no-log))
(deny default))
(if (param-true? enable-logging) (debug deny))
; Allow sending signals to self - https://crbug.com/20370
(allow signal (target self))
; Consumes a subpath and appends it to the user's homedir path.
(define (user-homedir-path subpath)
(string-append (param homedir-as-literal) subpath))
; Allow logging for all processes.
(allow file-write* (path (param log-file-path)))
; Allow component builds to work.
(if (param-defined? component-path)
(allow file-read* (subpath (param component-path))))
(allow process-exec (path (param executable-path)))
(allow file-read* (path (param executable-path)))
(allow mach-lookup (global-name (string-append (param bundle-id)
".rohitfork."
(param browser-pid))))
; Allow realpath() to work.
(allow file-read-metadata (subpath "/"))
; All processes can read the bundle contents.
(allow file-read* (subpath (param bundle-path)))
; Allow reads of system libraries and frameworks.
(allow file-read-data
(subpath "/System/Library/Frameworks")
(subpath "/System/Library/PrivateFrameworks")
(subpath "/usr/lib"))
; Reads from /etc.
; This is read by CFPrefs calling getpwuid in a loop. libinfo then fails to
; contact any of the opendirectoryd mach services, and falls back to
; the /etc/passwd file for the user info. The access is OK because
; no actual password hashes are in /etc/passwd anymore.
(allow file-read-data (path "/private/etc/passwd"))
; Access to /dev.
(allow file-ioctl file-read-data file-write-data (path "/dev/dtracehelper"))
(allow file-read-data
(path "/dev/null")
(path "/dev/random")
(path "/dev/urandom"))
(if (= os-version 1013)
(begin (allow file-read-data (subpath "/private/var/db/timezone"))
(allow file-read-data (subpath "/usr/share/zoneinfo.default"))))
(if (< os-version 1013)
(allow file-read-data (subpath "/usr/share/zoneinfo")))
; Reads from /Library.
(allow file-read-data
(path "/Library/Preferences/.GlobalPreferences.plist")
(path "/System/Library/CoreServices/SystemVersion.plist"))
; Reads from /usr.
(allow file-read-data
(subpath "/usr/share/icu")
(subpath "/usr/share/locale"))
; Access to the home directory.
(allow file-read-data
(path (user-homedir-path "/Library/Preferences/.GlobalPreferences.plist"))
(regex (user-homedir-path #"/Library/Preferences/ByHost/.GlobalPreferences.*")))
; Mach IPC needed by all Chromium Helper instances.
(allow mach-lookup
; crbug.com/792229
(global-name "com.apple.logd")
(global-name "com.apple.system.logger")
; crbug.com/792228
(global-name "com.apple.system.opendirectoryd.libinfo"))
; sysctls permitted.
(if (= os-version 1009)
(allow sysctl-read)
; else
(allow sysctl-read
(sysctl-name "hw.activecpu")
(sysctl-name "hw.busfrequency_compat")
(sysctl-name "hw.byteorder")
(sysctl-name "hw.cachelinesize_compat")
(sysctl-name "hw.cpufrequency_compat")
(sysctl-name "hw.cputype")
(sysctl-name "hw.machine")
(sysctl-name "hw.ncpu")
(sysctl-name "hw.pagesize_compat")
(sysctl-name "hw.physicalcpu_max")
(sysctl-name "hw.tbfrequency_compat")
(sysctl-name "hw.vectorunit")
(sysctl-name "kern.hostname")
(sysctl-name "kern.maxfilesperproc")
(sysctl-name "kern.osrelease")
(sysctl-name "kern.ostype")
(sysctl-name "kern.osversion")
(sysctl-name (string-append "kern.proc.pid." (param current-pid)))
(sysctl-name "kern.usrstack64")
(sysctl-name "kern.version")
(sysctl-name "sysctl.proc_cputype")))
; Copyright 2017 The Chromium Authors. All rights reserved.
; Use of this source code is governed by a BSD-style license that can be
; found in the LICENSE file.
(version 1)
; The top of this will be the V2 common profile.
; Helper function to check if a param is set to true.
(define (param-true? str) (string=? (param str) "TRUE"))
; Helper function to determine if a parameter is defined or not.
(define (param-defined? str) (string? (param str)))
; Define constants for all of the parameter strings passed in.
(define browser-pid "BROWSER_PID")
(define bundle-id "BUNDLE_ID")
(define bundle-path "BUNDLE_PATH")
(define component-path "COMPONENT_PATH")
(define current-pid "CURRENT_PID")
(define disable-sandbox-denial-logging "DISABLE_SANDBOX_DENIAL_LOGGING")
(define enable-logging "ENABLE_LOGGING")
(define executable-path "EXECUTABLE_PATH")
(define homedir-as-literal "USER_HOMEDIR_AS_LITERAL")
(define log-file-path "LOG_FILE_PATH")
(define os-version (string->number (param "OS_VERSION")))
; Backwards compatibility for 10.9
(if (not (defined? 'path))
(define path literal))
(if (not (defined? 'iokit-registry-entry-class))
(define iokit-registry-entry-class iokit-user-client-class))
; --enable-sandbox-logging causes the sandbox to log failures to the syslog.
(if (param-true? disable-sandbox-denial-logging)
(deny default (with no-log))
(deny default))
(if (param-true? enable-logging) (debug deny))
; Allow sending signals to self - https://crbug.com/20370
(allow signal (target self))
; Consumes a subpath and appends it to the user's homedir path.
(define (user-homedir-path subpath)
(string-append (param homedir-as-literal) subpath))
; Allow logging for all processes.
(allow file-write* (path (param log-file-path)))
; Allow component builds to work.
(if (param-defined? component-path)
(allow file-read* (subpath (param component-path))))
(allow process-exec (path (param executable-path)))
(allow file-read* (path (param executable-path)))
(allow mach-lookup (global-name (string-append (param bundle-id)
".rohitfork."
(param browser-pid))))
; Allow realpath() to work.
(allow file-read-metadata (subpath "/"))
; --- The contents of common.sb implicitly included here. ---
; Allow cf prefs to work.
(allow user-preference-read)
; All processes can read the bundle contents.
(allow file-read* (subpath (param bundle-path)))
; End of common.sb?
(allow file-ioctl file-read-data file-write-data (path "/dev/dtracehelper"))
; File reads.
; Reads from the home directory.
(allow file-read-data
(path (user-homedir-path "/.CFUserTextEncoding"))
(path (user-homedir-path "/Library/Preferences/com.apple.universalaccess.plist"))
(path (user-homedir-path "/Library/Preferences/.GlobalPreferences.plist"))
(regex (user-homedir-path #"/Library/Preferences/ByHost/.GlobalPreferences.*"))
(subpath (user-homedir-path "/Library/Fonts")))
; Reads of /dev devices.
(allow file-read-data
(path "/dev/autofs_nowait")
(path "/dev/fd")
(path "/dev/null")
(path "/dev/random")
(path "/dev/urandom"))
(path "/dev/fd"))
(allow file-write-data (path "/dev/null"))
; Reads from /etc.
; This is read by CFPrefs calling getpwuid in a loop. libinfo then fails to
; contact any of the opendirectoryd mach services, and falls back to
; the /etc/passwd file for the user info. The access is OK because
; no actual password hashes are in /etc/passwd anymore.
(allow file-read-data (path "/private/etc/passwd"))
; Reads from /usr.
(allow file-read-data
(subpath "/usr/lib")
(subpath "/usr/share/icu")
(subpath "/usr/share/locale"))
(if (= os-version 1013)
(begin (allow file-read-data (subpath "/private/var/db/timezone"))
(allow file-read-data (subpath "/usr/share/zoneinfo.default"))))
(if (< os-version 1013)
(allow file-read-data (subpath "/usr/share/zoneinfo")))
; Reads from /Library.
(allow file-read-data
(subpath "/Library/Fonts")
(path "/Library/Preferences/.GlobalPreferences.plist"))
(allow file-read-data (subpath "/Library/Fonts"))
; Reads from /System.
(allow file-read-data
(path "/System/Library/CoreServices/checkfixlist")
(path "/System/Library/CoreServices/CoreTypes.bundle/Contents/Library/AppExceptions.bundle/Exceptions.plist")
(path "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/Exceptions.plist")
(path "/System/Library/CoreServices/SystemVersion.plist")
(path "/System/Library/Preferences/Logging/Subsystems/com.apple.SkyLight.plist")
(subpath "/System/Library/ColorSync/Profiles")
(subpath "/System/Library/CoreServices/SystemAppearance.bundle")
(subpath "/System/Library/CoreServices/SystemVersion.bundle")
(subpath "/System/Library/Fonts")
(subpath "/System/Library/Frameworks")
(subpath "/System/Library/LinguisticData")
(subpath "/System/Library/PrivateFrameworks"))
(subpath "/System/Library/LinguisticData"))
; IOKit
(allow iokit-open
......@@ -137,19 +45,19 @@
(allow ipc-posix-shm-read-data
(ipc-posix-name "apple.cfprefs.317580v1")
(ipc-posix-name "apple.cfprefs.daemonv1")
; crbug.com/792217
(ipc-posix-name "apple.shm.notification_center"))
; mach IPC
(allow mach-lookup
; crbug.com/792257
(global-name "com.apple.distributed_notifications@Uv3")
(global-name "com.apple.fonts")
; crbug.com/756145, crbug.com/786615
(global-name "com.apple.FontObjectsServer")
(global-name "com.apple.logd")
(global-name "com.apple.lsd.mapdb")
(global-name "com.apple.system.logger")
; crbug.com/792217
(global-name "com.apple.system.notification_center")
(global-name "com.apple.system.opendirectoryd.libinfo")
(global-name "com.apple.windowserver.active"))
; MacOS dropped FontServer to replace it with the (XPC based) com.apple.fonts,
......@@ -161,30 +69,3 @@
; /System/Library/Asssets/com_apple_MobileAsset_Font*.
; (https://crbug.com/662686)
(allow file-read* (extension "com.apple.app-sandbox.read"))
; sysctl
(if (= os-version 1009)
(allow sysctl-read)
; else
(allow sysctl-read
(sysctl-name "hw.activecpu")
(sysctl-name "hw.busfrequency_compat")
(sysctl-name "hw.byteorder")
(sysctl-name "hw.cachelinesize_compat")
(sysctl-name "hw.cpufrequency_compat")
(sysctl-name "hw.cputype")
(sysctl-name "hw.machine")
(sysctl-name "hw.ncpu")
(sysctl-name "hw.pagesize_compat")
(sysctl-name "hw.physicalcpu_max")
(sysctl-name "hw.tbfrequency_compat")
(sysctl-name "hw.vectorunit")
(sysctl-name "kern.hostname")
(sysctl-name "kern.maxfilesperproc")
(sysctl-name "kern.osrelease")
(sysctl-name "kern.ostype")
(sysctl-name "kern.osversion")
(sysctl-name (string-append "kern.proc.pid." (param current-pid)))
(sysctl-name "kern.usrstack64")
(sysctl-name "kern.version")
(sysctl-name "sysctl.proc_cputype")))
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment