summaryrefslogtreecommitdiffstats
path: root/chrome/nacl
diff options
context:
space:
mode:
authorjvoung@google.com <jvoung@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-15 23:02:52 +0000
committerjvoung@google.com <jvoung@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-15 23:02:52 +0000
commit23acfc08defd8db4cd54d91e86593baf47b461ea (patch)
treefe9e80355421a03b7fab0bf372834144adf4bd21 /chrome/nacl
parent9d098779ae0342c1bf8db56d0bacbb57c3858215 (diff)
downloadchromium_src-23acfc08defd8db4cd54d91e86593baf47b461ea.zip
chromium_src-23acfc08defd8db4cd54d91e86593baf47b461ea.tar.gz
chromium_src-23acfc08defd8db4cd54d91e86593baf47b461ea.tar.bz2
Set up tests to exercise the chrome outersandbox from the nacl loader.
It is similar to the renderer sandbox tests in that the test code is separated into a DLL and only loaded based on commandline flags. Currently tests file open, process creation, and connect. This is currently not set up for Linux. To set it up for Linux, we need to be more careful about what tests are expected to pass, and will need to look into zygote process for how to get the test shared lib loaded. BUG=39409 TEST=none Review URL: http://codereview.chromium.org/1549046 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@52567 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/nacl')
-rw-r--r--chrome/nacl/nacl_main.cc44
-rw-r--r--chrome/nacl/nacl_main_platform_delegate.h47
-rw-r--r--chrome/nacl/nacl_main_platform_delegate_linux.cc53
-rw-r--r--chrome/nacl/nacl_main_platform_delegate_mac.mm85
-rw-r--r--chrome/nacl/nacl_main_platform_delegate_win.cc85
5 files changed, 280 insertions, 34 deletions
diff --git a/chrome/nacl/nacl_main.cc b/chrome/nacl/nacl_main.cc
index 760eb85..d1cf8e1 100644
--- a/chrome/nacl/nacl_main.cc
+++ b/chrome/nacl/nacl_main.cc
@@ -25,6 +25,7 @@
#if defined(OS_WIN)
#include "chrome/nacl/broker_thread.h"
#endif
+#include "chrome/nacl/nacl_main_platform_delegate.h"
#include "chrome/nacl/nacl_thread.h"
#ifdef _WIN64
@@ -86,28 +87,11 @@ static void HandleNaClTestParameters(const CommandLine& command_line) {
}
}
-// Launch the NaCl child process in its own thread.
-#if defined (OS_WIN)
-static void LaunchNaClChildProcess(bool no_sandbox,
- sandbox::TargetServices* target_services) {
- ChildProcess nacl_process;
- nacl_process.set_main_thread(new NaClThread());
- if (!no_sandbox && target_services) {
- // Cause advapi32 to load before the sandbox is turned on.
- unsigned int dummy_rand;
- rand_s(&dummy_rand);
- // Turn the sanbox on.
- target_services->LowerToken();
- }
- MessageLoop::current()->Run();
-}
-#elif defined(OS_MACOSX) || defined(OS_LINUX)
static void LaunchNaClChildProcess() {
ChildProcess nacl_process;
nacl_process.set_main_thread(new NaClThread());
MessageLoop::current()->Run();
}
-#endif
// main() routine for the NaCl loader process.
int NaClMain(const MainFunctionParams& parameters) {
@@ -126,33 +110,25 @@ int NaClMain(const MainFunctionParams& parameters) {
SystemMonitor system_monitor;
HighResolutionTimerManager hi_res_timer_manager;
-#if defined(OS_WIN)
- sandbox::TargetServices* target_services =
- parameters.sandbox_info_.TargetServices();
-
- DLOG(INFO) << "Started NaCl loader with " <<
- parsed_command_line.command_line_string();
+#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)
+ NaClMainPlatformDelegate platform(parameters);
- HMODULE sandbox_test_module = NULL;
+ platform.PlatformInitialize();
bool no_sandbox = parsed_command_line.HasSwitch(switches::kNoSandbox);
- if (target_services && !no_sandbox) {
- // The command line might specify a test plugin to load.
- if (parsed_command_line.HasSwitch(switches::kTestSandbox)) {
- std::wstring test_plugin_name =
- parsed_command_line.GetSwitchValue(switches::kTestSandbox);
- sandbox_test_module = LoadLibrary(test_plugin_name.c_str());
- DCHECK(sandbox_test_module);
- }
+ platform.InitSandboxTests(no_sandbox);
+
+ if (!no_sandbox) {
+ platform.EnableSandbox();
}
- LaunchNaClChildProcess(no_sandbox, target_services);
+ platform.RunSandboxTests();
-#elif defined(OS_MACOSX) || defined(OS_LINUX)
LaunchNaClChildProcess();
#else
NOTIMPLEMENTED() << " not implemented startup, plugin startup dialog etc.";
#endif
+ platform.PlatformUninitialize();
return 0;
}
diff --git a/chrome/nacl/nacl_main_platform_delegate.h b/chrome/nacl/nacl_main_platform_delegate.h
new file mode 100644
index 0000000..fe13ae3
--- /dev/null
+++ b/chrome/nacl/nacl_main_platform_delegate.h
@@ -0,0 +1,47 @@
+// Copyright (c) 2010 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_NACL_NACL_MAIN_PLATFORM_DELEGATE_H_
+#define CHROME_NACL_NACL_MAIN_PLATFORM_DELEGATE_H_
+
+#include "chrome/common/main_function_params.h"
+
+typedef bool (*RunNaClLoaderTests)(void);
+const char kNaClLoaderTestCall[] = "RunNaClLoaderTests";
+
+
+class NaClMainPlatformDelegate {
+ public:
+ explicit NaClMainPlatformDelegate(const MainFunctionParams& parameters);
+ ~NaClMainPlatformDelegate();
+
+ // Called first thing and last thing in the process' lifecycle, i.e. before
+ // the sandbox is enabled.
+ void PlatformInitialize();
+ void PlatformUninitialize();
+
+ // Gives us an opportunity to initialize state used for tests before enabling
+ // the sandbox.
+ void InitSandboxTests(bool no_sandbox);
+
+ // Initiate Lockdown, returns true on success.
+ bool EnableSandbox();
+
+ // Runs the sandbox tests for the NaCl Loader, if tests supplied.
+ // Cannot run again, after this (resources freed).
+ void RunSandboxTests();
+
+ private:
+ const MainFunctionParams& parameters_;
+#if defined(OS_WIN)
+ HMODULE sandbox_test_module_;
+ // #elif defined(OS_POSIX) doesn't seem to work on Mac.
+#elif defined(OS_LINUX) || defined(OS_MACOSX)
+ void* sandbox_test_module_;
+#endif
+
+ DISALLOW_COPY_AND_ASSIGN(NaClMainPlatformDelegate);
+};
+
+#endif // CHROME_NACL_NACL_MAIN_PLATFORM_DELEGATE_H_
diff --git a/chrome/nacl/nacl_main_platform_delegate_linux.cc b/chrome/nacl/nacl_main_platform_delegate_linux.cc
new file mode 100644
index 0000000..92613a8
--- /dev/null
+++ b/chrome/nacl/nacl_main_platform_delegate_linux.cc
@@ -0,0 +1,53 @@
+// Copyright (c) 2010 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/nacl/nacl_main_platform_delegate.h"
+
+#include "base/command_line.h"
+#include "base/debug_util.h"
+#include "sandbox/linux/seccomp/sandbox.h"
+
+#include "chrome/common/chrome_switches.h"
+
+NaClMainPlatformDelegate::NaClMainPlatformDelegate(
+ const MainFunctionParams& parameters)
+ : parameters_(parameters), sandbox_test_module_(NULL) {
+}
+
+NaClMainPlatformDelegate::~NaClMainPlatformDelegate() {
+}
+
+void NaClMainPlatformDelegate::PlatformInitialize() {
+}
+
+void NaClMainPlatformDelegate::PlatformUninitialize() {
+}
+
+void NaClMainPlatformDelegate::InitSandboxTests(bool no_sandbox) {
+ // The sandbox is started in the zygote process: zygote_main_linux.cc
+ // http://code.google.com/p/chromium/wiki/LinuxSUIDSandbox
+ return;
+}
+
+bool NaClMainPlatformDelegate::EnableSandbox() {
+ // The setuid sandbox is started in the zygote process: zygote_main_linux.cc
+ // http://code.google.com/p/chromium/wiki/LinuxSUIDSandbox
+ //
+ // The seccomp sandbox is started in the renderer.
+ // http://code.google.com/p/seccompsandbox/
+#if defined(ARCH_CPU_X86_FAMILY) && !defined(CHROMIUM_SELINUX)
+ // N.b. SupportsSeccompSandbox() returns a cached result, as we already
+ // called it earlier in the zygote. Thus, it is OK for us to not pass in
+ // a file descriptor for "/proc".
+ if (switches::SeccompSandboxEnabled() && SupportsSeccompSandbox(-1))
+ StartSeccompSandbox();
+#endif
+ return true;
+}
+
+void NaClMainPlatformDelegate::RunSandboxTests() {
+ // The sandbox is started in the zygote process: zygote_main_linux.cc
+ // http://code.google.com/p/chromium/wiki/LinuxSUIDSandbox
+}
+
diff --git a/chrome/nacl/nacl_main_platform_delegate_mac.mm b/chrome/nacl/nacl_main_platform_delegate_mac.mm
new file mode 100644
index 0000000..61a2ed7
--- /dev/null
+++ b/chrome/nacl/nacl_main_platform_delegate_mac.mm
@@ -0,0 +1,85 @@
+// Copyright (c) 2010 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/nacl/nacl_main_platform_delegate.h"
+
+#import <Cocoa/Cocoa.h>
+#include <dlfcn.h>
+#import "base/chrome_application_mac.h"
+#include "base/command_line.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/sandbox_mac.h"
+#include "third_party/WebKit/WebKit/mac/WebCoreSupport/WebSystemInterface.h"
+
+NaClMainPlatformDelegate::NaClMainPlatformDelegate(
+ const MainFunctionParams& parameters)
+ : parameters_(parameters), sandbox_test_module_(NULL) {
+}
+
+NaClMainPlatformDelegate::~NaClMainPlatformDelegate() {
+}
+
+// TODO(jvoung): see if this old comment (from renderer_main_platform...)
+// is relevant to the nacl loader.
+// TODO(mac-port): Any code needed to initialize a process for purposes of
+// running a NaClLoader needs to also be reflected in chrome_dll_main.cc for
+// --single-process support.
+void NaClMainPlatformDelegate::PlatformInitialize() {
+}
+
+void NaClMainPlatformDelegate::PlatformUninitialize() {
+}
+
+void NaClMainPlatformDelegate::InitSandboxTests(bool no_sandbox) {
+ const CommandLine& command_line = parameters_.command_line_;
+
+ DLOG(INFO) << "Started NaClLdr with ";
+ const std::vector<std::string>& argstrings = command_line.argv();
+ for (std::vector<std::string>::const_iterator ii = argstrings.begin();
+ ii != argstrings.end(); ++ii) {
+ DLOG(INFO) << *ii;
+ }
+ DLOG(INFO) << std::endl;
+
+ // Be sure not to load the sandbox test DLL if the sandbox isn't on.
+ // Comment-out guard and recompile if you REALLY want to test w/out the SB.
+ // TODO(jvoung): allow testing without sandbox, but change expected ret vals.
+ if (!no_sandbox) {
+ std::string test_dll_name =
+ command_line.GetSwitchValueASCII(switches::kTestNaClSandbox);
+ if (!test_dll_name.empty()) {
+ sandbox_test_module_ = dlopen(test_dll_name.c_str(), RTLD_LAZY);
+ CHECK(sandbox_test_module_);
+ }
+ }
+ return;
+}
+
+bool NaClMainPlatformDelegate::EnableSandbox() {
+ CommandLine* parsed_command_line = CommandLine::ForCurrentProcess();
+ SandboxInitWrapper sandbox_wrapper;
+ bool sandbox_initialized_ok =
+ sandbox_wrapper.InitializeSandbox(*parsed_command_line,
+ switches::kNaClLoaderProcess);
+ CHECK(sandbox_initialized_ok) << "Error initializing sandbox for "
+ << switches::kNaClLoaderProcess;
+ return sandbox_initialized_ok;
+}
+
+
+void NaClMainPlatformDelegate::RunSandboxTests() {
+ if (sandbox_test_module_) {
+ RunNaClLoaderTests run_security_tests =
+ reinterpret_cast<RunNaClLoaderTests>(dlsym(sandbox_test_module_,
+ kNaClLoaderTestCall));
+
+ CHECK(run_security_tests);
+ if (run_security_tests) {
+ DLOG(INFO) << "Running NaCl Loader security tests";
+ CHECK((*run_security_tests)());
+ }
+ dlclose(sandbox_test_module_);
+ }
+}
+
diff --git a/chrome/nacl/nacl_main_platform_delegate_win.cc b/chrome/nacl/nacl_main_platform_delegate_win.cc
new file mode 100644
index 0000000..df01489
--- /dev/null
+++ b/chrome/nacl/nacl_main_platform_delegate_win.cc
@@ -0,0 +1,85 @@
+// Copyright (c) 2010 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/nacl/nacl_main_platform_delegate.h"
+#include "base/command_line.h"
+#include "chrome/common/chrome_constants.h"
+#include "chrome/common/chrome_switches.h"
+#include "sandbox/src/sandbox.h"
+
+NaClMainPlatformDelegate::NaClMainPlatformDelegate(
+ const MainFunctionParams& parameters)
+ : parameters_(parameters), sandbox_test_module_(NULL) {
+}
+
+NaClMainPlatformDelegate::~NaClMainPlatformDelegate() {
+}
+
+void NaClMainPlatformDelegate::PlatformInitialize() {
+ // Be mindful of what resources you acquire here. They can be used by
+ // malicious code if the renderer gets compromised.
+}
+
+void NaClMainPlatformDelegate::PlatformUninitialize() {
+}
+
+void NaClMainPlatformDelegate::InitSandboxTests(bool no_sandbox) {
+ const CommandLine& command_line = parameters_.command_line_;
+
+ DLOG(INFO) << "Started NaClLdr with " << command_line.command_line_string();
+
+ sandbox::TargetServices* target_services =
+ parameters_.sandbox_info_.TargetServices();
+
+ if (target_services && !no_sandbox) {
+ std::wstring test_dll_name =
+ command_line.GetSwitchValue(switches::kTestNaClSandbox);
+ if (!test_dll_name.empty()) {
+ // At this point, hack on the suffix according to with bitness
+ // of your windows process.
+#if defined(_WIN64)
+ DLOG(INFO) << "Using 64-bit test dll\n";
+ test_dll_name.append(L"64.dll");
+#else
+ DLOG(INFO) << "Using 32-bit test dll\n";
+ test_dll_name.append(L".dll");
+#endif
+ DLOG(INFO) << "Loading test lib " << test_dll_name << "\n";
+ sandbox_test_module_ = LoadLibrary(test_dll_name.c_str());
+ CHECK(sandbox_test_module_);
+ LOG(INFO) << "Testing NaCl sandbox\n";
+ }
+ }
+ return;
+}
+
+bool NaClMainPlatformDelegate::EnableSandbox() {
+ sandbox::TargetServices* target_services =
+ parameters_.sandbox_info_.TargetServices();
+
+ if (target_services) {
+ // Cause advapi32 to load before the sandbox is turned on.
+ unsigned int dummy_rand;
+ rand_s(&dummy_rand);
+ // Turn the sandbox on.
+ target_services->LowerToken();
+ return true;
+ }
+ return false;
+}
+
+void NaClMainPlatformDelegate::RunSandboxTests() {
+ if (sandbox_test_module_) {
+ RunNaClLoaderTests run_security_tests = reinterpret_cast<RunNaClLoaderTests>
+ (GetProcAddress(sandbox_test_module_, kNaClLoaderTestCall));
+
+ CHECK(run_security_tests);
+ if (run_security_tests) {
+ DLOG(INFO) << "Running NaCl Loader security tests";
+ CHECK((*run_security_tests)());
+ }
+ FreeLibrary(sandbox_test_module_);
+ }
+}
+