summaryrefslogtreecommitdiffstats
path: root/content/common
diff options
context:
space:
mode:
authorjochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-25 20:55:24 +0000
committerjochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-25 20:55:24 +0000
commitdbd82584da433118de55fb3319be12c4c3536cf2 (patch)
treebba6762062c6bff54dce8cadcb2a7d19a7ea19eb /content/common
parent0cc75fe16b6e272176ee8db613ceef0990825bcf (diff)
downloadchromium_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
Diffstat (limited to 'content/common')
-rw-r--r--content/common/sandbox_init_mac.cc61
-rw-r--r--content/common/sandbox_init_mac.h22
-rw-r--r--content/common/sandbox_mac.h42
-rw-r--r--content/common/sandbox_mac.mm135
-rw-r--r--content/common/sandbox_mac_fontloading_unittest.mm2
-rw-r--r--content/common/sandbox_mac_unittest_helper.h10
-rw-r--r--content/common/sandbox_mac_unittest_helper.mm15
7 files changed, 156 insertions, 131 deletions
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";