diff options
author | jeremy@chromium.org <jeremy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-05 12:50:34 +0000 |
---|---|---|
committer | jeremy@chromium.org <jeremy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-05 12:50:34 +0000 |
commit | 824083c52c5689198290e24938793ce4ccc6e683 (patch) | |
tree | a9a8145fff77340dc6c88ee787fa9653c421e35a /chrome/common | |
parent | 498fd8ed8d91dd428dab8b7d40029a62aa42734e (diff) | |
download | chromium_src-824083c52c5689198290e24938793ce4ccc6e683.zip chromium_src-824083c52c5689198290e24938793ce4ccc6e683.tar.gz chromium_src-824083c52c5689198290e24938793ce4ccc6e683.tar.bz2 |
Sandbox Worker process on the Mac.
* Add plumbing to allow multiple Sandbox profiles on OS X.
* Separate sandbox_init_wrapper into platform specific files.
* Sandbox Worker process & add plumbing to Sandbox utility process when we bring that up.
* Remove mention of stale bugs in utility process on Mac.
BUG=23582
TEST=Worker process should work.
Review URL: http://codereview.chromium.org/341033
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@31089 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/common')
-rw-r--r-- | chrome/common/chrome_switches.cc | 4 | ||||
-rw-r--r-- | chrome/common/chrome_switches.h | 1 | ||||
-rw-r--r-- | chrome/common/sandbox_init_wrapper.cc | 44 | ||||
-rw-r--r-- | chrome/common/sandbox_init_wrapper.h | 18 | ||||
-rw-r--r-- | chrome/common/sandbox_init_wrapper_linux.cc | 14 | ||||
-rw-r--r-- | chrome/common/sandbox_init_wrapper_mac.cc | 49 | ||||
-rw-r--r-- | chrome/common/sandbox_init_wrapper_win.cc | 32 | ||||
-rw-r--r-- | chrome/common/sandbox_mac.h | 25 | ||||
-rw-r--r-- | chrome/common/sandbox_mac.mm | 46 |
9 files changed, 174 insertions, 59 deletions
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 86e9467..60736d2 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -601,6 +601,10 @@ const char kUtilityCmdPrefix[] = "utility-cmd-prefix"; // Causes the process to run as a utility subprocess. const char kUtilityProcess[] = "utility"; +// The utility process is sandboxed, with access to one directory. This flag +// specifies the directory that can be accessed. +const char kUtilityProcessAllowedDir[] = "utility-allowed-dir"; + // Will add kWaitForDebugger to every child processes. If a value is passed, it // will be used as a filter to determine if the child process should have the // kWaitForDebugger flag passed on or not. diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 89ecf9f..2d387cd 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -169,6 +169,7 @@ extern const char kUserDataDir[]; extern const char kUserScriptsDir[]; extern const char kUtilityCmdPrefix[]; extern const char kUtilityProcess[]; +extern const char kUtilityProcessAllowedDir[]; extern const char kWaitForDebuggerChildren[]; extern const char kWebWorkerProcessPerCore[]; extern const char kWebWorkerShareProcesses[]; diff --git a/chrome/common/sandbox_init_wrapper.cc b/chrome/common/sandbox_init_wrapper.cc deleted file mode 100644 index 31488f7..0000000 --- a/chrome/common/sandbox_init_wrapper.cc +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 2009 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. - -#include "chrome/common/sandbox_init_wrapper.h" - -#include "base/command_line.h" -#include "chrome/common/chrome_switches.h" - -#if defined(OS_WIN) - -void SandboxInitWrapper::SetServices(sandbox::SandboxInterfaceInfo* info) { - if (info) { - broker_services_ = info->broker_services; - target_services_ = info->target_services; - } -} - -#endif - -void SandboxInitWrapper::InitializeSandbox(const CommandLine& command_line, - const std::string& process_type) { -#if defined(OS_WIN) - if (!target_services_) - return; -#endif - if (!command_line.HasSwitch(switches::kNoSandbox)) { - if ((process_type == switches::kRendererProcess) || - (process_type == switches::kWorkerProcess) || - (process_type == switches::kNaClProcess) || - (process_type == switches::kUtilityProcess) || - (process_type == switches::kPluginProcess && - command_line.HasSwitch(switches::kSafePlugins))) { -#if defined(OS_WIN) - target_services_->Init(); -#elif defined(OS_MACOSX) - // We just cache the process type so we can configure the sandbox - // correctly, see renderer_main_platform_delegate_mac.cc for one of those - // places. - process_type_ = process_type; -#endif - } - } -} diff --git a/chrome/common/sandbox_init_wrapper.h b/chrome/common/sandbox_init_wrapper.h index a1c2de9..d1652d2 100644 --- a/chrome/common/sandbox_init_wrapper.h +++ b/chrome/common/sandbox_init_wrapper.h @@ -33,7 +33,10 @@ class SandboxInitWrapper { // Initialize the sandbox for renderer and plug-in processes, depending on // the command line flags. The browser process is not sandboxed. - void InitializeSandbox(const CommandLine& parsed_command_line, + // Returns true if the sandbox was initialized succesfully, false if an error + // occurred. If process_type isn't one that needs sandboxing true is always + // returned. + bool InitializeSandbox(const CommandLine& parsed_command_line, const std::string& process_type); private: sandbox::BrokerServices* broker_services_; @@ -50,17 +53,12 @@ class SandboxInitWrapper { // Initialize the sandbox for renderer and plug-in processes, depending on // the command line flags. The browser process is not sandboxed. - void InitializeSandbox(const CommandLine& parsed_command_line, + // Returns true if the sandbox was initialized succesfully, false if an error + // occurred. If process_type isn't one that needs sandboxing true is always + // returned. + bool InitializeSandbox(const CommandLine& parsed_command_line, const std::string& process_type); -#if defined(OS_MACOSX) - // We keep the process type so we can configure the sandbox as needed. - public: - std::string ProcessType() const { return process_type_; } - private: - std::string process_type_; -#endif - private: DISALLOW_COPY_AND_ASSIGN(SandboxInitWrapper); }; diff --git a/chrome/common/sandbox_init_wrapper_linux.cc b/chrome/common/sandbox_init_wrapper_linux.cc new file mode 100644 index 0000000..daf02d3 --- /dev/null +++ b/chrome/common/sandbox_init_wrapper_linux.cc @@ -0,0 +1,14 @@ +// Copyright (c) 2009 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. + +#include "chrome/common/sandbox_init_wrapper.h" + +#include "base/command_line.h" +#include "chrome/common/chrome_switches.h" + +bool SandboxInitWrapper::InitializeSandbox(const CommandLine& command_line, + const std::string& process_type) { + // TODO(port): Does Linux need to do anything here? + return true; +} diff --git a/chrome/common/sandbox_init_wrapper_mac.cc b/chrome/common/sandbox_init_wrapper_mac.cc new file mode 100644 index 0000000..6ce09d3 --- /dev/null +++ b/chrome/common/sandbox_init_wrapper_mac.cc @@ -0,0 +1,49 @@ +// Copyright (c) 2009 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. + +#include "chrome/common/sandbox_init_wrapper.h" + +#include "base/command_line.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/sandbox_mac.h" + +bool SandboxInitWrapper::InitializeSandbox(const CommandLine& command_line, + const std::string& process_type) { + if (command_line.HasSwitch(switches::kNoSandbox)) + return true; + + sandbox::SandboxProcessType sandbox_process_type; + FilePath allowed_dir; // Empty by default. + + if (process_type.empty()) { + // Browser process isn't sandboxed. + return true; + } else if (process_type == switches::kRendererProcess) { + // Renderer process sandbox. + sandbox_process_type = sandbox::SANDBOX_TYPE_RENDERER; + } else if (process_type == switches::kUtilityProcess) { + // Utility process sandbox. + sandbox_process_type = sandbox::SANDBOX_TYPE_UTILITY; + allowed_dir = FilePath::FromWStringHack( + command_line.GetSwitchValue(switches::kUtilityProcessAllowedDir)); + } else if (process_type == switches::kWorkerProcess) { + // Worker process sandbox. + sandbox_process_type = sandbox::SANDBOX_TYPE_WORKER; + } else if ((process_type == switches::kNaClProcess) || + (process_type == switches::kPluginProcess) || + (process_type == switches::kProfileImportProcess)) { + return true; + } else { + // Failsafe: If you hit an unreached here, is your new process type in need + // of sandboxing? + NOTREACHED(); + return true; + } + + // Warm up APIs before turning on the sandbox. + sandbox::SandboxWarmup(); + + // Actually sandbox the process. + return sandbox::EnableSandbox(sandbox_process_type, allowed_dir); +} diff --git a/chrome/common/sandbox_init_wrapper_win.cc b/chrome/common/sandbox_init_wrapper_win.cc new file mode 100644 index 0000000..fe5c6df --- /dev/null +++ b/chrome/common/sandbox_init_wrapper_win.cc @@ -0,0 +1,32 @@ +// Copyright (c) 2009 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. + +#include "chrome/common/sandbox_init_wrapper.h" + +#include "base/command_line.h" +#include "chrome/common/chrome_switches.h" + +void SandboxInitWrapper::SetServices(sandbox::SandboxInterfaceInfo* info) { + if (info) { + broker_services_ = info->broker_services; + target_services_ = info->target_services; + } +} + +bool SandboxInitWrapper::InitializeSandbox(const CommandLine& command_line, + const std::string& process_type) { + if (command_line.HasSwitch(switches::kNoSandbox)) + return true; + if ((process_type == switches::kRendererProcess) || + (process_type == switches::kWorkerProcess) || + (process_type == switches::kNaClProcess) || + (process_type == switches::kUtilityProcess) || + (process_type == switches::kPluginProcess && + command_line.HasSwitch(switches::kSafePlugins))) { + if (!target_services_) + return false; + target_services_->Init(); + } + return true; +} diff --git a/chrome/common/sandbox_mac.h b/chrome/common/sandbox_mac.h index c747e20..a8a55b0 100644 --- a/chrome/common/sandbox_mac.h +++ b/chrome/common/sandbox_mac.h @@ -5,14 +5,37 @@ #ifndef CHROME_COMMON_SANDBOX_MAC_H_ #define CHROME_COMMON_SANDBOX_MAC_H_ +#include "base/file_path.h" + namespace sandbox { +enum SandboxProcessType { + SANDBOX_TYPE_RENDERER, + + // Worker process has *everything* not needed for Cocoa locked down. + SANDBOX_TYPE_WORKER, + + // Utility process is as restrictive as the worker process except full access + // is allowed to one configurable directory. + SANDBOX_TYPE_UTILITY, +}; + // Warm up System APIs that empirically need to be accessed before the Sandbox // is turned on. void SandboxWarmup(); // Turns on the OS X sandbox for this process. -bool EnableSandbox(); +// |sandbox_type| - type of Sandbox to use. +// |allowed_dir| - directory to allow access to, currently the only sandbox +// profile that supports this is SANDBOX_TYPE_UTILITY . +// +// |allowed_dir| must be a "simple" string since it's placed as is in a regex +// i.e. it must not contain quotation characters, escaping or any characters +// that might have special meaning when blindly substituted into a regular +// expression - crbug.com/26492 . +// Returns true on success, false if an error occurred enabling the sandbox. +bool EnableSandbox(SandboxProcessType sandbox_type, + const FilePath& allowed_dir); } // namespace sandbox diff --git a/chrome/common/sandbox_mac.mm b/chrome/common/sandbox_mac.mm index ae55b52..6eac34c 100644 --- a/chrome/common/sandbox_mac.mm +++ b/chrome/common/sandbox_mac.mm @@ -84,11 +84,42 @@ void SandboxWarmup() { } // Turns on the OS X sandbox for this process. -bool EnableSandbox() { - // For the renderer, we give it a custom sandbox to lock things down as - // tightly as possible, while still enabling drawing. +bool EnableSandbox(SandboxProcessType sandbox_type, + const FilePath& allowed_dir) { + // Sanity - currently only SANDBOX_TYPE_UTILITY supports a directory being + // passed in. + if (sandbox_type != SANDBOX_TYPE_UTILITY) { + DCHECK(allowed_dir.empty()) + << "Only SANDBOX_TYPE_UTILITY allows a custom directory parameter."; + } else { + DCHECK(!allowed_dir.empty()) + << "SANDBOX_TYPE_UTILITY " + << "needs a custom directory parameter, but an empty one was provided."; + } + + // We use a custom sandbox definition file to lock things down as + // tightly as possible. + // TODO(jeremy): Look at using include syntax to unify common parts of sandbox + // definition files. + NSString* sandbox_config_filename = nil; + switch (sandbox_type) { + case SANDBOX_TYPE_RENDERER: + sandbox_config_filename = @"renderer"; + break; + case SANDBOX_TYPE_WORKER: + sandbox_config_filename = @"worker"; + break; + case SANDBOX_TYPE_UTILITY: + sandbox_config_filename = @"utility"; + break; + default: + NOTREACHED(); + return false; + } + NSString* sandbox_profile_path = - [mac_util::MainAppBundle() pathForResource:@"renderer" ofType:@"sb"]; + [mac_util::MainAppBundle() pathForResource:sandbox_config_filename + ofType:@"sb"]; NSString* sandbox_data = [NSString stringWithContentsOfFile:sandbox_profile_path encoding:NSUTF8StringEncoding @@ -108,6 +139,13 @@ bool EnableSandbox() { withString:@""]; } + if (!allowed_dir.empty()) { + NSString* allowed_dir_ns = base::SysUTF8ToNSString(allowed_dir.value()); + sandbox_data = [sandbox_data + stringByReplacingOccurrencesOfString:@"DIR_TO_ALLOW_ACCESS" + withString:allowed_dir_ns]; + } + int32 major_version, minor_version, bugfix_version; base::SysInfo::OperatingSystemVersionNumbers(&major_version, &minor_version, &bugfix_version); |