diff options
Diffstat (limited to 'chrome/nacl')
-rw-r--r-- | chrome/nacl/nacl_main.cc | 44 | ||||
-rw-r--r-- | chrome/nacl/nacl_main_platform_delegate.h | 47 | ||||
-rw-r--r-- | chrome/nacl/nacl_main_platform_delegate_linux.cc | 53 | ||||
-rw-r--r-- | chrome/nacl/nacl_main_platform_delegate_mac.mm | 85 | ||||
-rw-r--r-- | chrome/nacl/nacl_main_platform_delegate_win.cc | 85 |
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_); + } +} + |