diff options
author | jvoung@google.com <jvoung@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-15 23:02:52 +0000 |
---|---|---|
committer | jvoung@google.com <jvoung@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-15 23:02:52 +0000 |
commit | 23acfc08defd8db4cd54d91e86593baf47b461ea (patch) | |
tree | fe9e80355421a03b7fab0bf372834144adf4bd21 /chrome | |
parent | 9d098779ae0342c1bf8db56d0bacbb57c3858215 (diff) | |
download | chromium_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')
23 files changed, 1015 insertions, 101 deletions
diff --git a/chrome/app/chrome_dll_main.cc b/chrome/app/chrome_dll_main.cc index c51ac67..9e3feb8 100644 --- a/chrome/app/chrome_dll_main.cc +++ b/chrome/app/chrome_dll_main.cc @@ -732,9 +732,11 @@ int ChromeMain(int argc, char** argv) { #if defined(OS_MACOSX) // On OS X the renderer sandbox needs to be initialized later in the startup - // sequence in RendererMainPlatformDelegate::PlatformInitialize(). + // sequence in RendererMainPlatformDelegate::EnableSandbox(). + // Same goes for NaClLoader, in NaClMainPlatformDelegate::EnableSandbox(). if (process_type != switches::kRendererProcess && - process_type != switches::kExtensionProcess) { + process_type != switches::kExtensionProcess && + process_type != switches::kNaClLoaderProcess) { bool sandbox_initialized_ok = sandbox_wrapper.InitializeSandbox(parsed_command_line, process_type); // Die if the sandbox can't be enabled. diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index f86d0c6..6bd89ba 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -425,6 +425,118 @@ ], }, { + 'target_name': 'nacl_security_tests', + 'type': 'shared_library', + 'msvs_guid': 'D705E8B8-4750-4F1F-BC8F-A7806872F504', + 'include_dirs': [ + '..' + ], + 'sources': [ + # mostly OS dependent files below... + ], + 'conditions': [ + ['OS=="mac"', { + # only Mac is using gtest for now (linking issues on other plats). + 'dependencies': [ + '../testing/gtest.gyp:gtest' + ], + 'sources': [ + 'test/nacl_security_tests/commands_posix.cc', + 'test/nacl_security_tests/commands_posix.h', + 'test/nacl_security_tests/nacl_security_tests_posix.h', + 'test/nacl_security_tests/nacl_security_tests_mac.cc', + ], + 'xcode_settings': { + 'DYLIB_INSTALL_NAME_BASE': '@executable_path/', + }, + },], + ['OS=="linux"', { + 'sources': [ + 'test/nacl_security_tests/commands_posix.cc', + 'test/nacl_security_tests/commands_posix.h', + 'test/nacl_security_tests/nacl_security_tests_posix.h', + 'test/nacl_security_tests/nacl_security_tests_linux.cc', + ], + },], + ['OS=="win"', { + 'sources': [ + '../sandbox/tests/validation_tests/commands.cc', + '../sandbox/tests/validation_tests/commands.h', + '../sandbox/tests/common/controller.h', + 'test/nacl_security_tests/nacl_security_tests_win.h', + 'test/nacl_security_tests/nacl_security_tests_win.cc', + ], + },], + # set fPIC for linux in case it isn't set. + ['OS=="linux" and (target_arch=="x64" or target_arch=="arm") and linux_fpic!=1', { + 'cflags': ['-fPIC'], + },], + ], + }, + { + 'target_name': 'nacl_sandbox_tests', + 'type': 'executable', + 'msvs_guid': '3087FC25-2C24-44B2-8253-44065EB47ACD', + 'dependencies': [ + 'chrome', + 'browser', + 'debugger', + 'common', + 'chrome_resources', + 'chrome_strings', + 'test_support_ui', + '../base/base.gyp:base', + '../build/temp_gyp/googleurl.gyp:googleurl', + '../net/net.gyp:net', + '../skia/skia.gyp:skia', + '../testing/gtest.gyp:gtest', + '../third_party/icu/icu.gyp:icui18n', + '../third_party/icu/icu.gyp:icuuc', + '../third_party/libxml/libxml.gyp:libxml', + ], + 'include_dirs': [ + '..', + ], + 'sources': [ + 'test/nacl/nacl_test.cc', + 'test/nacl/nacl_sandbox_test.cc' + ], + 'conditions': [ + ['OS=="win"', { + 'dependencies': [ + 'chrome_nacl_win64', + 'crash_service', # run time dependency + 'nacl_security_tests', # run time dependency + 'test_support_common', + '../google_update/google_update.gyp:google_update', + '../views/views.gyp:views', + # run time dependency + '../webkit/webkit.gyp:npapi_test_plugin', + '<(allocator_target)', + ], + 'link_settings': { + 'libraries': [ + '-lOleAcc.lib', + ], + }, + 'configurations': { + 'Debug_Base': { + 'msvs_settings': { + 'VCLinkerTool': { + 'LinkIncremental': '<(msvs_large_module_debug_link_mode)', + }, + }, + }, + }, + }], + ['OS=="mac"', { + 'dependencies': [ + 'nacl_security_tests', # run time dependency + ], + }], + ], + }, + { 'target_name': 'nacl_ui_tests', 'type': 'executable', 'msvs_guid': '43E2004F-CD62-4595-A8A6-31E9BFA1EE5E', @@ -449,6 +561,7 @@ ], 'sources': [ 'test/nacl/nacl_test.cc', + 'test/nacl/nacl_ui_test.cc', ], 'conditions': [ ['OS=="win"', { @@ -2226,6 +2339,26 @@ '../sandbox/tests/validation_tests/commands.h', ], }, + # Extra 64-bit DLL for windows + { + 'target_name': 'nacl_security_tests64', + 'type': 'shared_library', + 'configurations': { + 'Common_Base': { + 'msvs_target_platform': 'x64', + }, + }, + 'include_dirs': [ + '..' + ], + 'sources': [ + '../sandbox/tests/validation_tests/commands.cc', + '../sandbox/tests/validation_tests/commands.h', + '../sandbox/tests/common/controller.h', + 'test/nacl_security_tests/nacl_security_tests_win.h', + 'test/nacl_security_tests/nacl_security_tests_win.cc', + ], + }, { 'target_name': 'selenium_tests', 'type': 'executable', @@ -2460,6 +2593,7 @@ # 'browser_tests', '../ipc/ipc.gyp:ipc_tests', '../media/media.gyp:media_unittests', + 'nacl_sandbox_tests', 'nacl_ui_tests', '../net/net.gyp:net_unittests', '../printing/printing.gyp:printing_unittests', diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index e527bc52..f0e6950 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -882,9 +882,12 @@ const char kSyncUseCacheInvalidation[] = "use-cache-invalidation"; // Pass the name of the current running automated test to Chrome. const char kTestName[] = "test-name"; -// Runs the security test for the sandbox. +// Runs the security test for the renderer sandbox. const char kTestSandbox[] = "test-sandbox"; +// Runs the security test for the NaCl loader sandbox. +const char kTestNaClSandbox[] = "test-nacl-sandbox"; + // Pass the type of the current test harness ("browser" or "ui") const char kTestType[] = "test-type"; diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 495994d..06429d1 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -251,6 +251,7 @@ extern const char kSyncServer[]; extern const char kSyncServiceURL[]; extern const char kSyncUseSslTcp[]; extern const char kSyncUseCacheInvalidation[]; +extern const char kTestNaClSandbox[]; extern const char kTestName[]; extern const char kTestSandbox[]; extern const char kTestType[]; diff --git a/chrome/common/nacl_cmd_line.cc b/chrome/common/nacl_cmd_line.cc index 2893860..a54f196 100644 --- a/chrome/common/nacl_cmd_line.cc +++ b/chrome/common/nacl_cmd_line.cc @@ -18,7 +18,7 @@ namespace nacl { // TODO(gregoryd): check which flags of those below can be supported. static const char* const switch_names[] = { switches::kNoSandbox, - switches::kTestSandbox, + switches::kTestNaClSandbox, switches::kDisableBreakpad, switches::kFullMemoryCrashReport, switches::kEnableLogging, diff --git a/chrome/nacl.gypi b/chrome/nacl.gypi index b860e0f..d4be912 100644 --- a/chrome/nacl.gypi +++ b/chrome/nacl.gypi @@ -24,6 +24,10 @@ # platforms, including both 32-bit and 64-bit Windows. # Test files are also not included. 'nacl/nacl_main.cc', + 'nacl/nacl_main_platform_delegate.h', + 'nacl/nacl_main_platform_delegate_linux.cc', + 'nacl/nacl_main_platform_delegate_mac.mm', + 'nacl/nacl_main_platform_delegate_win.cc', 'nacl/nacl_thread.cc', 'nacl/nacl_thread.h', 'nacl/sel_main.cc', 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_); + } +} + diff --git a/chrome/test/nacl/nacl_sandbox_test.cc b/chrome/test/nacl/nacl_sandbox_test.cc new file mode 100644 index 0000000..1e1b856 --- /dev/null +++ b/chrome/test/nacl/nacl_sandbox_test.cc @@ -0,0 +1,44 @@ +// 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/test/nacl/nacl_sandbox_test.h" + +#include "base/file_util.h" +#include "base/path_service.h" +#include "chrome/common/chrome_switches.h" + +namespace { + +// Base url is specified in nacl_test. +const FilePath::CharType kSrpcHwHtmlFileName[] = + FILE_PATH_LITERAL("srpc_hw.html"); + +} // anonymous namespace + +NaClSandboxTest::NaClSandboxTest() : NaClTest() { + // Append the --test-nacl-sandbox=$TESTDLL flag before launching. + FilePath dylibDir; + PathService::Get(base::DIR_EXE, &dylibDir); +#if defined(OS_MACOSX) + dylibDir = dylibDir.AppendASCII("libnacl_security_tests.dylib"); + launch_arguments_.AppendSwitchWithValue(switches::kTestNaClSandbox, + dylibDir.value()); +#elif defined(OS_WIN) + // Let the NaCl process detect if it is 64-bit or not and hack on + // the appropriate suffix to this dll. + dylibDir = dylibDir.AppendASCII("nacl_security_tests"); + launch_arguments_.AppendSwitchWithValue(switches::kTestNaClSandbox, + dylibDir.value()); +#elif defined(OS_LINUX) + // We currently do not test the Chrome Linux SUID or seccomp sandboxes. +#endif +} + +NaClSandboxTest::~NaClSandboxTest() {} + +TEST_F(NaClSandboxTest, NaClOuterSBTest) { + // Load a helloworld .nexe to trigger the nacl loader test. + FilePath test_file(kSrpcHwHtmlFileName); + RunTest(test_file, action_max_timeout_ms()); +} diff --git a/chrome/test/nacl/nacl_sandbox_test.h b/chrome/test/nacl/nacl_sandbox_test.h new file mode 100644 index 0000000..578535a --- /dev/null +++ b/chrome/test/nacl/nacl_sandbox_test.h @@ -0,0 +1,24 @@ +// 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_TEST_NACL_NACL_SANDBOX_TEST_H_ +#define CHROME_TEST_NACL_NACL_SANDBOX_TEST_H_ + +#include "chrome/test/nacl/nacl_test.h" + +class FilePath; + +// This class implements integration tests for Native Client. +// Specifically, this tests that the sandbox is active by the time a +// NaCl module is loaded. To force a NaCl module to be loaded, +// it will navigate to a page containing a simple NaCl module. +// The NaCl module itself won't exercise the sandbox, but a DLL will be +// loaded into the same process that does exercise the sandbox. +class NaClSandboxTest : public NaClTest { + protected: + NaClSandboxTest(); + virtual ~NaClSandboxTest(); +}; + +#endif // CHROME_TEST_NACL_NACL_SANDBOX_TEST_H_ diff --git a/chrome/test/nacl/nacl_test.cc b/chrome/test/nacl/nacl_test.cc index 4f67bf5..5a249c3 100644 --- a/chrome/test/nacl/nacl_test.cc +++ b/chrome/test/nacl/nacl_test.cc @@ -21,29 +21,6 @@ const char kTestCompleteSuccess[] = "OK"; const FilePath::CharType kBaseUrl[] = FILE_PATH_LITERAL("http://localhost:5103/tests/prebuilt"); -const FilePath::CharType kSrpcHwHtmlFileName[] = - FILE_PATH_LITERAL("srpc_hw.html"); - -const FilePath::CharType kSrpcBasicHtmlFileName[] = - FILE_PATH_LITERAL("srpc_basic.html"); - -const FilePath::CharType kSrpcSockAddrHtmlFileName[] = - FILE_PATH_LITERAL("srpc_sockaddr.html"); - -const FilePath::CharType kSrpcShmHtmlFileName[] = - FILE_PATH_LITERAL("srpc_shm.html"); - -const FilePath::CharType kSrpcPluginHtmlFileName[] = - FILE_PATH_LITERAL("srpc_plugin.html"); - -const FilePath::CharType kSrpcNrdXferHtmlFileName[] = - FILE_PATH_LITERAL("srpc_nrd_xfer.html"); - -const FilePath::CharType kServerHtmlFileName[] = - FILE_PATH_LITERAL("server_test.html"); - -const FilePath::CharType kNpapiHwHtmlFileName[] = - FILE_PATH_LITERAL("npapi_hw.html"); } // anonymous namespace NaClTest::NaClTest() @@ -117,43 +94,3 @@ void NaClTest::TearDown() { StopHttpServer(); UITest::TearDown(); } - -TEST_F(NaClTest, ServerTest) { - FilePath test_file(kServerHtmlFileName); - RunTest(test_file, action_max_timeout_ms()); -} - -TEST_F(NaClTest, SrpcHelloWorld) { - FilePath test_file(kSrpcHwHtmlFileName); - RunTest(test_file, action_max_timeout_ms()); -} - -TEST_F(NaClTest, SrpcBasicTest) { - FilePath test_file(kSrpcBasicHtmlFileName); - RunTest(test_file, action_max_timeout_ms()); -} - -TEST_F(NaClTest, SrpcSockAddrTest) { - FilePath test_file(kSrpcSockAddrHtmlFileName); - RunTest(test_file, action_max_timeout_ms()); -} - -TEST_F(NaClTest, SrpcShmTest) { - FilePath test_file(kSrpcShmHtmlFileName); - RunTest(test_file, action_max_timeout_ms()); -} - -TEST_F(NaClTest, FLAKY_SrpcPluginTest) { - FilePath test_file(kSrpcPluginHtmlFileName); - RunTest(test_file, action_max_timeout_ms()); -} - -TEST_F(NaClTest, SrpcNrdXferTest) { - FilePath test_file(kSrpcNrdXferHtmlFileName); - RunTest(test_file, action_max_timeout_ms()); -} - -TEST_F(NaClTest, NpapiHwTest) { - FilePath test_file(kNpapiHwHtmlFileName); - RunTest(test_file, action_max_timeout_ms()); -} diff --git a/chrome/test/nacl/nacl_ui_test.cc b/chrome/test/nacl/nacl_ui_test.cc new file mode 100644 index 0000000..10af909 --- /dev/null +++ b/chrome/test/nacl/nacl_ui_test.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/test/nacl/nacl_ui_test.h" + +// TODO(jvoung) see what includes we really need. +#include "base/file_util.h" +#include "base/path_service.h" +#include "chrome/common/chrome_paths.h" + +namespace { + + // base url specified in nacl_test + +const FilePath::CharType kSrpcHwHtmlFileName[] = + FILE_PATH_LITERAL("srpc_hw.html"); + +const FilePath::CharType kSrpcBasicHtmlFileName[] = + FILE_PATH_LITERAL("srpc_basic.html"); + +const FilePath::CharType kSrpcSockAddrHtmlFileName[] = + FILE_PATH_LITERAL("srpc_sockaddr.html"); + +const FilePath::CharType kSrpcShmHtmlFileName[] = + FILE_PATH_LITERAL("srpc_shm.html"); + +const FilePath::CharType kSrpcPluginHtmlFileName[] = + FILE_PATH_LITERAL("srpc_plugin.html"); + +const FilePath::CharType kSrpcNrdXferHtmlFileName[] = + FILE_PATH_LITERAL("srpc_nrd_xfer.html"); + +const FilePath::CharType kServerHtmlFileName[] = + FILE_PATH_LITERAL("server_test.html"); + +const FilePath::CharType kNpapiHwHtmlFileName[] = + FILE_PATH_LITERAL("npapi_hw.html"); +} // anonymous namespace + +NaClUITest::NaClUITest() : NaClTest() { + // NaClTest has all we need. +} + +NaClUITest::~NaClUITest() {} + +TEST_F(NaClUITest, ServerTest) { + FilePath test_file(kServerHtmlFileName); + RunTest(test_file, action_max_timeout_ms()); +} + +TEST_F(NaClUITest, SrpcHelloWorld) { + FilePath test_file(kSrpcHwHtmlFileName); + RunTest(test_file, action_max_timeout_ms()); +} + +TEST_F(NaClUITest, SrpcBasicTest) { + FilePath test_file(kSrpcBasicHtmlFileName); + RunTest(test_file, action_max_timeout_ms()); +} + +TEST_F(NaClUITest, SrpcSockAddrTest) { + FilePath test_file(kSrpcSockAddrHtmlFileName); + RunTest(test_file, action_max_timeout_ms()); +} + +TEST_F(NaClUITest, SrpcShmTest) { + FilePath test_file(kSrpcShmHtmlFileName); + RunTest(test_file, action_max_timeout_ms()); +} + +TEST_F(NaClUITest, FLAKY_SrpcPluginTest) { + FilePath test_file(kSrpcPluginHtmlFileName); + RunTest(test_file, action_max_timeout_ms()); +} + +TEST_F(NaClUITest, SrpcNrdXferTest) { + FilePath test_file(kSrpcNrdXferHtmlFileName); + RunTest(test_file, action_max_timeout_ms()); +} + +TEST_F(NaClUITest, NpapiHwTest) { + FilePath test_file(kNpapiHwHtmlFileName); + RunTest(test_file, action_max_timeout_ms()); +} diff --git a/chrome/test/nacl/nacl_ui_test.h b/chrome/test/nacl/nacl_ui_test.h new file mode 100644 index 0000000..1b82c12 --- /dev/null +++ b/chrome/test/nacl/nacl_ui_test.h @@ -0,0 +1,18 @@ +// 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_TEST_NACL_NACL_UI_TEST_H_ +#define CHROME_TEST_NACL_NACL_UI_TEST_H_ + +#include "chrome/test/nacl/nacl_test.h" + +// The actual NaCl ui tests are hooked onto this, so that the base class +// can be reused without running tests that require loading a NaCl module. +class NaClUITest : public NaClTest { + protected: + NaClUITest(); + virtual ~NaClUITest(); +}; + +#endif // CHROME_TEST_NACL_NACL_UI_TEST_H_ diff --git a/chrome/test/nacl_security_tests/commands_posix.cc b/chrome/test/nacl_security_tests/commands_posix.cc new file mode 100644 index 0000000..85196e3 --- /dev/null +++ b/chrome/test/nacl_security_tests/commands_posix.cc @@ -0,0 +1,112 @@ +// 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 "./commands_posix.h" + +#include <fcntl.h> +#include <netdb.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> + +#include <string> + +// Sandbox access tests (mimic'ing "sandbox/tests/validation_tests/commands.h") + +namespace sandbox { + +SboxTestResult TestOpenReadFile(const char *path) { + int fd = open(path, O_RDONLY | O_CREAT); + if (-1 == fd) { + return SBOX_TEST_DENIED; + } else { + fprintf(stderr, "OOPS: Opened file for read %s %d\n", path, fd); + close(fd); + return SBOX_TEST_SUCCEEDED; + } +} + +SboxTestResult TestOpenWriteFile(const char *path) { + int fd = open(path, O_WRONLY | O_CREAT); + if (-1 == fd) { + return SBOX_TEST_DENIED; + } else { + fprintf(stderr, "OOPS: Opened file for write %s %d\n", path, fd); + close(fd); + return SBOX_TEST_SUCCEEDED; + } +} + +SboxTestResult TestCreateProcess(const char *path) { + pid_t pid; + int exec_res; + int child_stat; + + pid = fork(); + if (0 == pid) { + exec_res = execl(path, path, NULL); + if (exec_res) { + return SBOX_TEST_DENIED; + } else { + return SBOX_TEST_SUCCEEDED; + } + return SBOX_TEST_SUCCEEDED; + } else if (0 < pid) { + fprintf(stderr, "PARENT: Oops, forked child!\n"); + waitpid(pid, &child_stat, WNOHANG); + return SBOX_TEST_SUCCEEDED; + } else { + return SBOX_TEST_DENIED; + } +} + +SboxTestResult TestConnect(const char *url) { + int conn_sock; + struct addrinfo hints, *servinfo, *p; + int rv; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + rv = getaddrinfo(url, "http", &hints, &servinfo); + if (0 != rv) { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); + return SBOX_TEST_DENIED; + } + + p = servinfo; + // Just try the first entry. + conn_sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol); + if (-1 == conn_sock) { + perror("socket"); + freeaddrinfo(servinfo); + fprintf(stderr, "Error at socket()\n"); + return SBOX_TEST_DENIED; + } + + if (-1 == connect(conn_sock, p->ai_addr, p->ai_addrlen)) { + close(conn_sock); + freeaddrinfo(servinfo); + return SBOX_TEST_DENIED; + } + + fprintf(stderr, "Connected to server.\n"); + shutdown(conn_sock, SHUT_RDWR); + close(conn_sock); + freeaddrinfo(servinfo); + return SBOX_TEST_SUCCEEDED; +} + +// TODO(jvoung): test more: e.g., bind and accept. +// chmod, unlink, symlink, ... if guaranteed a test file that would normally +// allow us to do such things (i.e., we want the test operations to be +// context-independent, yet leave no traces). + +SboxTestResult TestDummyFails() { + fprintf(stderr, "Running dummy sandbox test, which should fail\n"); + return SBOX_TEST_SUCCEEDED; +} + +} // namespace sandbox diff --git a/chrome/test/nacl_security_tests/commands_posix.h b/chrome/test/nacl_security_tests/commands_posix.h new file mode 100644 index 0000000..95d5647 --- /dev/null +++ b/chrome/test/nacl_security_tests/commands_posix.h @@ -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. + +#ifndef CHROME_TEST_NACL_SECURITY_TESTS_COMMANDS_POSIX_H_ +#define CHROME_TEST_NACL_SECURITY_TESTS_COMMANDS_POSIX_H_ + +// TODO(jvoung): factor out the SboxTestResult from +// sandbox/tests/common/controller.h +// to make it OS independent. + +namespace sandbox { + +#define SEVERITY_INFO_FLAGS 0x40000000 +#define SEVERITY_ERROR_FLAGS 0xC0000000 +#define CUSTOMER_CODE 0x20000000 +#define SBOX_TESTS_FACILITY 0x05B10000 + +enum SboxTestResult { + SBOX_TEST_FIRST_RESULT = 8998, + SBOX_TEST_SUCCEEDED, + SBOX_TEST_PING_OK, + SBOX_TEST_FIRST_INFO = SBOX_TEST_FIRST_RESULT | SEVERITY_INFO_FLAGS, + SBOX_TEST_DENIED, // Access was denied. + SBOX_TEST_NOT_FOUND, // The resource was not found. + SBOX_TEST_FIRST_ERROR = SBOX_TEST_FIRST_RESULT | SEVERITY_ERROR_FLAGS, + SBOX_TEST_INVALID_PARAMETER, + SBOX_TEST_FAILED_TO_RUN_TEST, + SBOX_TEST_FAILED_TO_EXECUTE_COMMAND, + SBOX_TEST_TIMED_OUT, + SBOX_TEST_FAILED, + SBOX_TEST_LAST_RESULT +}; + +// Sandbox access tests for Mac and Linux +// (mimic'ing "sandbox/tests/validation_tests/commands.h") + +SboxTestResult TestOpenReadFile(const char* path); + +SboxTestResult TestOpenWriteFile(const char* path); + +SboxTestResult TestCreateProcess(const char* path); + +SboxTestResult TestConnect(const char* url); + +// Dummy test that returns SBOX_TEST_SUCCEEDED +// (so it fails, because everything should be denied). +SboxTestResult TestDummyFails(); + +} // namespace sandbox + +#endif // CHROME_TEST_NACL_SECURITY_TESTS_COMMANDS_POSIX_H_ + diff --git a/chrome/test/nacl_security_tests/nacl_security_tests_linux.cc b/chrome/test/nacl_security_tests/nacl_security_tests_linux.cc new file mode 100644 index 0000000..768aa55 --- /dev/null +++ b/chrome/test/nacl_security_tests/nacl_security_tests_linux.cc @@ -0,0 +1,36 @@ +// 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/test/nacl_security_tests/nacl_security_tests_posix.h" +#include <string> +#include "chrome/test/nacl_security_tests/commands_posix.h" + +#define RETURN_IF_NOT_DENIED(x) \ + if (sandbox::SBOX_TEST_DENIED != x) { \ + return false; \ + } + +// Runs the security tests of sandbox for the nacl loader process. +extern "C" bool RunNaClLoaderTests(void) { + // Need to check if the system supports CLONE_NEWPID before testing + // the filesystem accesses (otherwise the sandbox is not enabled). + RETURN_IF_NOT_DENIED(sandbox::TestOpenReadFile("/etc")); + RETURN_IF_NOT_DENIED(sandbox::TestOpenReadFile("/tmp")); + RETURN_IF_NOT_DENIED(sandbox::TestOpenReadFile("$HOME")); + RETURN_IF_NOT_DENIED(sandbox::TestOpenWriteFile("/etc")); + RETURN_IF_NOT_DENIED(sandbox::TestOpenWriteFile("/etc/passwd")); + RETURN_IF_NOT_DENIED(sandbox::TestOpenWriteFile("/bin")); + RETURN_IF_NOT_DENIED(sandbox::TestOpenWriteFile("/usr/bin")); + RETURN_IF_NOT_DENIED(sandbox::TestOpenWriteFile("/usr/bin/bash")); + RETURN_IF_NOT_DENIED(sandbox::TestOpenWriteFile("/usr/bin/login")); + RETURN_IF_NOT_DENIED(sandbox::TestOpenWriteFile("/usr/sbin")); + RETURN_IF_NOT_DENIED(sandbox::TestOpenWriteFile("$HOME")); + + // Linux (suid) sandbox doesn't block connect, etc... + RETURN_IF_NOT_DENIED(sandbox::TestCreateProcess("/usr/bin/env")); + RETURN_IF_NOT_DENIED(sandbox::TestConnect("www.archive.org")); + + return true; +} + diff --git a/chrome/test/nacl_security_tests/nacl_security_tests_mac.cc b/chrome/test/nacl_security_tests/nacl_security_tests_mac.cc new file mode 100644 index 0000000..12f7583 --- /dev/null +++ b/chrome/test/nacl_security_tests/nacl_security_tests_mac.cc @@ -0,0 +1,46 @@ +// 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/test/nacl_security_tests/nacl_security_tests_posix.h" +#include <string> +#include "testing/gtest/include/gtest/gtest.h" +#include "chrome/test/nacl_security_tests/commands_posix.h" + +__attribute__((constructor)) +static void initializer(void) { +} + +__attribute__((destructor)) +static void finalizer(void) { +} + +namespace { +void CheckDenied(sandbox::SboxTestResult x) { + EXPECT_EQ(sandbox::SBOX_TEST_DENIED, x); +} +} // anon namespace + +extern "C" +__attribute__((visibility("default"))) +bool RunNaClLoaderTests(void) { + CheckDenied(sandbox::TestOpenReadFile("/etc")); + CheckDenied(sandbox::TestOpenReadFile("/tmp")); + CheckDenied(sandbox::TestOpenReadFile("$HOME")); + CheckDenied(sandbox::TestOpenWriteFile("/etc")); + CheckDenied(sandbox::TestOpenWriteFile("/etc/passwd")); + CheckDenied(sandbox::TestOpenWriteFile("/bin")); + CheckDenied(sandbox::TestOpenWriteFile("/usr/bin")); + CheckDenied(sandbox::TestOpenWriteFile("/usr/bin/bash")); + CheckDenied(sandbox::TestOpenWriteFile("/usr/bin/login")); + CheckDenied(sandbox::TestOpenWriteFile("/usr/sbin")); + CheckDenied(sandbox::TestOpenWriteFile("$HOME")); + + CheckDenied(sandbox::TestCreateProcess("/usr/bin/env")); + CheckDenied(sandbox::TestConnect("www.archive.org")); + + return !(testing::Test::HasFatalFailure() || + testing::Test::HasNonfatalFailure()); +} + diff --git a/chrome/test/nacl_security_tests/nacl_security_tests_posix.h b/chrome/test/nacl_security_tests/nacl_security_tests_posix.h new file mode 100644 index 0000000..251e3f0 --- /dev/null +++ b/chrome/test/nacl_security_tests/nacl_security_tests_posix.h @@ -0,0 +1,12 @@ +// 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_TEST_NACL_SECURITY_TESTS_NACL_SECURITY_TESTS_POSIX_H_ +#define CHROME_TEST_NACL_SECURITY_TESTS_NACL_SECURITY_TESTS_POSIX_H_ + +// Runs security tests against the outer sandbox of the nacl loader process. +extern "C" bool RunNaClLoaderTests(void); + +#endif // CHROME_TEST_NACL_SECURITY_TESTS_NACL_SECURITY_TESTS_POSIX_H_ + diff --git a/chrome/test/nacl_security_tests/nacl_security_tests_win.cc b/chrome/test/nacl_security_tests/nacl_security_tests_win.cc new file mode 100644 index 0000000..e95e17f --- /dev/null +++ b/chrome/test/nacl_security_tests/nacl_security_tests_win.cc @@ -0,0 +1,145 @@ +// 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/test/nacl_security_tests/nacl_security_tests_win.h" +#include <winsock2.h> +#include <ws2tcpip.h> +#include <windows.h> +#include <string> + +// TODO(jvoung): factor out the enum SboxTestResult from +// "sandbox/tests/common/controller.h" to make it OS independent + +#include "sandbox/tests/common/controller.h" +#include "sandbox/tests/validation_tests/commands.h" + +BOOL APIENTRY DllMain(HMODULE module, DWORD ul_reason_for_call, + LPVOID lpReserved) { + return TRUE; +} + +#define RETURN_IF_NOT_DENIED(x) \ + if (sandbox::SBOX_TEST_DENIED != x) { \ + return false; \ + } + +//////////////////////////////////////////////////////////// +// Additional sandbox access tests +// (not in "sandbox/tests/validation_tests/commands.h") +//////////////////////////////////////////////////////////// + +namespace sandbox { + +SboxTestResult TestCreateProcess(const wchar_t *path_str, wchar_t *cmd_str) { + STARTUPINFO si; + PROCESS_INFORMATION pi; + + ZeroMemory(&si, sizeof(si)); + ZeroMemory(&pi, sizeof(pi)); + if (!::CreateProcess(path_str, cmd_str, NULL, NULL, FALSE, 0, + NULL, NULL, &si, &pi)) { + if (ERROR_ACCESS_DENIED == ::GetLastError()) { + fprintf(stderr, "Create process denied\n"); + return SBOX_TEST_DENIED; + } else { + fprintf(stderr, "Created process denied for misc reason: %ld\n", + ::GetLastError()); + return SBOX_TEST_DENIED; + } + } else { + fprintf(stderr, "Created process\n"); + return SBOX_TEST_SUCCEEDED; + } +} + +SboxTestResult TestConnect(const char* url) { + WSADATA wsaData; + int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); + if (NO_ERROR != iResult) { + fprintf(stderr, "Error at WSAStartup()\n"); + } + + struct addrinfo hints, *servinfo, *p; + DWORD dwRet; + ZeroMemory(&hints, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + + dwRet = getaddrinfo(url, "80", &hints, &servinfo); + if (0 != dwRet) { + fprintf(stderr, "getaddrinfo failed with %d\n", dwRet); + WSACleanup(); + return SBOX_TEST_DENIED; + } + + p = servinfo; + // Just try the first entry. + SOCKET sock; + sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol); + if (INVALID_SOCKET == sock) { + fprintf(stderr, "Error at socket(): %ld\n", WSAGetLastError()); + freeaddrinfo(servinfo); + WSACleanup(); + return SBOX_TEST_DENIED; + } + + if (SOCKET_ERROR == connect(sock, p->ai_addr, + static_cast<int>(p->ai_addrlen))) { + fprintf(stderr, "Failed to connect\n"); + freeaddrinfo(servinfo); + closesocket(sock); + WSACleanup(); + return SBOX_TEST_DENIED; + } + + fprintf(stderr, "OOPS: Connected to server.\n"); + freeaddrinfo(servinfo); + closesocket(sock); + WSACleanup(); + return SBOX_TEST_SUCCEEDED; +} + +} // namespace sandbox + +//////////////////////////////////////////////////////////// + + +// Runs the security tests of sandbox for the nacl loader process. +// If a test fails, the return value is FALSE and test_count contains the +// number of tests executed, including the failing test. +extern "C" bool __declspec(dllexport) RunNaClLoaderTests(void) { + // Filesystem and Registry tests borrowed from renderer security_tests.dll + RETURN_IF_NOT_DENIED(sandbox::TestOpenReadFile(L"%SystemDrive%")); + RETURN_IF_NOT_DENIED(sandbox::TestOpenReadFile(L"%SystemRoot%")); + RETURN_IF_NOT_DENIED(sandbox::TestOpenReadFile(L"%ProgramFiles%")); + RETURN_IF_NOT_DENIED(sandbox::TestOpenReadFile(L"%SystemRoot%\\System32")); + RETURN_IF_NOT_DENIED( + sandbox::TestOpenReadFile(L"%SystemRoot%\\explorer.exe")); + RETURN_IF_NOT_DENIED( + sandbox::TestOpenReadFile(L"%SystemRoot%\\Cursors\\arrow_i.cur")); + RETURN_IF_NOT_DENIED(sandbox::TestOpenWriteFile(L"%SystemRoot%")); + RETURN_IF_NOT_DENIED(sandbox::TestOpenWriteFile(L"%ProgramFiles%")); + RETURN_IF_NOT_DENIED(sandbox::TestOpenWriteFile(L"%SystemRoot%\\System32")); + RETURN_IF_NOT_DENIED( + sandbox::TestOpenWriteFile(L"%SystemRoot%\\explorer.exe")); + RETURN_IF_NOT_DENIED( + sandbox::TestOpenWriteFile(L"%SystemRoot%\\Cursors\\arrow_i.cur")); + RETURN_IF_NOT_DENIED(sandbox::TestOpenReadFile(L"%AllUsersProfile%")); + RETURN_IF_NOT_DENIED(sandbox::TestOpenReadFile(L"%Temp%")); + RETURN_IF_NOT_DENIED(sandbox::TestOpenReadFile(L"%AppData%")); + RETURN_IF_NOT_DENIED(sandbox::TestOpenKey(HKEY_LOCAL_MACHINE, L"")); + RETURN_IF_NOT_DENIED(sandbox::TestOpenKey(HKEY_CURRENT_USER, L"")); + RETURN_IF_NOT_DENIED(sandbox::TestOpenKey(HKEY_USERS, L"")); + RETURN_IF_NOT_DENIED(sandbox::TestOpenKey(HKEY_LOCAL_MACHINE, + L"Software\\Microsoft\\Windows NT\\CurrentVersion\\WinLogon")); + + RETURN_IF_NOT_DENIED(sandbox::TestConnect("www.archive.org")); + RETURN_IF_NOT_DENIED(sandbox::TestConnect("www.google.com")); + + RETURN_IF_NOT_DENIED(sandbox::TestCreateProcess(L"%SystemRoot%\\explorer.exe", + L"%SystemRoot%\\explorer.exe")); + + return true; +} diff --git a/chrome/test/nacl_security_tests/nacl_security_tests_win.h b/chrome/test/nacl_security_tests/nacl_security_tests_win.h new file mode 100644 index 0000000..5e3bda6 --- /dev/null +++ b/chrome/test/nacl_security_tests/nacl_security_tests_win.h @@ -0,0 +1,12 @@ +// 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_TEST_NACL_SECURITY_TESTS_NACL_SECURITY_TESTS_WIN_H_ +#define CHROME_TEST_NACL_SECURITY_TESTS_NACL_SECURITY_TESTS_WIN_H_ + +// Runs security tests against the outer sandbox of the nacl loader process. +extern "C" bool __declspec(dllexport) RunNaClLoaderTests(void); + +#endif // CHROME_TEST_NACL_SECURITY_TESTS_NACL_SECURITY_TESTS_WIN_H_ + |