Index: sandbox/win/src/policy_target_test.cc |
diff --git a/sandbox/win/src/policy_target_test.cc b/sandbox/win/src/policy_target_test.cc |
deleted file mode 100644 |
index 71054abd3d5ab50f0e7f75930251c7b67ccecd67..0000000000000000000000000000000000000000 |
--- a/sandbox/win/src/policy_target_test.cc |
+++ /dev/null |
@@ -1,407 +0,0 @@ |
-// Copyright (c) 2012 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 "base/memory/shared_memory.h" |
-#include "base/strings/string_number_conversions.h" |
-#include "base/strings/string_piece.h" |
-#include "base/win/scoped_process_information.h" |
-#include "base/win/windows_version.h" |
-#include "sandbox/win/src/sandbox.h" |
-#include "sandbox/win/src/sandbox_factory.h" |
-#include "sandbox/win/src/sandbox_utils.h" |
-#include "sandbox/win/src/target_services.h" |
-#include "sandbox/win/tests/common/controller.h" |
-#include "testing/gtest/include/gtest/gtest.h" |
- |
-#if defined(OS_WIN) |
-#include "base/win/win_util.h" |
-#endif |
- |
-namespace sandbox { |
- |
-#define BINDNTDLL(name) \ |
- name ## Function name = reinterpret_cast<name ## Function>( \ |
- ::GetProcAddress(::GetModuleHandle(L"ntdll.dll"), #name)) |
- |
-// Reverts to self and verify that SetInformationToken was faked. Returns |
-// SBOX_TEST_SUCCEEDED if faked and SBOX_TEST_FAILED if not faked. |
-SBOX_TESTS_COMMAND int PolicyTargetTest_token(int argc, wchar_t **argv) { |
- HANDLE thread_token; |
- // Get the thread token, using impersonation. |
- if (!::OpenThreadToken(GetCurrentThread(), TOKEN_IMPERSONATE | |
- TOKEN_DUPLICATE, FALSE, &thread_token)) |
- return ::GetLastError(); |
- |
- ::RevertToSelf(); |
- ::CloseHandle(thread_token); |
- |
- int ret = SBOX_TEST_FAILED; |
- if (::OpenThreadToken(GetCurrentThread(), TOKEN_IMPERSONATE | TOKEN_DUPLICATE, |
- FALSE, &thread_token)) { |
- ret = SBOX_TEST_SUCCEEDED; |
- ::CloseHandle(thread_token); |
- } |
- return ret; |
-} |
- |
-// Stores the high privilege token on a static variable, change impersonation |
-// again to that one and verify that we are not interfering anymore with |
-// RevertToSelf. |
-SBOX_TESTS_COMMAND int PolicyTargetTest_steal(int argc, wchar_t **argv) { |
- static HANDLE thread_token; |
- if (!SandboxFactory::GetTargetServices()->GetState()->RevertedToSelf()) { |
- if (!::OpenThreadToken(GetCurrentThread(), TOKEN_IMPERSONATE | |
- TOKEN_DUPLICATE, FALSE, &thread_token)) |
- return ::GetLastError(); |
- } else { |
- if (!::SetThreadToken(NULL, thread_token)) |
- return ::GetLastError(); |
- |
- // See if we fake the call again. |
- int ret = PolicyTargetTest_token(argc, argv); |
- ::CloseHandle(thread_token); |
- return ret; |
- } |
- return 0; |
-} |
- |
-// Opens the thread token with and without impersonation. |
-SBOX_TESTS_COMMAND int PolicyTargetTest_token2(int argc, wchar_t **argv) { |
- HANDLE thread_token; |
- // Get the thread token, using impersonation. |
- if (!::OpenThreadToken(GetCurrentThread(), TOKEN_IMPERSONATE | |
- TOKEN_DUPLICATE, FALSE, &thread_token)) |
- return ::GetLastError(); |
- ::CloseHandle(thread_token); |
- |
- // Get the thread token, without impersonation. |
- if (!OpenThreadToken(GetCurrentThread(), TOKEN_IMPERSONATE | TOKEN_DUPLICATE, |
- TRUE, &thread_token)) |
- return ::GetLastError(); |
- ::CloseHandle(thread_token); |
- return SBOX_TEST_SUCCEEDED; |
-} |
- |
-// Opens the thread token with and without impersonation, using |
-// NtOpenThreadTokenEX. |
-SBOX_TESTS_COMMAND int PolicyTargetTest_token3(int argc, wchar_t **argv) { |
- BINDNTDLL(NtOpenThreadTokenEx); |
- if (!NtOpenThreadTokenEx) |
- return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; |
- |
- HANDLE thread_token; |
- // Get the thread token, using impersonation. |
- NTSTATUS status = NtOpenThreadTokenEx(GetCurrentThread(), |
- TOKEN_IMPERSONATE | TOKEN_DUPLICATE, |
- FALSE, 0, &thread_token); |
- if (status == STATUS_NO_TOKEN) |
- return ERROR_NO_TOKEN; |
- if (!NT_SUCCESS(status)) |
- return SBOX_TEST_FAILED; |
- |
- ::CloseHandle(thread_token); |
- |
- // Get the thread token, without impersonation. |
- status = NtOpenThreadTokenEx(GetCurrentThread(), |
- TOKEN_IMPERSONATE | TOKEN_DUPLICATE, TRUE, 0, |
- &thread_token); |
- if (!NT_SUCCESS(status)) |
- return SBOX_TEST_FAILED; |
- |
- ::CloseHandle(thread_token); |
- return SBOX_TEST_SUCCEEDED; |
-} |
- |
-// Tests that we can open the current thread. |
-SBOX_TESTS_COMMAND int PolicyTargetTest_thread(int argc, wchar_t **argv) { |
- DWORD thread_id = ::GetCurrentThreadId(); |
- HANDLE thread = ::OpenThread(SYNCHRONIZE, FALSE, thread_id); |
- if (!thread) |
- return ::GetLastError(); |
- if (!::CloseHandle(thread)) |
- return ::GetLastError(); |
- |
- return SBOX_TEST_SUCCEEDED; |
-} |
- |
-// New thread entry point: do nothing. |
-DWORD WINAPI PolicyTargetTest_thread_main(void* param) { |
- ::Sleep(INFINITE); |
- return 0; |
-} |
- |
-// Tests that we can create a new thread, and open it. |
-SBOX_TESTS_COMMAND int PolicyTargetTest_thread2(int argc, wchar_t **argv) { |
- // Use default values to create a new thread. |
- DWORD thread_id; |
- HANDLE thread = ::CreateThread(NULL, 0, &PolicyTargetTest_thread_main, 0, 0, |
- &thread_id); |
- if (!thread) |
- return ::GetLastError(); |
- if (!::CloseHandle(thread)) |
- return ::GetLastError(); |
- |
- thread = ::OpenThread(SYNCHRONIZE, FALSE, thread_id); |
- if (!thread) |
- return ::GetLastError(); |
- |
- if (!::CloseHandle(thread)) |
- return ::GetLastError(); |
- |
- return SBOX_TEST_SUCCEEDED; |
-} |
- |
-// Tests that we can call CreateProcess. |
-SBOX_TESTS_COMMAND int PolicyTargetTest_process(int argc, wchar_t **argv) { |
- // Use default values to create a new process. |
- STARTUPINFO startup_info = {0}; |
- startup_info.cb = sizeof(startup_info); |
- PROCESS_INFORMATION temp_process_info = {}; |
- // Note: CreateProcessW() can write to its lpCommandLine, don't pass a |
- // raw string literal. |
- base::string16 writable_cmdline_str(L"foo.exe"); |
- if (!::CreateProcessW(L"foo.exe", &writable_cmdline_str[0], NULL, NULL, FALSE, |
- 0, NULL, NULL, &startup_info, &temp_process_info)) |
- return SBOX_TEST_SUCCEEDED; |
- base::win::ScopedProcessInformation process_info(temp_process_info); |
- return SBOX_TEST_FAILED; |
-} |
- |
-TEST(PolicyTargetTest, SetInformationThread) { |
- TestRunner runner; |
- runner.SetTestState(BEFORE_REVERT); |
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"PolicyTargetTest_token")); |
- |
- runner.SetTestState(AFTER_REVERT); |
- EXPECT_EQ(ERROR_NO_TOKEN, runner.RunTest(L"PolicyTargetTest_token")); |
- |
- runner.SetTestState(EVERY_STATE); |
- EXPECT_EQ(SBOX_TEST_FAILED, runner.RunTest(L"PolicyTargetTest_steal")); |
-} |
- |
-TEST(PolicyTargetTest, OpenThreadToken) { |
- TestRunner runner; |
- runner.SetTestState(BEFORE_REVERT); |
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"PolicyTargetTest_token2")); |
- |
- runner.SetTestState(AFTER_REVERT); |
- EXPECT_EQ(ERROR_NO_TOKEN, runner.RunTest(L"PolicyTargetTest_token2")); |
-} |
- |
-TEST(PolicyTargetTest, OpenThreadTokenEx) { |
- TestRunner runner; |
- |
- runner.SetTestState(BEFORE_REVERT); |
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"PolicyTargetTest_token3")); |
- |
- runner.SetTestState(AFTER_REVERT); |
- EXPECT_EQ(ERROR_NO_TOKEN, runner.RunTest(L"PolicyTargetTest_token3")); |
-} |
- |
-TEST(PolicyTargetTest, OpenThread) { |
- TestRunner runner; |
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"PolicyTargetTest_thread")) << |
- "Opens the current thread"; |
- |
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"PolicyTargetTest_thread2")) << |
- "Creates a new thread and opens it"; |
-} |
- |
-TEST(PolicyTargetTest, OpenProcess) { |
- TestRunner runner; |
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"PolicyTargetTest_process")) << |
- "Opens a process"; |
-} |
- |
-// Launches the app in the sandbox and ask it to wait in an |
-// infinite loop. Waits for 2 seconds and then check if the |
-// desktop associated with the app thread is not the same as the |
-// current desktop. |
-TEST(PolicyTargetTest, DesktopPolicy) { |
- BrokerServices* broker = GetBroker(); |
- |
- // Precreate the desktop. |
- TargetPolicy* temp_policy = broker->CreatePolicy(); |
- temp_policy->CreateAlternateDesktop(false); |
- temp_policy->Release(); |
- |
- ASSERT_TRUE(broker != NULL); |
- |
- // Get the path to the sandboxed app. |
- wchar_t prog_name[MAX_PATH]; |
- GetModuleFileNameW(NULL, prog_name, MAX_PATH); |
- |
- base::string16 arguments(L"\""); |
- arguments += prog_name; |
- arguments += L"\" -child 0 wait"; // Don't care about the "state" argument. |
- |
- // Launch the app. |
- ResultCode result = SBOX_ALL_OK; |
- base::win::ScopedProcessInformation target; |
- |
- TargetPolicy* policy = broker->CreatePolicy(); |
- policy->SetAlternateDesktop(false); |
- policy->SetTokenLevel(USER_INTERACTIVE, USER_LOCKDOWN); |
- PROCESS_INFORMATION temp_process_info = {}; |
- result = broker->SpawnTarget(prog_name, arguments.c_str(), policy, |
- &temp_process_info); |
- base::string16 desktop_name = policy->GetAlternateDesktop(); |
- policy->Release(); |
- |
- EXPECT_EQ(SBOX_ALL_OK, result); |
- if (result == SBOX_ALL_OK) |
- target.Set(temp_process_info); |
- |
- EXPECT_EQ(1u, ::ResumeThread(target.thread_handle())); |
- |
- EXPECT_EQ(static_cast<DWORD>(WAIT_TIMEOUT), |
- ::WaitForSingleObject(target.process_handle(), 2000)); |
- |
- EXPECT_NE(::GetThreadDesktop(target.thread_id()), |
- ::GetThreadDesktop(::GetCurrentThreadId())); |
- |
- HDESK desk = ::OpenDesktop(desktop_name.c_str(), 0, FALSE, DESKTOP_ENUMERATE); |
- EXPECT_TRUE(NULL != desk); |
- EXPECT_TRUE(::CloseDesktop(desk)); |
- EXPECT_TRUE(::TerminateProcess(target.process_handle(), 0)); |
- |
- ::WaitForSingleObject(target.process_handle(), INFINITE); |
- |
- // Close the desktop handle. |
- temp_policy = broker->CreatePolicy(); |
- temp_policy->DestroyAlternateDesktop(); |
- temp_policy->Release(); |
- |
- // Make sure the desktop does not exist anymore. |
- desk = ::OpenDesktop(desktop_name.c_str(), 0, FALSE, DESKTOP_ENUMERATE); |
- EXPECT_TRUE(NULL == desk); |
-} |
- |
-// Launches the app in the sandbox and ask it to wait in an |
-// infinite loop. Waits for 2 seconds and then check if the |
-// winstation associated with the app thread is not the same as the |
-// current desktop. |
-TEST(PolicyTargetTest, WinstaPolicy) { |
- BrokerServices* broker = GetBroker(); |
- |
- // Precreate the desktop. |
- TargetPolicy* temp_policy = broker->CreatePolicy(); |
- temp_policy->CreateAlternateDesktop(true); |
- temp_policy->Release(); |
- |
- ASSERT_TRUE(broker != NULL); |
- |
- // Get the path to the sandboxed app. |
- wchar_t prog_name[MAX_PATH]; |
- GetModuleFileNameW(NULL, prog_name, MAX_PATH); |
- |
- base::string16 arguments(L"\""); |
- arguments += prog_name; |
- arguments += L"\" -child 0 wait"; // Don't care about the "state" argument. |
- |
- // Launch the app. |
- ResultCode result = SBOX_ALL_OK; |
- base::win::ScopedProcessInformation target; |
- |
- TargetPolicy* policy = broker->CreatePolicy(); |
- policy->SetAlternateDesktop(true); |
- policy->SetTokenLevel(USER_INTERACTIVE, USER_LOCKDOWN); |
- PROCESS_INFORMATION temp_process_info = {}; |
- result = broker->SpawnTarget(prog_name, arguments.c_str(), policy, |
- &temp_process_info); |
- base::string16 desktop_name = policy->GetAlternateDesktop(); |
- policy->Release(); |
- |
- EXPECT_EQ(SBOX_ALL_OK, result); |
- if (result == SBOX_ALL_OK) |
- target.Set(temp_process_info); |
- |
- EXPECT_EQ(1u, ::ResumeThread(target.thread_handle())); |
- |
- EXPECT_EQ(static_cast<DWORD>(WAIT_TIMEOUT), |
- ::WaitForSingleObject(target.process_handle(), 2000)); |
- |
- EXPECT_NE(::GetThreadDesktop(target.thread_id()), |
- ::GetThreadDesktop(::GetCurrentThreadId())); |
- |
- ASSERT_FALSE(desktop_name.empty()); |
- |
- // Make sure there is a backslash, for the window station name. |
- EXPECT_NE(desktop_name.find_first_of(L'\\'), base::string16::npos); |
- |
- // Isolate the desktop name. |
- desktop_name = desktop_name.substr(desktop_name.find_first_of(L'\\') + 1); |
- |
- HDESK desk = ::OpenDesktop(desktop_name.c_str(), 0, FALSE, DESKTOP_ENUMERATE); |
- // This should fail if the desktop is really on another window station. |
- EXPECT_FALSE(NULL != desk); |
- EXPECT_TRUE(::TerminateProcess(target.process_handle(), 0)); |
- |
- ::WaitForSingleObject(target.process_handle(), INFINITE); |
- |
- // Close the desktop handle. |
- temp_policy = broker->CreatePolicy(); |
- temp_policy->DestroyAlternateDesktop(); |
- temp_policy->Release(); |
-} |
- |
-// Launches the app in the sandbox and share a handle with it. The app should |
-// be able to use the handle. |
-TEST(PolicyTargetTest, ShareHandleTest) { |
- |
- BrokerServices* broker = GetBroker(); |
- ASSERT_TRUE(broker != NULL); |
- |
- base::StringPiece contents = "Hello World"; |
- std::string name = "TestSharedMemory"; |
- base::SharedMemoryCreateOptions options; |
- options.size = contents.size(); |
- options.share_read_only = true; |
- options.name_deprecated = &name; |
- base::SharedMemory writable_shmem; |
- ASSERT_TRUE(writable_shmem.Create(options)); |
- ASSERT_TRUE(writable_shmem.Map(options.size)); |
- memcpy(writable_shmem.memory(), contents.data(), contents.size()); |
- |
- base::SharedMemory read_only_view; |
- ASSERT_TRUE(read_only_view.Open(name, true)); |
- |
- // Get the path to the sandboxed app. |
- wchar_t prog_name[MAX_PATH]; |
- GetModuleFileNameW(NULL, prog_name, MAX_PATH); |
- |
- TargetPolicy* policy = broker->CreatePolicy(); |
- policy->AddHandleToShare(read_only_view.handle().GetHandle()); |
- |
- base::string16 arguments(L"\""); |
- arguments += prog_name; |
- arguments += L"\" -child 0 shared_memory_handle "; |
- arguments += base::UintToString16( |
- base::win::HandleToUint32(read_only_view.handle().GetHandle())); |
- |
- // Launch the app. |
- ResultCode result = SBOX_ALL_OK; |
- base::win::ScopedProcessInformation target; |
- |
- policy->SetTokenLevel(USER_INTERACTIVE, USER_LOCKDOWN); |
- PROCESS_INFORMATION temp_process_info = {}; |
- result = broker->SpawnTarget(prog_name, arguments.c_str(), policy, |
- &temp_process_info); |
- policy->Release(); |
- |
- EXPECT_EQ(SBOX_ALL_OK, result); |
- if (result == SBOX_ALL_OK) |
- target.Set(temp_process_info); |
- |
- EXPECT_EQ(1u, ::ResumeThread(target.thread_handle())); |
- |
- EXPECT_EQ(static_cast<DWORD>(WAIT_TIMEOUT), |
- ::WaitForSingleObject(target.process_handle(), 2000)); |
- |
- EXPECT_TRUE(::TerminateProcess(target.process_handle(), 0)); |
- |
- ::WaitForSingleObject(target.process_handle(), INFINITE); |
-} |
- |
-} // namespace sandbox |