diff options
author | jochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-25 20:55:24 +0000 |
---|---|---|
committer | jochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-25 20:55:24 +0000 |
commit | dbd82584da433118de55fb3319be12c4c3536cf2 (patch) | |
tree | bba6762062c6bff54dce8cadcb2a7d19a7ea19eb | |
parent | 0cc75fe16b6e272176ee8db613ceef0990825bcf (diff) | |
download | chromium_src-dbd82584da433118de55fb3319be12c4c3536cf2.zip chromium_src-dbd82584da433118de55fb3319be12c4c3536cf2.tar.gz chromium_src-dbd82584da433118de55fb3319be12c4c3536cf2.tar.bz2 |
Load mac sandbox definitions from resources instead of the bundle.
Also, move all mac sandbox unittests to content
BUG=90443
TEST=content_unittests
Review URL: http://codereview.chromium.org/8589001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@111614 0039d316-1c4b-4281-b951-d872f2087c98
38 files changed, 356 insertions, 193 deletions
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc index 380e0553..c015c0b 100644 --- a/chrome/app/chrome_main_delegate.cc +++ b/chrome/app/chrome_main_delegate.cc @@ -282,8 +282,12 @@ bool SubprocessNeedsResourceBundle(const std::string& process_type) { process_type == switches::kZygoteProcess || #endif #if defined(OS_MACOSX) - // Mac needs them to for scrollbar related images. + // Mac needs them too for scrollbar related images and for sandbox + // profiles. process_type == switches::kWorkerProcess || + process_type == switches::kNaClLoaderProcess || + process_type == switches::kPpapiPluginProcess || + process_type == switches::kPpapiBrokerProcess || #endif process_type == switches::kRendererProcess || process_type == switches::kUtilityProcess; @@ -607,7 +611,10 @@ void ChromeMainDelegate::PreSandboxStartup() { // sources. The language should have been passed in to us from the // browser process as a command line flag. DCHECK(command_line.HasSwitch(switches::kLang) || - process_type == switches::kZygoteProcess); + process_type == switches::kZygoteProcess || + process_type == switches::kNaClLoaderProcess || + process_type == switches::kPpapiBrokerProcess || + process_type == switches::kPpapiPluginProcess); // TODO(markusheintz): The command line flag --lang is actually processed // by the CommandLinePrefStore, and made available through the PrefService diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index a9e39bd..630f21a 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd @@ -167,9 +167,6 @@ <if expr="pp_ifdef('chromeos') and pp_ifdef('_google_chrome')"> <include name="IDR_HELP_MANIFEST" file="resources\help_app\manifest.json" type="BINDATA" /> </if> - <if expr="pp_ifdef('is_macosx')"> - <include name="IDR_NACL_SANDBOX_DEFINITION" file="nacl_loader.sb" type="BINDATA" /> - </if> </includes> </release> </grit> diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index b4c09eb..e696465 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -4447,9 +4447,6 @@ '$(SDKROOT)/System/Library/Frameworks/QuartzCore.framework', '$(SDKROOT)/System/Library/Frameworks/SecurityInterface.framework', ], - 'mac_bundle_resources': [ - 'browser/nacl_loader.sb', - ], }, 'dependencies': [ '../content/content.gyp:closure_blocks_leopard_compat', diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi index 3f2f4871..ed15ce2 100644 --- a/chrome/chrome_common.gypi +++ b/chrome/chrome_common.gypi @@ -76,6 +76,7 @@ 'common/chrome_notification_types.h', 'common/chrome_plugin_messages.h', 'common/chrome_result_codes.h', + 'common/chrome_sandbox_type_mac.h', 'common/chrome_utility_messages.h', 'common/chrome_version_info.cc', 'common/chrome_version_info_linux.cc', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 4ed0c4c..c6a5917 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -2011,11 +2011,6 @@ 'tools/convert_dict/convert_dict_unittest.cc', '../content/browser/tab_contents/navigation_controller_unittest.cc', '../content/browser/tab_contents/render_view_host_manager_unittest.cc', - '../content/common/sandbox_mac_diraccess_unittest.mm', - '../content/common/sandbox_mac_fontloading_unittest.mm', - '../content/common/sandbox_mac_unittest_helper.h', - '../content/common/sandbox_mac_unittest_helper.mm', - '../content/common/sandbox_mac_system_access_unittest.mm', '../testing/gtest_mac_unittest.mm', '../third_party/cld/encodings/compact_lang_det/compact_lang_det_unittest_small.cc', '../ui/views/test/test_views_delegate.cc', diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc index 9c8ca65..da07553 100644 --- a/chrome/common/chrome_content_client.cc +++ b/chrome/common/chrome_content_client.cc @@ -21,6 +21,7 @@ #include "chrome/common/render_messages.h" #include "chrome/default_plugin/plugin_main.h" #include "content/public/common/pepper_plugin_info.h" +#include "grit/common_resources.h" #include "remoting/client/plugin/pepper_entrypoints.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" @@ -30,6 +31,8 @@ #if defined(OS_WIN) #include "sandbox/src/sandbox.h" +#elif defined(OS_MACOSX) +#include "chrome/common/chrome_sandbox_type_mac.h" #endif namespace { @@ -399,4 +402,17 @@ bool ChromeContentClient::SandboxPlugin(CommandLine* command_line, } #endif +#if defined(OS_MACOSX) +bool ChromeContentClient::GetSandboxProfileForSandboxType( + int sandbox_type, + int* sandbox_profile_resource_id) const { + DCHECK(sandbox_profile_resource_id); + if (sandbox_type == CHROME_SANDBOX_TYPE_NACL_LOADER) { + *sandbox_profile_resource_id = IDR_NACL_SANDBOX_PROFILE; + return true; + } + return false; +} +#endif + } // namespace chrome diff --git a/chrome/common/chrome_content_client.h b/chrome/common/chrome_content_client.h index 6c252e1..d925c34 100644 --- a/chrome/common/chrome_content_client.h +++ b/chrome/common/chrome_content_client.h @@ -33,6 +33,12 @@ class ChromeContentClient : public content::ContentClient { virtual bool SandboxPlugin(CommandLine* command_line, sandbox::TargetPolicy* policy) OVERRIDE; #endif + +#if defined(OS_MACOSX) + virtual bool GetSandboxProfileForSandboxType( + int sandbox_type, + int* sandbox_profile_resource_id) const OVERRIDE; +#endif }; } // namespace chrome diff --git a/chrome/common/chrome_sandbox_type_mac.h b/chrome/common/chrome_sandbox_type_mac.h new file mode 100644 index 0000000..86aafef --- /dev/null +++ b/chrome/common/chrome_sandbox_type_mac.h @@ -0,0 +1,17 @@ +// Copyright (c) 2011 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. + +#ifndef CHROME_COMMON_CHROME_SANDBOX_TYPE_MAC_H_ +#define CHROME_COMMON_CHROME_SANDBOX_TYPE_MAC_H_ +#pragma once + +#include "content/public/common/sandbox_type_mac.h" + +enum ChromeSandboxType { + CHROME_SANDBOX_TYPE_FIRST_TYPE = content::SANDBOX_TYPE_AFTER_LAST_TYPE, + + CHROME_SANDBOX_TYPE_NACL_LOADER = CHROME_SANDBOX_TYPE_FIRST_TYPE, +}; + +#endif // CHROME_COMMON_CHROME_SANDBOX_TYPE_MAC_H_ diff --git a/chrome/common/common_resources.grd b/chrome/common/common_resources.grd index 619b92e..63c7a54 100644 --- a/chrome/common/common_resources.grd +++ b/chrome/common/common_resources.grd @@ -14,6 +14,9 @@ <include name="IDR_I18N_TEMPLATE_JS" file="..\browser\resources\shared\js\i18n_template.js" type="BINDATA" /> <include name="IDR_JSTEMPLATE_JS" file="..\browser\resources\shared\js\jstemplate_compiled.js" flattenhtml="true" type="BINDATA" /> <include name="IDR_WEB_APP_SCHEMA" file="web_app_schema.json" type="BINDATA" /> + <if expr="is_macosx"> + <include name="IDR_NACL_SANDBOX_PROFILE" file="nacl_loader.sb" type="BINDATA" /> + </if> </includes> </release> </grit> diff --git a/chrome/browser/nacl_loader.sb b/chrome/common/nacl_loader.sb index e881afe..e881afe 100644 --- a/chrome/browser/nacl_loader.sb +++ b/chrome/common/nacl_loader.sb diff --git a/chrome/nacl/nacl_main_platform_delegate_mac.mm b/chrome/nacl/nacl_main_platform_delegate_mac.mm index 6e3121e..b818ce7 100644 --- a/chrome/nacl/nacl_main_platform_delegate_mac.mm +++ b/chrome/nacl/nacl_main_platform_delegate_mac.mm @@ -9,6 +9,7 @@ #include "base/file_path.h" #include "base/logging.h" #include "base/native_library.h" +#include "chrome/common/chrome_sandbox_type_mac.h" #include "chrome/common/chrome_switches.h" #include "content/common/sandbox_mac.h" #include "content/public/common/sandbox_init.h" @@ -55,8 +56,8 @@ void NaClMainPlatformDelegate::InitSandboxTests(bool no_sandbox) { } void NaClMainPlatformDelegate::EnableSandbox() { - CHECK(content::InitializeSandbox()) << "Error initializing sandbox for " - << switches::kNaClLoaderProcess; + CHECK(content::InitializeSandbox(CHROME_SANDBOX_TYPE_NACL_LOADER, FilePath())) + << "Error initializing sandbox for " << switches::kNaClLoaderProcess; } bool NaClMainPlatformDelegate::RunSandboxTests() { diff --git a/content/DEPS b/content/DEPS index 471c32b..6c72faf 100644 --- a/content/DEPS +++ b/content/DEPS @@ -18,8 +18,12 @@ include_rules = [ # TODO(ben): remove this "+content/public/browser/native_web_keyboard_event.h", + "+grit/content_resources.h", + "+grit/webkit_chromium_resources.h", + "+grit/webkit_resources.h", + "+grit/webkit_strings.h", + "+dbus", - "+grit", "+gpu", "+net", "+ppapi", diff --git a/content/app/content_main.cc b/content/app/content_main.cc index 5720b49..678e96f 100644 --- a/content/app/content_main.cc +++ b/content/app/content_main.cc @@ -40,6 +40,7 @@ #include "base/mach_ipc_mac.h" #include "base/system_monitor/system_monitor.h" #include "content/browser/mach_broker_mac.h" +#include "content/common/sandbox_init_mac.h" #endif // OS_WIN #if defined(OS_POSIX) diff --git a/content/common/sandbox_init_mac.cc b/content/common/sandbox_init_mac.cc index 86cf9e6..7fd288d 100644 --- a/content/common/sandbox_init_mac.cc +++ b/content/common/sandbox_init_mac.cc @@ -12,21 +12,34 @@ namespace content { -bool InitializeSandbox() { - using sandbox::Sandbox; +bool InitializeSandbox(int sandbox_type, const FilePath& allowed_dir) { + // Warm up APIs before turning on the sandbox. + sandbox::Sandbox::SandboxWarmup(sandbox_type); + + // Actually sandbox the process. + return sandbox::Sandbox::EnableSandbox(sandbox_type, allowed_dir); +} + +// Fill in |sandbox_type| and |allowed_dir| based on the command line, returns +// false if the current process type doesn't need to be sandboxed or if the +// sandbox was disabled from the command line. +bool GetSandboxTypeFromCommandLine(int* sandbox_type, + FilePath* allowed_dir) { + DCHECK(sandbox_type); + DCHECK(allowed_dir); + + *sandbox_type = -1; + *allowed_dir = FilePath(); // Empty by default. const CommandLine& command_line = *CommandLine::ForCurrentProcess(); if (command_line.HasSwitch(switches::kNoSandbox)) - return true; - - Sandbox::SandboxProcessType sandbox_process_type; - FilePath allowed_dir; // Empty by default. + return false; std::string process_type = command_line.GetSwitchValueASCII(switches::kProcessType); if (process_type.empty()) { // Browser process isn't sandboxed. - return true; + return false; } else if (process_type == switches::kRendererProcess) { if (!command_line.HasSwitch(switches::kDisable3DAPIs) && !command_line.HasSwitch(switches::kDisableExperimentalWebGL) && @@ -34,41 +47,41 @@ bool InitializeSandbox() { // TODO(kbr): this check seems to be necessary only on this // platform because the sandbox is initialized later. Remove // this once this flag is removed. - return true; + return false; } else { - sandbox_process_type = Sandbox::SANDBOX_TYPE_RENDERER; + *sandbox_type = SANDBOX_TYPE_RENDERER; } } else if (process_type == switches::kUtilityProcess) { // Utility process sandbox. - sandbox_process_type = Sandbox::SANDBOX_TYPE_UTILITY; - allowed_dir = + *sandbox_type = SANDBOX_TYPE_UTILITY; + *allowed_dir = command_line.GetSwitchValuePath(switches::kUtilityProcessAllowedDir); } else if (process_type == switches::kWorkerProcess) { // Worker process sandbox. - sandbox_process_type = Sandbox::SANDBOX_TYPE_WORKER; - } else if (process_type == switches::kNaClLoaderProcess) { - // Native Client sel_ldr (user untrusted code) sandbox. - sandbox_process_type = Sandbox::SANDBOX_TYPE_NACL_LOADER; + *sandbox_type = SANDBOX_TYPE_WORKER; } else if (process_type == switches::kGpuProcess) { - sandbox_process_type = Sandbox::SANDBOX_TYPE_GPU; + *sandbox_type = SANDBOX_TYPE_GPU; } else if ((process_type == switches::kPluginProcess) || (process_type == switches::kServiceProcess) || (process_type == switches::kPpapiBrokerProcess)) { - return true; + return false; } else if (process_type == switches::kPpapiPluginProcess) { - sandbox_process_type = Sandbox::SANDBOX_TYPE_PPAPI; + *sandbox_type = SANDBOX_TYPE_PPAPI; } else { // Failsafe: If you hit an unreached here, is your new process type in need // of sandboxing? NOTREACHED() << "Unknown process type " << process_type; - return true; + return false; } + return true; +} - // Warm up APIs before turning on the sandbox. - Sandbox::SandboxWarmup(sandbox_process_type); - - // Actually sandbox the process. - return Sandbox::EnableSandbox(sandbox_process_type, allowed_dir); +bool InitializeSandbox() { + int sandbox_type = 0; + FilePath allowed_dir; + if (!GetSandboxTypeFromCommandLine(&sandbox_type, &allowed_dir)) + return true; + return InitializeSandbox(sandbox_type, allowed_dir); } } // namespace content diff --git a/content/common/sandbox_init_mac.h b/content/common/sandbox_init_mac.h new file mode 100644 index 0000000..08512b5 --- /dev/null +++ b/content/common/sandbox_init_mac.h @@ -0,0 +1,22 @@ +// Copyright (c) 2011 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. + +#ifndef CONTENT_COMMON_SANDBOX_INIT_MAC_H_ +#define CONTENT_COMMON_SANDBOX_INIT_MAC_H_ +#pragma once + +namespace content { + +// Initialize the sandbox for renderer, gpu, utility, worker, and plug-in +// processes, depending on the command line flags. Although The browser process +// is not sandboxed, this also needs to be called because it will initialize +// the broker code. +// 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(); + +} // namespace content + +#endif // CONTENT_COMMON_SANDBOX_INIT_MAC_H_ diff --git a/content/common/sandbox_mac.h b/content/common/sandbox_mac.h index 358c098..c9710c3 100644 --- a/content/common/sandbox_mac.h +++ b/content/common/sandbox_mac.h @@ -11,6 +11,7 @@ #include "base/basictypes.h" #include "base/hash_tables.h" #include "base/gtest_prod_util.h" +#include "content/public/common/sandbox_type_mac.h" class FilePath; @@ -57,44 +58,21 @@ class Sandbox { typedef base::hash_map<std::string, SandboxSubstring> SandboxVariableSubstitions; - enum SandboxProcessType { - SANDBOX_TYPE_FIRST_TYPE, // Placeholder to ease iteration. - - SANDBOX_TYPE_RENDERER = SANDBOX_TYPE_FIRST_TYPE, - - // The worker process uses the most restrictive sandbox which has almost - // *everything* locked down. Only a couple of /System/Library/ paths and - // some other very basic operations (e.g., reading metadata to allow - // following symlinks) are permitted. - SANDBOX_TYPE_WORKER, - - // Utility process is as restrictive as the worker process except full - // access is allowed to one configurable directory. - SANDBOX_TYPE_UTILITY, - - // Native Client sandbox for the user's untrusted code. - SANDBOX_TYPE_NACL_LOADER, - - // GPU process. - SANDBOX_TYPE_GPU, - - // The PPAPI plugin process. - SANDBOX_TYPE_PPAPI, - - SANDBOX_AFTER_TYPE_LAST_TYPE, // Placeholder to ease iteration. - }; - - // Warm up System APIs that empirically need to be accessed before the Sandbox - // is turned on. |sandbox_type| is the type of sandbox to warm up. - static void SandboxWarmup(SandboxProcessType sandbox_type); + // Warm up System APIs that empirically need to be accessed before the + // sandbox is turned on. |sandbox_type| is the type of sandbox to warm up. + // Valid |sandbox_type| values are defined by the enum SandboxType, or can be + // defined by the embedder via + // ContentClient::GetSandboxProfileForProcessType(). + static void SandboxWarmup(int sandbox_type); // Turns on the OS X sandbox for this process. - // |sandbox_type| - type of Sandbox to use. + // |sandbox_type| - type of Sandbox to use. See SandboxWarmup() for legal + // values. // |allowed_dir| - directory to allow access to, currently the only sandbox // profile that supports this is SANDBOX_TYPE_UTILITY . // // Returns true on success, false if an error occurred enabling the sandbox. - static bool EnableSandbox(SandboxProcessType sandbox_type, + static bool EnableSandbox(int sandbox_type, const FilePath& allowed_dir); diff --git a/content/common/sandbox_mac.mm b/content/common/sandbox_mac.mm index d1ab290..d58e001 100644 --- a/content/common/sandbox_mac.mm +++ b/content/common/sandbox_mac.mm @@ -21,18 +21,40 @@ extern "C" { #include "base/mac/scoped_cftyperef.h" #include "base/mac/scoped_nsautorelease_pool.h" #include "base/string16.h" +#include "base/string_piece.h" #include "base/string_util.h" #include "base/stringprintf.h" #include "base/sys_info.h" #include "base/sys_string_conversions.h" #include "base/utf_string_conversions.h" #include "content/common/chrome_application_mac.h" +#include "content/public/common/content_client.h" #include "content/public/common/content_switches.h" +#include "grit/content_resources.h" #include "unicode/uchar.h" #include "ui/gfx/gl/gl_surface.h" namespace { +struct SandboxTypeToResourceIDMapping { + content::SandboxType sandbox_type; + int sandbox_profile_resource_id; +}; + +// Mapping from sandbox process types to resource IDs containing the sandbox +// profile for all process types known to content. +SandboxTypeToResourceIDMapping kDefaultSandboxTypeToResourceIDMapping[] = { + { content::SANDBOX_TYPE_RENDERER, IDR_RENDERER_SANDBOX_PROFILE }, + { content::SANDBOX_TYPE_WORKER, IDR_WORKER_SANDBOX_PROFILE }, + { content::SANDBOX_TYPE_UTILITY, IDR_UTILITY_SANDBOX_PROFILE }, + { content::SANDBOX_TYPE_GPU, IDR_GPU_SANDBOX_PROFILE }, + { content::SANDBOX_TYPE_PPAPI, IDR_PPAPI_SANDBOX_PROFILE }, +}; + +COMPILE_ASSERT(arraysize(kDefaultSandboxTypeToResourceIDMapping) == \ + size_t(content::SANDBOX_TYPE_AFTER_LAST_TYPE), \ + sandbox_type_to_resource_id_mapping_incorrect); + // Try to escape |c| as a "SingleEscapeCharacter" (\n, etc). If successful, // returns true and appends the escape sequence to |dst|. bool EscapeSingleChar(char c, std::string* dst) { @@ -190,7 +212,7 @@ bool Sandbox::QuoteStringForRegex(const std::string& str_utf8, // 10.5.6, 10.6.0 // static -void Sandbox::SandboxWarmup(SandboxProcessType sandbox_type) { +void Sandbox::SandboxWarmup(int sandbox_type) { base::mac::ScopedNSAutoreleasePool scoped_pool; { // CGColorSpaceCreateWithName(), CGBitmapContextCreate() - 10.5.6 @@ -247,18 +269,10 @@ void Sandbox::SandboxWarmup(SandboxProcessType sandbox_type) { } // Process-type dependent warm-up. - switch (sandbox_type) { - case SANDBOX_TYPE_GPU: - { - // Preload either the desktop GL or the osmesa so, depending on the - // --use-gl flag. - gfx::GLSurface::InitializeOneOff(); - } - break; - - default: - // To shut up a gcc warning. - break; + if (sandbox_type == content::SANDBOX_TYPE_GPU) { + // Preload either the desktop GL or the osmesa so, depending on the + // --use-gl flag. + gfx::GLSurface::InitializeOneOff(); } } @@ -324,65 +338,55 @@ NSString* Sandbox::BuildAllowDirectoryAccessSandboxString( // Load the appropriate template for the given sandbox type. // Returns the template as an NSString or nil on error. -NSString* LoadSandboxTemplate(Sandbox::SandboxProcessType sandbox_type) { - // We use a custom sandbox definition file to lock things down as - // tightly as possible. - NSString* sandbox_config_filename = nil; - switch (sandbox_type) { - case Sandbox::SANDBOX_TYPE_RENDERER: - sandbox_config_filename = @"renderer"; - break; - case Sandbox::SANDBOX_TYPE_WORKER: - sandbox_config_filename = @"worker"; - break; - case Sandbox::SANDBOX_TYPE_UTILITY: - sandbox_config_filename = @"utility"; - break; - case Sandbox::SANDBOX_TYPE_NACL_LOADER: - // The Native Client loader is used for safeguarding the user's - // untrusted code within Native Client. - sandbox_config_filename = @"nacl_loader"; - break; - case Sandbox::SANDBOX_TYPE_GPU: - sandbox_config_filename = @"gpu"; - break; - case Sandbox::SANDBOX_TYPE_PPAPI: - sandbox_config_filename = @"ppapi"; +NSString* LoadSandboxTemplate(int sandbox_type) { + // We use a custom sandbox definition to lock things down as tightly as + // possible. + int sandbox_profile_resource_id = -1; + + // Find resource id for sandbox profile to use for the specific sandbox type. + for (size_t i = 0; + i < arraysize(kDefaultSandboxTypeToResourceIDMapping); + ++i) { + if (kDefaultSandboxTypeToResourceIDMapping[i].sandbox_type == + sandbox_type) { + sandbox_profile_resource_id = + kDefaultSandboxTypeToResourceIDMapping[i].sandbox_profile_resource_id; break; - default: - NOTREACHED(); - return nil; + } + } + if (sandbox_profile_resource_id == -1) { + // Check if the embedder knows about this sandbox process type. + bool sandbox_type_found = + content::GetContentClient()->GetSandboxProfileForSandboxType( + sandbox_type, &sandbox_profile_resource_id); + CHECK(sandbox_type_found) << "Unknown sandbox type " << sandbox_type; } - // Read in the sandbox profile and the common prefix file. - NSString* common_sandbox_prefix_path = - [base::mac::MainAppBundle() pathForResource:@"common" - ofType:@"sb"]; - NSString* common_sandbox_prefix_data = - [NSString stringWithContentsOfFile:common_sandbox_prefix_path - encoding:NSUTF8StringEncoding - error:NULL]; - - if (!common_sandbox_prefix_data) { - DLOG(FATAL) << "Failed to find the sandbox profile on disk " - << [common_sandbox_prefix_path fileSystemRepresentation]; + base::StringPiece sandbox_definition = + content::GetContentClient()->GetDataResource(sandbox_profile_resource_id); + if (sandbox_definition.empty()) { + LOG(FATAL) << "Failed to load the sandbox profile (resource id " + << sandbox_profile_resource_id << ")"; return nil; } - NSString* sandbox_profile_path = - [base::mac::MainAppBundle() pathForResource:sandbox_config_filename - ofType:@"sb"]; - NSString* sandbox_data = - [NSString stringWithContentsOfFile:sandbox_profile_path - encoding:NSUTF8StringEncoding - error:NULL]; - - if (!sandbox_data) { - DLOG(FATAL) << "Failed to find the sandbox profile on disk " - << [sandbox_profile_path fileSystemRepresentation]; + base::StringPiece common_sandbox_definition = + content::GetContentClient()->GetDataResource(IDR_COMMON_SANDBOX_PROFILE); + if (common_sandbox_definition.empty()) { + LOG(FATAL) << "Failed to load the common sandbox profile"; return nil; } + NSString* common_sandbox_prefix_data = + [[NSString alloc] initWithBytes:common_sandbox_definition.data() + length:common_sandbox_definition.length() + encoding:NSUTF8StringEncoding]; + + NSString* sandbox_data = + [[NSString alloc] initWithBytes:sandbox_definition.data() + length:sandbox_definition.length() + encoding:NSUTF8StringEncoding]; + // Prefix sandbox_data with common_sandbox_prefix_data. return [common_sandbox_prefix_data stringByAppendingString:sandbox_data]; } @@ -459,11 +463,12 @@ bool Sandbox::PostProcessSandboxProfile( // Turns on the OS X sandbox for this process. // static -bool Sandbox::EnableSandbox(SandboxProcessType sandbox_type, +bool Sandbox::EnableSandbox(int sandbox_type, const FilePath& allowed_dir) { // Sanity - currently only SANDBOX_TYPE_UTILITY supports a directory being // passed in. - if (sandbox_type != SANDBOX_TYPE_UTILITY) { + if (sandbox_type < content::SANDBOX_TYPE_AFTER_LAST_TYPE && + sandbox_type != content::SANDBOX_TYPE_UTILITY) { DCHECK(allowed_dir.empty()) << "Only SANDBOX_TYPE_UTILITY allows a custom directory parameter."; } diff --git a/content/common/sandbox_mac_fontloading_unittest.mm b/content/common/sandbox_mac_fontloading_unittest.mm index 911110f..7e7154f 100644 --- a/content/common/sandbox_mac_fontloading_unittest.mm +++ b/content/common/sandbox_mac_fontloading_unittest.mm @@ -121,7 +121,7 @@ TEST_F(MacSandboxTest, FontLoadingTest) { file_util::WriteFileDescriptor(fileno(temp_file), static_cast<const char *>(font_data.memory()), font_data_size); - ASSERT_TRUE(RunTestInSandbox(Sandbox::SANDBOX_TYPE_RENDERER, + ASSERT_TRUE(RunTestInSandbox(content::SANDBOX_TYPE_RENDERER, "FontLoadingTestCase", temp_file_path.value().c_str())); temp_file_closer.reset(); ASSERT_TRUE(file_util::Delete(temp_file_path, false)); diff --git a/content/common/sandbox_mac_unittest_helper.h b/content/common/sandbox_mac_unittest_helper.h index 84c3221..4246c26 100644 --- a/content/common/sandbox_mac_unittest_helper.h +++ b/content/common/sandbox_mac_unittest_helper.h @@ -51,15 +51,19 @@ class MacSandboxTest : public base::MultiProcessTest { // required. // Returns true if the test passes, false if either of the functions in // the corresponding MacSandboxTestCase return false. - bool RunTestInSandbox(sandbox::Sandbox::SandboxProcessType sandbox_type, + bool RunTestInSandbox(content::SandboxType sandbox_type, const char* test_name, const char* test_data); - // Runs the test specified by |test_name| in all the different sandbox types, - // one by one. + // Runs the test specified by |test_name| in all the different sandbox types + // known to content, one by one. // Returns true if the test passes, false if either of the functions in // the corresponding MacSandboxTestCase return false in any of the spawned // processes. + // + // DANGER DANGER DANGER: + // Additional sandbox types defined by the embedder (e.g. the NaCL sandbox) + // won't be covered by these tests. bool RunTestInAllSandboxTypes(const char* test_name, const char* test_data); }; diff --git a/content/common/sandbox_mac_unittest_helper.mm b/content/common/sandbox_mac_unittest_helper.mm index 89a29cd..5e52e2a 100644 --- a/content/common/sandbox_mac_unittest_helper.mm +++ b/content/common/sandbox_mac_unittest_helper.mm @@ -14,6 +14,7 @@ extern "C" { #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "content/common/sandbox_mac.h" +#include "content/test/test_content_client.h" #include "testing/multiprocess_func_list.h" using sandbox::Sandbox; @@ -54,11 +55,11 @@ bool MacSandboxTest::RunTestInAllSandboxTypes(const char* test_name, const char* test_data) { // Go through all the sandbox types, and run the test case in each of them // if one fails, abort. - for(int i = static_cast<int>(Sandbox::SANDBOX_TYPE_FIRST_TYPE); - i < Sandbox::SANDBOX_AFTER_TYPE_LAST_TYPE; + for(int i = static_cast<int>(content::SANDBOX_TYPE_FIRST_TYPE); + i < content::SANDBOX_TYPE_AFTER_LAST_TYPE; ++i) { - if (!RunTestInSandbox(static_cast<Sandbox::SandboxProcessType>(i), + if (!RunTestInSandbox(static_cast<content::SandboxType>(i), test_name, test_data)) { LOG(ERROR) << "Sandboxed test (" << test_name << ")" << "Failed in sandbox type " << i << @@ -69,7 +70,7 @@ bool MacSandboxTest::RunTestInAllSandboxTypes(const char* test_name, return true; } -bool MacSandboxTest::RunTestInSandbox(Sandbox::SandboxProcessType sandbox_type, +bool MacSandboxTest::RunTestInSandbox(content::SandboxType sandbox_type, const char* test_name, const char* test_data) { std::stringstream s; @@ -125,14 +126,16 @@ namespace { // Main function for driver process that enables the sandbox and runs test // code. MULTIPROCESS_TEST_MAIN(mac_sandbox_test_runner) { + TestContentClient content_client; + content::SetContentClient(&content_client); // Extract parameters. char* sandbox_type_str = getenv(kSandboxTypeKey); if (!sandbox_type_str) { LOG(ERROR) << "Sandbox type not specified"; return -1; } - Sandbox::SandboxProcessType sandbox_type = - static_cast<Sandbox::SandboxProcessType>(atoi(sandbox_type_str)); + content::SandboxType sandbox_type = + static_cast<content::SandboxType>(atoi(sandbox_type_str)); char* sandbox_test_name = getenv(kSandboxTestNameKey); if (!sandbox_test_name) { LOG(ERROR) << "Sandbox test name not specified"; diff --git a/content/content_browser.gypi b/content/content_browser.gypi index ac46dac..37f7324 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -697,12 +697,6 @@ '../third_party/mozilla/NSPasteboard+Utils.h', '../third_party/mozilla/NSPasteboard+Utils.mm', ], - 'link_settings': { - 'mac_bundle_resources': [ - 'browser/gpu.sb', - 'browser/worker.sb', - ], - }, 'dependencies': [ 'closure_blocks_leopard_compat', ], diff --git a/content/content_common.gypi b/content/content_common.gypi index 507d80e..9a61b39 100644 --- a/content/content_common.gypi +++ b/content/content_common.gypi @@ -56,6 +56,7 @@ 'public/common/resource_dispatcher_delegate.h', 'public/common/result_codes.h', 'public/common/sandbox_init.h', + 'public/common/sandbox_type_mac.h', 'public/common/security_style.h', 'public/common/serialized_script_value.cc', 'public/common/serialized_script_value.h', @@ -216,6 +217,7 @@ 'common/resource_dispatcher.h', 'common/resource_messages.h', 'common/sandbox_init_mac.cc', + 'common/sandbox_init_mac.h', 'common/sandbox_init_win.cc', 'common/sandbox_mac.h', 'common/sandbox_mac.mm', @@ -269,13 +271,6 @@ 'common/sandbox_policy.h', ], }], - ['OS=="mac"', { - 'link_settings': { - 'mac_bundle_resources': [ - 'common/common.sb', - ], - }, - }], ['toolkit_uses_gtk == 1', { 'dependencies': [ '../build/linux/system.gyp:gtk', diff --git a/content/content_ppapi_plugin.gypi b/content/content_ppapi_plugin.gypi index fcc58da..b428614 100644 --- a/content/content_ppapi_plugin.gypi +++ b/content/content_ppapi_plugin.gypi @@ -24,13 +24,4 @@ 'include_dirs': [ '..', ], - 'conditions': [ - ['OS=="mac"', { - 'link_settings': { - 'mac_bundle_resources': [ - 'ppapi_plugin/ppapi.sb', - ], - }, - }], - ], } diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index 36906fb..3ff1a99 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi @@ -246,11 +246,6 @@ 'sources!': [ 'common/process_watcher_posix.cc', ], - 'link_settings': { - 'mac_bundle_resources': [ - 'renderer/renderer.sb', - ], - }, }], ['OS=="win" and win_use_allocator_shim==1', { 'dependencies': [ diff --git a/content/content_resources.grd b/content/content_resources.grd index cbfebb1..c60c3a7 100644 --- a/content/content_resources.grd +++ b/content/content_resources.grd @@ -20,12 +20,12 @@ content_resources.rc file to the respective targets. <release seq="1"> <includes> <if expr="is_macosx"> - <include name="IDR_GPU_SANDBOX_DEFINITION" file="browser/gpu.sb" type="BINDATA" /> - <include name="IDR_WORKER_SANDBOX_DEFINITION" file="browser/worker.sb" type="BINDATA" /> - <include name="IDR_COMMON_SANDBOX_DEFINITION" file="common/common.sb" type="BINDATA" /> - <include name="IDR_PPAPI_SANDBOX_DEFINITION" file="ppapi_plugin/ppapi.sb" type="BINDATA" /> - <include name="IDR_RENDERER_SANDBOX_DEFINITION" file="renderer/renderer.sb" type="BINDATA" /> - <include name="IDR_UTILITY_SANDBOX_DEFINITION" file="utility/utility.sb" type="BINDATA" /> + <include name="IDR_GPU_SANDBOX_PROFILE" file="browser/gpu.sb" type="BINDATA" /> + <include name="IDR_WORKER_SANDBOX_PROFILE" file="browser/worker.sb" type="BINDATA" /> + <include name="IDR_COMMON_SANDBOX_PROFILE" file="common/common.sb" type="BINDATA" /> + <include name="IDR_PPAPI_SANDBOX_PROFILE" file="ppapi_plugin/ppapi.sb" type="BINDATA" /> + <include name="IDR_RENDERER_SANDBOX_PROFILE" file="renderer/renderer.sb" type="BINDATA" /> + <include name="IDR_UTILITY_SANDBOX_PROFILE" file="utility/utility.sb" type="BINDATA" /> </if> </includes> </release> diff --git a/content/content_resources.gyp b/content/content_resources.gyp index 63b6f6a..69c4220 100644 --- a/content/content_resources.gyp +++ b/content/content_resources.gyp @@ -23,6 +23,14 @@ }, ], 'includes': [ '../build/grit_target.gypi' ], + 'copies': [ + { + 'destination': '<(PRODUCT_DIR)', + 'files': [ + '<(SHARED_INTERMEDIATE_DIR)/content/content_resources.pak' + ], + }, + ], }, ], } diff --git a/content/content_tests.gypi b/content/content_tests.gypi index cade666..24bcfc3 100644 --- a/content/content_tests.gypi +++ b/content/content_tests.gypi @@ -135,6 +135,7 @@ 'content_plugin', 'content_renderer', 'test_support_content', + 'content_resources.gyp:content_resources', '../base/base.gyp:test_support_base', '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', '../crypto/crypto.gyp:crypto', @@ -231,6 +232,11 @@ 'common/net/url_fetcher_impl_unittest.cc', 'common/page_zoom_unittest.cc', 'common/resource_dispatcher_unittest.cc', + 'common/sandbox_mac_diraccess_unittest.mm', + 'common/sandbox_mac_fontloading_unittest.mm', + 'common/sandbox_mac_unittest_helper.h', + 'common/sandbox_mac_unittest_helper.mm', + 'common/sandbox_mac_system_access_unittest.mm', 'gpu/gpu_info_collector_unittest.cc', 'gpu/gpu_info_collector_unittest_win.cc', 'renderer/active_notification_tracker_unittest.cc', diff --git a/content/content_utility.gypi b/content/content_utility.gypi index 9fa39eb..e799de5 100644 --- a/content/content_utility.gypi +++ b/content/content_utility.gypi @@ -17,13 +17,4 @@ 'include_dirs': [ '..', ], - 'conditions': [ - ['OS=="mac"', { - 'link_settings': { - 'mac_bundle_resources': [ - 'utility/utility.sb', - ], - }, - }], - ], } diff --git a/content/ppapi_plugin/ppapi_thread.cc b/content/ppapi_plugin/ppapi_thread.cc index 7b865bc..c5f2a6b 100644 --- a/content/ppapi_plugin/ppapi_thread.cc +++ b/content/ppapi_plugin/ppapi_thread.cc @@ -27,6 +27,8 @@ #if defined(OS_WIN) #include "sandbox/src/sandbox.h" +#elif defined(OS_MACOSX) +#include "content/common/sandbox_init_mac.h" #endif #if defined(OS_WIN) diff --git a/content/public/common/content_client.h b/content/public/common/content_client.h index 840e370..f984b47 100644 --- a/content/public/common/content_client.h +++ b/content/public/common/content_client.h @@ -114,6 +114,19 @@ class CONTENT_EXPORT ContentClient { sandbox::TargetPolicy* policy) = 0; #endif +#if defined(OS_MACOSX) + // Allows the embedder to define a new |sandbox_type| by mapping it to the + // resource ID corresponding to the sandbox profile to use. The legal values + // for |sandbox_type| are defined by the embedder and should start with + // SandboxType::SANDBOX_TYPE_AFTER_LAST_TYPE. Returns false if no sandbox + // profile for the given |sandbox_type| exists. Otherwise, + // |sandbox_profile_resource_id| is set to the resource ID corresponding to + // the sandbox profile to use and true is returned. + virtual bool GetSandboxProfileForSandboxType( + int sandbox_type, + int* sandbox_profile_resource_id) const = 0; +#endif + private: // The embedder API for participating in browser logic. ContentBrowserClient* browser_; diff --git a/content/public/common/sandbox_init.h b/content/public/common/sandbox_init.h index 3415e0d..88c6d839 100644 --- a/content/public/common/sandbox_init.h +++ b/content/public/common/sandbox_init.h @@ -13,10 +13,13 @@ namespace sandbox { struct SandboxInterfaceInfo; } +#elif defined(OS_MACOSX) +class FilePath; #endif namespace content { +#if defined(OS_WIN) // Initialize the sandbox for renderer, gpu, utility, worker, nacl, and plug-in // processes, depending on the command line flags. Although The browser process // is not sandboxed, this also needs to be called because it will initialize @@ -24,11 +27,25 @@ namespace content { // 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. -#if defined(OS_WIN) CONTENT_EXPORT bool InitializeSandbox( sandbox::SandboxInterfaceInfo* sandbox_info); #elif defined(OS_MACOSX) -CONTENT_EXPORT bool InitializeSandbox(); +// Initialize the sandbox of the given |sandbox_type|, optionally specifying a +// directory to allow access to. Note specifying a directory needs to be +// supported by the sandbox profile associated with the given |sandbox_type|. +// Valid values for |sandbox_type| are defined either by the enum SandboxType, +// or by ContentClient::GetSandboxProfileForSandboxType(). +// +// If the |sandbox_type| isn't one of the ones defined by content then the +// embedder is queried using ContentClient::GetSandboxPolicyForSandboxType(). +// The embedder can use values for |sandbox_type| starting from +// content::sandbox::SANDBOX_PROCESS_TYPE_AFTER_LAST_TYPE. +// +// Returns true if the sandbox was initialized succesfully, false if an error +// occurred. If process_type isn't one that needs sandboxing, no action is +// taken and true is always returned. +CONTENT_EXPORT bool InitializeSandbox(int sandbox_type, + const FilePath& allowed_path); #endif } // namespace content diff --git a/content/public/common/sandbox_type_mac.h b/content/public/common/sandbox_type_mac.h new file mode 100644 index 0000000..68a5d0f --- /dev/null +++ b/content/public/common/sandbox_type_mac.h @@ -0,0 +1,40 @@ +// Copyright (c) 2011 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. + +#ifndef CONTENT_PUBLIC_COMMON_SANDBOX_TYPE_MAC_H_ +#define CONTENT_PUBLIC_COMMON_SANDBOX_TYPE_MAC_H_ +#pragma once + +namespace content { + +// Defines the Mac sandbox types known within content. Embedders can add +// additional sandbox types with IDs starting with SANDBOX_TYPE_AFTER_LAST_TYPE. + +enum SandboxType { + SANDBOX_TYPE_FIRST_TYPE = 0, // Placeholder to ease iteration. + + SANDBOX_TYPE_RENDERER = SANDBOX_TYPE_FIRST_TYPE, + + // The worker process uses the most restrictive sandbox which has almost + // *everything* locked down. Only a couple of /System/Library/ paths and + // some other very basic operations (e.g., reading metadata to allow + // following symlinks) are permitted. + SANDBOX_TYPE_WORKER, + + // Utility process is as restrictive as the worker process except full + // access is allowed to one configurable directory. + SANDBOX_TYPE_UTILITY, + + // GPU process. + SANDBOX_TYPE_GPU, + + // The PPAPI plugin process. + SANDBOX_TYPE_PPAPI, + + SANDBOX_TYPE_AFTER_LAST_TYPE, // Placeholder to ease iteration. +}; + +} // namespace content + +#endif // CONTENT_PUBLIC_COMMON_SANDBOX_TYPE_MAC_H_ diff --git a/content/renderer/renderer_main_platform_delegate_mac.mm b/content/renderer/renderer_main_platform_delegate_mac.mm index 68685c4..34912e4 100644 --- a/content/renderer/renderer_main_platform_delegate_mac.mm +++ b/content/renderer/renderer_main_platform_delegate_mac.mm @@ -14,7 +14,7 @@ #import "content/common/chrome_application_mac.h" #include "content/common/sandbox_mac.h" #include "content/public/common/content_switches.h" -#include "content/public/common/sandbox_init.h" +#include "content/common/sandbox_init_mac.h" #include "third_party/WebKit/Source/WebKit/mac/WebCoreSupport/WebSystemInterface.h" RendererMainPlatformDelegate::RendererMainPlatformDelegate( diff --git a/content/shell/shell_content_client.cc b/content/shell/shell_content_client.cc index c6bf11f..fc6da53 100644 --- a/content/shell/shell_content_client.cc +++ b/content/shell/shell_content_client.cc @@ -54,4 +54,12 @@ bool ShellContentClient::SandboxPlugin(CommandLine* command_line, } #endif +#if defined(OS_MACOSX) +bool ShellContentClient::GetSandboxProfileForSandboxType( + int sandbox_type, + int* sandbox_profile_resource_id) const { + return false; +} +#endif + } // namespace content diff --git a/content/shell/shell_content_client.h b/content/shell/shell_content_client.h index 388e200..a4ef244 100644 --- a/content/shell/shell_content_client.h +++ b/content/shell/shell_content_client.h @@ -31,6 +31,12 @@ class ShellContentClient : public ContentClient { virtual bool SandboxPlugin(CommandLine* command_line, sandbox::TargetPolicy* policy) OVERRIDE; #endif + +#if defined(OS_MACOSX) + virtual bool GetSandboxProfileForSandboxType( + int sandbox_type, + int* sandbox_profile_resource_id) const OVERRIDE; +#endif }; } // namespace content diff --git a/content/test/DEPS b/content/test/DEPS index cf47233..87c46bc 100644 --- a/content/test/DEPS +++ b/content/test/DEPS @@ -1,4 +1,5 @@ include_rules = [ # Testing utilities can access anything in content/ "+content", + "+ui/base/resource/data_pack.h" ] diff --git a/content/test/test_content_client.cc b/content/test/test_content_client.cc index e1d6d43..eeb1df3 100644 --- a/content/test/test_content_client.cc +++ b/content/test/test_content_client.cc @@ -4,10 +4,18 @@ #include "content/test/test_content_client.h" +#include "base/base_paths.h" +#include "base/file_path.h" #include "base/logging.h" +#include "base/path_service.h" #include "base/string_piece.h" TestContentClient::TestContentClient() { + FilePath content_resources_pack_path; + PathService::Get(base::DIR_MODULE, &content_resources_pack_path); + content_resources_pack_path = content_resources_pack_path.Append( + FILE_PATH_LITERAL("content_resources.pak")); + data_pack_.Load(content_resources_pack_path); } TestContentClient::~TestContentClient() { @@ -45,7 +53,9 @@ string16 TestContentClient::GetLocalizedString(int message_id) const { } base::StringPiece TestContentClient::GetDataResource(int resource_id) const { - return base::StringPiece(); + base::StringPiece resource; + data_pack_.GetStringPiece(resource_id, &resource); + return resource; } #if defined(OS_WIN) @@ -54,3 +64,11 @@ bool TestContentClient::SandboxPlugin(CommandLine* command_line, return false; } #endif + +#if defined(OS_MACOSX) +bool TestContentClient::GetSandboxProfileForSandboxType( + int sandbox_type, + int* sandbox_profile_resource_id) const { + return false; +} +#endif diff --git a/content/test/test_content_client.h b/content/test/test_content_client.h index d4b27bf..44399a7 100644 --- a/content/test/test_content_client.h +++ b/content/test/test_content_client.h @@ -8,6 +8,7 @@ #include "base/compiler_specific.h" #include "content/public/common/content_client.h" +#include "ui/base/resource/data_pack.h" class TestContentClient : public content::ContentClient { public: @@ -30,8 +31,15 @@ class TestContentClient : public content::ContentClient { virtual bool SandboxPlugin(CommandLine* command_line, sandbox::TargetPolicy* policy) OVERRIDE; #endif +#if defined(OS_MACOSX) + virtual bool GetSandboxProfileForSandboxType( + int sandbox_type, + int* sandbox_profile_resource_id) const OVERRIDE; +#endif private: + ui::DataPack data_pack_; + DISALLOW_COPY_AND_ASSIGN(TestContentClient); }; |