diff options
author | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-05 18:14:22 +0000 |
---|---|---|
committer | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-05 18:14:22 +0000 |
commit | ef159f884e077a13cd142bccd9b8ae7bf1ad49cd (patch) | |
tree | 3c4f8887c1bb6aab3a90f34637dfc58c92b3c358 /sandbox/win | |
parent | 762c75eda5f802b528fbb0da09d1ee053e07409d (diff) | |
download | chromium_src-ef159f884e077a13cd142bccd9b8ae7bf1ad49cd.zip chromium_src-ef159f884e077a13cd142bccd9b8ae7bf1ad49cd.tar.gz chromium_src-ef159f884e077a13cd142bccd9b8ae7bf1ad49cd.tar.bz2 |
Sandbox: Add support for Windows 8' AppContainer.
Both sandboxes are not fully compatible yet; it is not
possible to enable the AppContainer if the process is to be
fully sandboxed (USER_LOCKDOWN), but the sandbox is user
configurable anyway.
BUG=none
TEST=sbox_unittests, sbox_integration_tests
Review URL: https://chromiumcodereview.appspot.com/10825425
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@154986 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sandbox/win')
-rw-r--r-- | sandbox/win/sandbox_win.gypi | 21 | ||||
-rw-r--r-- | sandbox/win/src/app_container.cc | 174 | ||||
-rw-r--r-- | sandbox/win/src/app_container.h | 68 | ||||
-rw-r--r-- | sandbox/win/src/app_container_test.cc | 143 | ||||
-rw-r--r-- | sandbox/win/src/app_container_unittest.cc | 58 | ||||
-rw-r--r-- | sandbox/win/src/broker_services.cc | 57 | ||||
-rw-r--r-- | sandbox/win/src/broker_services.h | 26 | ||||
-rw-r--r-- | sandbox/win/src/sandbox.h | 15 | ||||
-rw-r--r-- | sandbox/win/src/sandbox_policy.h | 33 | ||||
-rw-r--r-- | sandbox/win/src/sandbox_policy_base.cc | 69 | ||||
-rw-r--r-- | sandbox/win/src/sandbox_policy_base.h | 25 | ||||
-rw-r--r-- | sandbox/win/src/sandbox_types.h | 12 | ||||
-rw-r--r-- | sandbox/win/src/sync_policy_test.cc | 3 | ||||
-rw-r--r-- | sandbox/win/src/sync_policy_test.h | 18 | ||||
-rw-r--r-- | sandbox/win/src/target_process.cc | 12 | ||||
-rw-r--r-- | sandbox/win/src/target_process.h | 7 | ||||
-rw-r--r-- | sandbox/win/tests/common/controller.h | 6 |
17 files changed, 665 insertions, 82 deletions
diff --git a/sandbox/win/sandbox_win.gypi b/sandbox/win/sandbox_win.gypi index 3a6ecc7..7160bf7 100644 --- a/sandbox/win/sandbox_win.gypi +++ b/sandbox/win/sandbox_win.gypi @@ -14,6 +14,8 @@ 'sources': [ 'src/acl.cc', 'src/acl.h', + 'src/app_container.cc', + 'src/app_container.h', 'src/broker_services.cc', 'src/broker_services.h', 'src/crosscall_client.h', @@ -229,11 +231,7 @@ '../testing/gtest.gyp:gtest', ], 'sources': [ - 'tests/common/controller.cc', - 'tests/common/controller.h', - 'tests/common/test_utils.cc', - 'tests/common/test_utils.h', - 'tests/integration_tests/integration_tests.cc', + 'src/app_container_test.cc', 'src/dep_test.cc', 'src/file_policy_test.cc', 'src/handle_policy_test.cc', @@ -246,7 +244,13 @@ 'src/process_policy_test.cc', 'src/registry_policy_test.cc', 'src/sync_policy_test.cc', + 'src/sync_policy_test.h', 'src/unload_dll_test.cc', + 'tests/common/controller.cc', + 'tests/common/controller.h', + 'tests/common/test_utils.cc', + 'tests/common/test_utils.h', + 'tests/integration_tests/integration_tests.cc', ], }, { @@ -273,9 +277,7 @@ '../testing/gtest.gyp:gtest', ], 'sources': [ - 'tests/common/test_utils.cc', - 'tests/common/test_utils.h', - 'tests/unit_tests/unit_tests.cc', + 'src/app_container_unittest.cc', 'src/interception_unittest.cc', 'src/service_resolver_unittest.cc', 'src/restricted_token_unittest.cc', @@ -287,6 +289,9 @@ 'src/ipc_unittest.cc', 'src/threadpool_unittest.cc', 'src/win_utils_unittest.cc', + 'tests/common/test_utils.cc', + 'tests/common/test_utils.h', + 'tests/unit_tests/unit_tests.cc', ], }, { diff --git a/sandbox/win/src/app_container.cc b/sandbox/win/src/app_container.cc new file mode 100644 index 0000000..ee978b9 --- /dev/null +++ b/sandbox/win/src/app_container.cc @@ -0,0 +1,174 @@ +// 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 "sandbox/win/src/app_container.h" + +#include <Sddl.h> +#include <vector> + +#include "base/logging.h" +#include "base/memory/scoped_ptr.h" +#include "base/win/startup_information.h" +#include "sandbox/win/src/internal_types.h" + +namespace { + +// Converts the passed in sid string to a PSID that must be relased with +// LocalFree. +PSID ConvertSid(const string16& sid) { + PSID local_sid; + if (!ConvertStringSidToSid(sid.c_str(), &local_sid)) + return NULL; + return local_sid; +} + +} // namespace + +namespace sandbox { + +AppContainerAttributes::AppContainerAttributes() { + memset(&capabilities_, 0, sizeof(capabilities_)); +} + +AppContainerAttributes::~AppContainerAttributes() { + for (size_t i = 0; i < attributes_.size(); i++) + LocalFree(attributes_[i].Sid); + LocalFree(capabilities_.AppContainerSid); +} + +ResultCode AppContainerAttributes::SetAppContainer( + const string16& app_container_sid, + const std::vector<string16>& capabilities) { + DCHECK(!capabilities_.AppContainerSid); + DCHECK(attributes_.empty()); + capabilities_.AppContainerSid = ConvertSid(app_container_sid); + if (!capabilities_.AppContainerSid) + return SBOX_ERROR_INVALID_APP_CONTAINER; + + for (size_t i = 0; i < capabilities.size(); i++) { + SID_AND_ATTRIBUTES sid_and_attributes; + sid_and_attributes.Sid = ConvertSid(capabilities[i]); + if (!sid_and_attributes.Sid) + return SBOX_ERROR_INVALID_CAPABILITY; + + sid_and_attributes.Attributes = SE_GROUP_ENABLED; + attributes_.push_back(sid_and_attributes); + } + + if (capabilities.size()) { + capabilities_.CapabilityCount = static_cast<DWORD>(capabilities.size()); + capabilities_.Capabilities = &attributes_[0]; + } + return SBOX_ALL_OK; +} + +ResultCode AppContainerAttributes::ShareForStartup( + base::win::StartupInformation* startup_information) const { + // The only thing we support so far is an AppContainer. + if (!capabilities_.AppContainerSid) + return SBOX_ERROR_INVALID_APP_CONTAINER; + + if (!startup_information->UpdateProcThreadAttribute( + PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES, + const_cast<SECURITY_CAPABILITIES*>(&capabilities_), + sizeof(capabilities_))) { + DPLOG(ERROR) << "Failed UpdateProcThreadAttribute"; + return SBOX_ERROR_CANNOT_INIT_APPCONTAINER; + } + return SBOX_ALL_OK; +} + +bool AppContainerAttributes::HasAppContainer() const { + return (capabilities_.AppContainerSid != NULL); +} + +ResultCode CreateAppContainer(const string16& sid, const string16& name) { + PSID local_sid; + if (!ConvertStringSidToSid(sid.c_str(), &local_sid)) + return SBOX_ERROR_INVALID_APP_CONTAINER; + + typedef HRESULT (WINAPI* AppContainerRegisterSidPtr)(PSID sid, + LPCWSTR moniker, + LPCWSTR display_name); + static AppContainerRegisterSidPtr AppContainerRegisterSid = NULL; + + if (!AppContainerRegisterSid) { + HMODULE module = GetModuleHandle(kKerneldllName); + AppContainerRegisterSid = reinterpret_cast<AppContainerRegisterSidPtr>( + GetProcAddress(module, "AppContainerRegisterSid")); + } + + ResultCode operation_result = SBOX_ERROR_GENERIC; + if (AppContainerRegisterSid) { + HRESULT rv = AppContainerRegisterSid(local_sid, name.c_str(), name.c_str()); + if (SUCCEEDED(rv)) + operation_result = SBOX_ALL_OK; + else + DLOG(ERROR) << "AppContainerRegisterSid error:" << std::hex << rv; + } + LocalFree(local_sid); + return operation_result; +} + +ResultCode DeleteAppContainer(const string16& sid) { + PSID local_sid; + if (!ConvertStringSidToSid(sid.c_str(), &local_sid)) + return SBOX_ERROR_INVALID_APP_CONTAINER; + + typedef HRESULT (WINAPI* AppContainerUnregisterSidPtr)(PSID sid); + static AppContainerUnregisterSidPtr AppContainerUnregisterSid = NULL; + + if (!AppContainerUnregisterSid) { + HMODULE module = GetModuleHandle(kKerneldllName); + AppContainerUnregisterSid = reinterpret_cast<AppContainerUnregisterSidPtr>( + GetProcAddress(module, "AppContainerUnregisterSid")); + } + + ResultCode operation_result = SBOX_ERROR_GENERIC; + if (AppContainerUnregisterSid) { + HRESULT rv = AppContainerUnregisterSid(local_sid); + if (SUCCEEDED(rv)) + operation_result = SBOX_ALL_OK; + else + DLOG(ERROR) << "AppContainerUnregisterSid error:" << std::hex << rv; + } + LocalFree(local_sid); + return operation_result; +} + +string16 LookupAppContainer(const string16& sid) { + PSID local_sid; + if (!ConvertStringSidToSid(sid.c_str(), &local_sid)) + return string16(); + + typedef HRESULT (WINAPI* AppContainerLookupMonikerPtr)(PSID sid, + LPWSTR* moniker); + typedef BOOLEAN (WINAPI* AppContainerFreeMemoryPtr)(void* ptr); + + static AppContainerLookupMonikerPtr AppContainerLookupMoniker = NULL; + static AppContainerFreeMemoryPtr AppContainerFreeMemory = NULL; + + if (!AppContainerLookupMoniker || !AppContainerFreeMemory) { + HMODULE module = GetModuleHandle(kKerneldllName); + AppContainerLookupMoniker = reinterpret_cast<AppContainerLookupMonikerPtr>( + GetProcAddress(module, "AppContainerLookupMoniker")); + AppContainerFreeMemory = reinterpret_cast<AppContainerFreeMemoryPtr>( + GetProcAddress(module, "AppContainerFreeMemory")); + } + + if (!AppContainerLookupMoniker || !AppContainerFreeMemory) + return string16(); + + wchar_t* buffer = NULL; + HRESULT rv = AppContainerLookupMoniker(local_sid, &buffer); + if (FAILED(rv)) + return string16(); + + string16 name(buffer); + if (!AppContainerFreeMemory(buffer)) + NOTREACHED(); + return name; +} + +} // namespace sandbox diff --git a/sandbox/win/src/app_container.h b/sandbox/win/src/app_container.h new file mode 100644 index 0000000..5ff0b9b --- /dev/null +++ b/sandbox/win/src/app_container.h @@ -0,0 +1,68 @@ +// 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. + +#ifndef SANDBOX_WIN_SRC_APP_CONTAINER_H_ +#define SANDBOX_WIN_SRC_APP_CONTAINER_H_ + +#include <windows.h> + +#include <vector> + +#include "base/memory/scoped_ptr.h" +#include "base/string16.h" +#include "sandbox/win/src/sandbox_types.h" + +namespace base { +namespace win { +class StartupInformation; +} +} + +namespace sandbox { + +// Maintains an attribute list to be used during creation of a new sandboxed +// process. +class AppContainerAttributes { + public: + AppContainerAttributes(); + ~AppContainerAttributes(); + + // Sets the AppContainer and capabilities to be used with the new process. + ResultCode SetAppContainer(const string16& app_container_sid, + const std::vector<string16>& capabilities); + + // Updates the proc_thred attribute list of the provided startup_information + // with the app container related data. + // WARNING: startup_information just points back to our internal memory, so + // the lifetime of this object has to be greater than the lifetime of the + // provided startup_information. + ResultCode ShareForStartup( + base::win::StartupInformation* startup_information) const; + + bool HasAppContainer() const; + + private: + SECURITY_CAPABILITIES capabilities_; + std::vector<SID_AND_ATTRIBUTES> attributes_; + + DISALLOW_COPY_AND_ASSIGN(AppContainerAttributes); +}; + +// Creates a new AppContainer on the system. |sid| is the identifier of the new +// AppContainer, and |name| will be used as both the display name and moniker. +// This function fails if the OS doesn't support AppContainers, or if there is +// an AppContainer registered with the same id. +ResultCode CreateAppContainer(const string16& sid, const string16& name); + +// Deletes an AppContainer previously created with a successfull call to +// CreateAppContainer. +ResultCode DeleteAppContainer(const string16& sid); + +// Retrieves the name associated with the provided AppContainer sid. Returns an +// empty string if the AppContainer is not registered with the system. +string16 LookupAppContainer(const string16& sid); + +} // namespace sandbox + +#endif // SANDBOX_WIN_SRC_APP_CONTAINER_H_ diff --git a/sandbox/win/src/app_container_test.cc b/sandbox/win/src/app_container_test.cc new file mode 100644 index 0000000..0d4d177 --- /dev/null +++ b/sandbox/win/src/app_container_test.cc @@ -0,0 +1,143 @@ +// 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 <windows.h> + +#define _ATL_NO_EXCEPTIONS +#include <atlbase.h> +#include <atlsecurity.h> + +#include "base/string16.h" +#include "base/win/scoped_handle.h" +#include "base/win/windows_version.h" +#include "sandbox/win/src/sync_policy_test.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +const wchar_t kAppContainerName[] = L"sbox_test"; +const wchar_t kAppContainerSid[] = + L"S-1-15-2-3251537155-1984446955-2931258699-841473695-1938553385-" + L"924012148-2839372144"; + +const ULONG kSharing = FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE; + +HANDLE CreateTaggedEvent(const string16& name, const string16& sid) { + base::win::ScopedHandle event(CreateEvent(NULL, FALSE, FALSE, name.c_str())); + if (!event.IsValid()) + return NULL; + + wchar_t file_name[MAX_PATH] = {}; + wchar_t temp_directory[MAX_PATH] = {}; + GetTempPath(MAX_PATH, temp_directory); + GetTempFileName(temp_directory, L"test", 0, file_name); + + base::win::ScopedHandle file; + file.Set(CreateFile(file_name, GENERIC_READ | STANDARD_RIGHTS_READ, kSharing, + NULL, OPEN_EXISTING, 0, NULL)); + DeleteFile(file_name); + if (!file.IsValid()) + return NULL; + + CSecurityDesc sd; + if (!AtlGetSecurityDescriptor(file.Get(), SE_FILE_OBJECT, &sd, + OWNER_SECURITY_INFORMATION | + GROUP_SECURITY_INFORMATION | + DACL_SECURITY_INFORMATION)) { + return NULL; + } + + PSID local_sid; + if (!ConvertStringSidToSid(sid.c_str(), &local_sid)) + return NULL; + + CDacl new_dacl; + sd.GetDacl(&new_dacl); + CSid csid(reinterpret_cast<SID*>(local_sid)); + new_dacl.AddAllowedAce(csid, EVENT_ALL_ACCESS); + if (!AtlSetDacl(event.Get(), SE_KERNEL_OBJECT, new_dacl)) + event.Close(); + + LocalFree(local_sid); + return event.IsValid() ? event.Take() : NULL; +} + +} // namespace + +namespace sandbox { + +TEST(AppContainerTest, AllowOpenEvent) { + if (base::win::OSInfo::GetInstance()->version() < base::win::VERSION_WIN8) + return; + + TestRunner runner(JOB_UNPROTECTED, USER_UNPROTECTED, USER_UNPROTECTED); + + const wchar_t capability[] = L"S-1-15-3-12345678-87654321"; + base::win::ScopedHandle handle(CreateTaggedEvent(L"test", capability)); + ASSERT_TRUE(handle.IsValid()); + + EXPECT_EQ(SBOX_ALL_OK, + runner.broker()->InstallAppContainer(kAppContainerSid, + kAppContainerName)); + EXPECT_EQ(SBOX_ALL_OK, runner.GetPolicy()->SetCapability(capability)); + EXPECT_EQ(SBOX_ALL_OK, runner.GetPolicy()->SetAppContainer(kAppContainerSid)); + + EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Event_Open f test")); + + runner.SetTestState(BEFORE_REVERT); + EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Event_Open f test")); + EXPECT_EQ(SBOX_ALL_OK, + runner.broker()->UninstallAppContainer(kAppContainerSid)); +} + +TEST(AppContainerTest, DenyOpenEvent) { + if (base::win::OSInfo::GetInstance()->version() < base::win::VERSION_WIN8) + return; + + TestRunner runner(JOB_UNPROTECTED, USER_UNPROTECTED, USER_UNPROTECTED); + + const wchar_t capability[] = L"S-1-15-3-12345678-87654321"; + base::win::ScopedHandle handle(CreateTaggedEvent(L"test", capability)); + ASSERT_TRUE(handle.IsValid()); + + EXPECT_EQ(SBOX_ALL_OK, + runner.broker()->InstallAppContainer(kAppContainerSid, + kAppContainerName)); + EXPECT_EQ(SBOX_ALL_OK, runner.GetPolicy()->SetAppContainer(kAppContainerSid)); + + EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Event_Open f test")); + + runner.SetTestState(BEFORE_REVERT); + EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Event_Open f test")); + EXPECT_EQ(SBOX_ALL_OK, + runner.broker()->UninstallAppContainer(kAppContainerSid)); +} + +TEST(AppContainerTest, NoImpersonation) { + if (base::win::OSInfo::GetInstance()->version() < base::win::VERSION_WIN8) + return; + + TestRunner runner(JOB_UNPROTECTED, USER_LIMITED, USER_LIMITED); + EXPECT_EQ(SBOX_ALL_OK, runner.GetPolicy()->SetAppContainer(kAppContainerSid)); +} + +TEST(AppContainerTest, WantsImpersonation) { + if (base::win::OSInfo::GetInstance()->version() < base::win::VERSION_WIN8) + return; + + TestRunner runner(JOB_UNPROTECTED, USER_UNPROTECTED, USER_NON_ADMIN); + EXPECT_EQ(SBOX_ERROR_CANNOT_INIT_APPCONTAINER, + runner.GetPolicy()->SetAppContainer(kAppContainerSid)); +} + +TEST(AppContainerTest, RequiresImpersonation) { + if (base::win::OSInfo::GetInstance()->version() < base::win::VERSION_WIN8) + return; + + TestRunner runner(JOB_UNPROTECTED, USER_RESTRICTED, USER_RESTRICTED); + EXPECT_EQ(SBOX_ERROR_CANNOT_INIT_APPCONTAINER, + runner.GetPolicy()->SetAppContainer(kAppContainerSid)); +} + +} // namespace sandbox diff --git a/sandbox/win/src/app_container_unittest.cc b/sandbox/win/src/app_container_unittest.cc new file mode 100644 index 0000000..936a9cb --- /dev/null +++ b/sandbox/win/src/app_container_unittest.cc @@ -0,0 +1,58 @@ +// 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/win/windows_version.h" +#include "sandbox/win/src/app_container.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace sandbox { + +// Tests the low level AppContainer interface. +TEST(AppContainerTest, CreateAppContainer) { + if (base::win::OSInfo::GetInstance()->version() < base::win::VERSION_WIN8) + return; + + const wchar_t kName[] = L"Test"; + const wchar_t kValidSid[] = L"S-1-15-2-12345-234-567-890-123-456-789"; + + EXPECT_TRUE(LookupAppContainer(kValidSid).empty()); + EXPECT_EQ(SBOX_ERROR_GENERIC, DeleteAppContainer(kValidSid)); + + EXPECT_EQ(SBOX_ALL_OK, CreateAppContainer(kValidSid, kName)); + EXPECT_EQ(SBOX_ERROR_GENERIC, CreateAppContainer(kValidSid, kName)); + EXPECT_EQ(kName, LookupAppContainer(kValidSid)); + EXPECT_EQ(SBOX_ALL_OK, DeleteAppContainer(kValidSid)); + + EXPECT_TRUE(LookupAppContainer(kValidSid).empty()); + EXPECT_EQ(SBOX_ERROR_GENERIC, DeleteAppContainer(kValidSid)); + + EXPECT_EQ(SBOX_ERROR_INVALID_APP_CONTAINER, + CreateAppContainer(L"Foo", kName)); +} + +// Tests handling of security capabilities on the attribute list. +TEST(AppContainerTest, SecurityCapabilities) { + if (base::win::OSInfo::GetInstance()->version() < base::win::VERSION_WIN8) + return; + + scoped_ptr<AppContainerAttributes> attributes(new AppContainerAttributes); + std::vector<string16> capabilities; + EXPECT_EQ(SBOX_ERROR_INVALID_APP_CONTAINER, + attributes->SetAppContainer(L"S-1-foo", capabilities)); + + EXPECT_EQ(SBOX_ALL_OK, + attributes->SetAppContainer(L"S-1-15-2-12345-234", capabilities)); + EXPECT_TRUE(attributes->HasAppContainer()); + + attributes.reset(new AppContainerAttributes); + capabilities.push_back(L"S-1-15-3-12345678-87654321"); + capabilities.push_back(L"S-1-15-3-1"); + capabilities.push_back(L"S-1-15-3-2"); + capabilities.push_back(L"S-1-15-3-3"); + EXPECT_EQ(SBOX_ALL_OK, + attributes->SetAppContainer(L"S-1-15-2-1-2", capabilities)); + EXPECT_TRUE(attributes->HasAppContainer()); +} + +} // namespace sandbox diff --git a/sandbox/win/src/broker_services.cc b/sandbox/win/src/broker_services.cc index 6cfd5b6..497f2f8 100644 --- a/sandbox/win/src/broker_services.cc +++ b/sandbox/win/src/broker_services.cc @@ -10,6 +10,8 @@ #include "base/win/scoped_handle.h" #include "base/win/scoped_process_information.h" #include "base/win/startup_information.h" +#include "base/win/windows_version.h" +#include "sandbox/win/src/app_container.h" #include "sandbox/win/src/sandbox_policy_base.h" #include "sandbox/win/src/sandbox.h" #include "sandbox/win/src/target_process.h" @@ -296,22 +298,19 @@ ResultCode BrokerServicesBase::SpawnTarget(const wchar_t* exe_path, // with the soon to be created target process. HANDLE initial_token_temp; HANDLE lockdown_token_temp; - DWORD win_result = policy_base->MakeTokens(&initial_token_temp, - &lockdown_token_temp); - if (ERROR_SUCCESS != win_result) - return SBOX_ERROR_GENERIC; + ResultCode result = policy_base->MakeTokens(&initial_token_temp, + &lockdown_token_temp); + if (SBOX_ALL_OK != result) + return result; base::win::ScopedHandle initial_token(initial_token_temp); base::win::ScopedHandle lockdown_token(lockdown_token_temp); HANDLE job_temp; - win_result = policy_base->MakeJobObject(&job_temp); + result = policy_base->MakeJobObject(&job_temp); base::win::ScopedHandle job(job_temp); - if (ERROR_SUCCESS != win_result) - return SBOX_ERROR_GENERIC; - - if (ERROR_ALREADY_EXISTS == ::GetLastError()) - return SBOX_ERROR_GENERIC; + if (SBOX_ALL_OK != result) + return result; // Initialize the startup information from the policy. base::win::StartupInformation startup_info; @@ -321,6 +320,14 @@ ResultCode BrokerServicesBase::SpawnTarget(const wchar_t* exe_path, const_cast<wchar_t*>(desktop.c_str()); } + const AppContainerAttributes* app_container = policy_base->GetAppContainer(); + if (app_container) { + startup_info.InitializeProcThreadAttributeList(1); + result = app_container->ShareForStartup(&startup_info); + if (SBOX_ALL_OK != result) + return result; + } + // Construct the thread pool here in case it is expensive. // The thread pool is shared by all the targets if (NULL == thread_pool_) @@ -334,8 +341,8 @@ ResultCode BrokerServicesBase::SpawnTarget(const wchar_t* exe_path, job, thread_pool_); - win_result = target->Create(exe_path, command_line, - startup_info, &process_info); + DWORD win_result = target->Create(exe_path, command_line, startup_info, + &process_info); if (ERROR_SUCCESS != win_result) return SpawnCleanup(target, win_result); @@ -408,4 +415,30 @@ ResultCode BrokerServicesBase::AddTargetPeer(HANDLE peer_process) { return SBOX_ALL_OK; } +ResultCode BrokerServicesBase::InstallAppContainer(const wchar_t* sid, + const wchar_t* name) { + if (base::win::OSInfo::GetInstance()->version() < base::win::VERSION_WIN8) + return SBOX_ERROR_UNSUPPORTED; + + string16 old_name = LookupAppContainer(sid); + if (old_name.empty()) + return CreateAppContainer(sid, name); + + if (old_name != name) + return SBOX_ERROR_INVALID_APP_CONTAINER; + + return SBOX_ALL_OK; +} + +ResultCode BrokerServicesBase::UninstallAppContainer(const wchar_t* sid) { + if (base::win::OSInfo::GetInstance()->version() < base::win::VERSION_WIN8) + return SBOX_ERROR_UNSUPPORTED; + + string16 name = LookupAppContainer(sid); + if (name.empty()) + return SBOX_ERROR_INVALID_APP_CONTAINER; + + return DeleteAppContainer(sid); +} + } // namespace sandbox diff --git a/sandbox/win/src/broker_services.h b/sandbox/win/src/broker_services.h index 0455dca..1f2e3fa 100644 --- a/sandbox/win/src/broker_services.h +++ b/sandbox/win/src/broker_services.h @@ -2,13 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef SANDBOX_SRC_BROKER_SERVICES_H__ -#define SANDBOX_SRC_BROKER_SERVICES_H__ +#ifndef SANDBOX_WIN_SRC_BROKER_SERVICES_H_ +#define SANDBOX_WIN_SRC_BROKER_SERVICES_H_ #include <list> #include <map> #include <set> #include "base/basictypes.h" +#include "base/compiler_specific.h" #include "base/win/scoped_handle.h" #include "sandbox/win/src/crosscall_server.h" #include "sandbox/win/src/job.h" @@ -42,19 +43,18 @@ class BrokerServicesBase : public BrokerServices, ~BrokerServicesBase(); - // The next five methods are the BrokerServices interface - virtual ResultCode Init(); - - virtual TargetPolicy* CreatePolicy(); - + // BrokerServices interface. + virtual ResultCode Init() OVERRIDE; + virtual TargetPolicy* CreatePolicy() OVERRIDE; virtual ResultCode SpawnTarget(const wchar_t* exe_path, const wchar_t* command_line, TargetPolicy* policy, - PROCESS_INFORMATION* target); - - virtual ResultCode WaitForAllTargets(); - - virtual ResultCode AddTargetPeer(HANDLE peer_process); + PROCESS_INFORMATION* target) OVERRIDE; + virtual ResultCode WaitForAllTargets() OVERRIDE; + virtual ResultCode AddTargetPeer(HANDLE peer_process) OVERRIDE; + virtual ResultCode InstallAppContainer(const wchar_t* sid, + const wchar_t* name) OVERRIDE; + virtual ResultCode UninstallAppContainer(const wchar_t* sid) OVERRIDE; // Checks if the supplied process ID matches one of the broker's active // target processes @@ -110,4 +110,4 @@ class BrokerServicesBase : public BrokerServices, } // namespace sandbox -#endif // SANDBOX_SRC_BROKER_SERVICES_H__ +#endif // SANDBOX_WIN_SRC_BROKER_SERVICES_H_ diff --git a/sandbox/win/src/sandbox.h b/sandbox/win/src/sandbox.h index ee4b7b0..e326194 100644 --- a/sandbox/win/src/sandbox.h +++ b/sandbox/win/src/sandbox.h @@ -16,8 +16,8 @@ // there are cases where the Sandbox library is linked against the main .exe // while its API needs to be used in a DLL. -#ifndef SANDBOX_SRC_SANDBOX_H__ -#define SANDBOX_SRC_SANDBOX_H__ +#ifndef SANDBOX_WIN_SRC_SANDBOX_H_ +#define SANDBOX_WIN_SRC_SANDBOX_H_ #include <windows.h> @@ -92,6 +92,15 @@ class BrokerServices { // If the return is ERROR_GENERIC, you can call ::GetLastError() to get // more information. virtual ResultCode AddTargetPeer(HANDLE peer_process) = 0; + + // Install the AppContainer with the specified sid an name. Returns ALL_OK if + // successful or an error code if the AppContainer cannot be installed. + virtual ResultCode InstallAppContainer(const wchar_t* sid, + const wchar_t* name) = 0; + + // Removes from the system the AppContainer with the specified sid. + // Returns ALL_OK if successful or an error code otherwise. + virtual ResultCode UninstallAppContainer(const wchar_t* sid) = 0; }; // TargetServices models the current process from the perspective @@ -153,4 +162,4 @@ class TargetServices { } // namespace sandbox -#endif // SANDBOX_SRC_SANDBOX_H__ +#endif // SANDBOX_WIN_SRC_SANDBOX_H_ diff --git a/sandbox/win/src/sandbox_policy.h b/sandbox/win/src/sandbox_policy.h index 566351a4..ff487bcc 100644 --- a/sandbox/win/src/sandbox_policy.h +++ b/sandbox/win/src/sandbox_policy.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef SANDBOX_SRC_SANDBOX_POLICY_H_ -#define SANDBOX_SRC_SANDBOX_POLICY_H_ +#ifndef SANDBOX_WIN_SRC_SANDBOX_POLICY_H_ +#define SANDBOX_WIN_SRC_SANDBOX_POLICY_H_ #include <string> @@ -71,7 +71,8 @@ class TargetPolicy { // is used by the process from the creation of the process until the moment // the process calls TargetServices::LowerToken() or the process calls // win32's ReverToSelf(). Once this happens the initial token is no longer - // available and the lockdown token is in effect. + // available and the lockdown token is in effect. Using an initial token is + // not compatible with AppContainer, see SetAppContainer. // lockdown: the security level for the token that comes into force after the // process calls TargetServices::LowerToken() or the process calls // ReverToSelf(). See the explanation of each level in the TokenLevel @@ -137,20 +138,32 @@ class TargetPolicy { virtual void DestroyAlternateDesktop() = 0; // Sets the integrity level of the process in the sandbox. Both the initial - // token and the main token will be affected by this. This is valid only - // on Vista. It is silently ignored on other OSes. If you set the integrity - // level to a level higher than your current level, the sandbox will fail + // token and the main token will be affected by this. If the integrity level + // is set to a level higher than the current level, the sandbox will fail // to start. virtual ResultCode SetIntegrityLevel(IntegrityLevel level) = 0; // Sets the integrity level of the process in the sandbox. The integrity level // will not take effect before you call LowerToken. User Interface Privilege // Isolation is not affected by this setting and will remain off for the - // process in the sandbox. This flag is valid on Vista only, it is silently - // ignored on other OSes. If you set the integrity level to a level higher - // than your current level, the sandbox will fail to start. + // process in the sandbox. If the integrity level is set to a level higher + // than the current level, the sandbox will fail to start. virtual ResultCode SetDelayedIntegrityLevel(IntegrityLevel level) = 0; + // Sets the AppContainer to be used for the sandboxed process. Any capability + // to be enabled for the process should be added before this method is invoked + // (by calling SetCapability() as many times as needed). + // The desired AppContainer must be already installed on the system, otherwise + // launching the sandboxed process will fail. See BrokerServices for details + // about installing an AppContainer. + // Note that currently Windows restricts the use of impersonation within + // AppContainers, so this function is incompatible with the use of an initial + // token. + virtual ResultCode SetAppContainer(const wchar_t* sid) = 0; + + // Sets a capability to be enabled for the sandboxed process' AppContainer. + virtual ResultCode SetCapability(const wchar_t* sid) = 0; + // Sets the interceptions to operate in strict mode. By default, interceptions // are performed in "relaxed" mode, where if something inside NTDLL.DLL is // already patched we attempt to intercept it anyway. Setting interceptions @@ -187,4 +200,4 @@ class TargetPolicy { } // namespace sandbox -#endif // SANDBOX_SRC_SANDBOX_POLICY_H_ +#endif // SANDBOX_WIN_SRC_SANDBOX_POLICY_H_ diff --git a/sandbox/win/src/sandbox_policy_base.cc b/sandbox/win/src/sandbox_policy_base.cc index 63e77d5..3950a0c 100644 --- a/sandbox/win/src/sandbox_policy_base.cc +++ b/sandbox/win/src/sandbox_policy_base.cc @@ -7,6 +7,8 @@ #include "base/basictypes.h" #include "base/callback.h" #include "base/logging.h" +#include "base/win/windows_version.h" +#include "sandbox/win/src/app_container.h" #include "sandbox/win/src/filesystem_dispatcher.h" #include "sandbox/win/src/filesystem_policy.h" #include "sandbox/win/src/handle_dispatcher.h" @@ -151,21 +153,21 @@ ResultCode PolicyBase::SetAlternateDesktop(bool alternate_winstation) { return CreateAlternateDesktop(alternate_winstation); } -std::wstring PolicyBase::GetAlternateDesktop() const { +string16 PolicyBase::GetAlternateDesktop() const { // No alternate desktop or winstation. Return an empty string. if (!use_alternate_desktop_ && !use_alternate_winstation_) { - return std::wstring(); + return string16(); } // The desktop and winstation should have been created by now. // If we hit this scenario, it means that the user ignored the failure // during SetAlternateDesktop, so we ignore it here too. if (use_alternate_desktop_ && !alternate_desktop_handle_) { - return std::wstring(); + return string16(); } if (use_alternate_winstation_ && (!alternate_desktop_handle_ || !alternate_winstation_handle_)) { - return std::wstring(); + return string16(); } return GetFullDesktopName(alternate_winstation_handle_, @@ -249,6 +251,31 @@ ResultCode PolicyBase::SetDelayedIntegrityLevel( return SBOX_ALL_OK; } +ResultCode PolicyBase::SetAppContainer(const wchar_t* sid) { + if (base::win::OSInfo::GetInstance()->version() < base::win::VERSION_WIN8) + return SBOX_ALL_OK; + + // Windows refuses to work with an impersonation token for a process inside + // an AppContainer. If the caller wants to use a more privileged initial + // token, or if the lockdown level will prevent the process from starting, + // we have to fail the operation. + if (lockdown_level_ < USER_LIMITED || lockdown_level_ != initial_level_) + return SBOX_ERROR_CANNOT_INIT_APPCONTAINER; + + DCHECK(!appcontainer_list_.get()); + appcontainer_list_.reset(new AppContainerAttributes); + ResultCode rv = appcontainer_list_->SetAppContainer(sid, capabilities_); + if (rv != SBOX_ALL_OK) + return rv; + + return SBOX_ALL_OK; +} + +ResultCode PolicyBase::SetCapability(const wchar_t* sid) { + capabilities_.push_back(sid); + return SBOX_ALL_OK; +} + void PolicyBase::SetStrictInterceptions() { relaxed_interceptions_ = false; } @@ -325,7 +352,7 @@ ResultCode PolicyBase::AddRule(SubSystem subsystem, Semantics semantics, } ResultCode PolicyBase::AddDllToUnload(const wchar_t* dll_name) { - blacklisted_dlls_.push_back(std::wstring(dll_name)); + blacklisted_dlls_.push_back(dll_name); return SBOX_ALL_OK; } @@ -370,25 +397,36 @@ bool PolicyBase::SetupService(InterceptionManager* manager, int service) { return dispatch->SetupService(manager, service); } -DWORD PolicyBase::MakeJobObject(HANDLE* job) { +ResultCode PolicyBase::MakeJobObject(HANDLE* job) { // Create the windows job object. Job job_obj; DWORD result = job_obj.Init(job_level_, NULL, ui_exceptions_); if (ERROR_SUCCESS != result) { - return result; + return SBOX_ERROR_GENERIC; } *job = job_obj.Detach(); - return ERROR_SUCCESS; + return SBOX_ALL_OK; } -DWORD PolicyBase::MakeTokens(HANDLE* initial, HANDLE* lockdown) { +ResultCode PolicyBase::MakeTokens(HANDLE* initial, HANDLE* lockdown) { // Create the 'naked' token. This will be the permanent token associated // with the process and therefore with any thread that is not impersonating. DWORD result = CreateRestrictedToken(lockdown, lockdown_level_, integrity_level_, PRIMARY); if (ERROR_SUCCESS != result) { - return result; + return SBOX_ERROR_GENERIC; } + + if (appcontainer_list_.get() && appcontainer_list_->HasAppContainer()) { + // Windows refuses to work with an impersonation token. See SetAppContainer + // implementation for more details. + if (lockdown_level_ < USER_LIMITED || lockdown_level_ != initial_level_) + return SBOX_ERROR_CANNOT_INIT_APPCONTAINER; + + *initial = INVALID_HANDLE_VALUE; + return SBOX_ALL_OK; + } + // Create the 'better' token. We use this token as the one that the main // thread uses when booting up the process. It should contain most of // what we need (before reaching main( )) @@ -396,11 +434,18 @@ DWORD PolicyBase::MakeTokens(HANDLE* initial, HANDLE* lockdown) { integrity_level_, IMPERSONATION); if (ERROR_SUCCESS != result) { ::CloseHandle(*lockdown); - return result; + return SBOX_ERROR_GENERIC; } return SBOX_ALL_OK; } +const AppContainerAttributes* PolicyBase::GetAppContainer() { + if (!appcontainer_list_.get() || !appcontainer_list_->HasAppContainer()) + return NULL; + + return appcontainer_list_.get(); +} + bool PolicyBase::AddTarget(TargetProcess* target) { if (NULL != policy_) policy_maker_->Done(); @@ -516,7 +561,7 @@ bool PolicyBase::SetupAllInterceptions(TargetProcess* target) { } if (!blacklisted_dlls_.empty()) { - std::vector<std::wstring>::iterator it = blacklisted_dlls_.begin(); + std::vector<string16>::iterator it = blacklisted_dlls_.begin(); for (; it != blacklisted_dlls_.end(); ++it) { manager.AddToUnloadModules(it->c_str()); } diff --git a/sandbox/win/src/sandbox_policy_base.h b/sandbox/win/src/sandbox_policy_base.h index 8fdfe91..1334304 100644 --- a/sandbox/win/src/sandbox_policy_base.h +++ b/sandbox/win/src/sandbox_policy_base.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef SANDBOX_SRC_SANDBOX_POLICY_BASE_H_ -#define SANDBOX_SRC_SANDBOX_POLICY_BASE_H_ +#ifndef SANDBOX_WIN_SRC_SANDBOX_POLICY_BASE_H_ +#define SANDBOX_WIN_SRC_SANDBOX_POLICY_BASE_H_ #include <windows.h> @@ -23,6 +23,7 @@ namespace sandbox { +class AppContainerAttributes; class LowLevelPolicy; class TargetProcess; struct PolicyGlobal; @@ -43,12 +44,14 @@ class PolicyBase : public Dispatcher, public TargetPolicy { virtual ResultCode SetJobLevel(JobLevel job_level, uint32 ui_exceptions) OVERRIDE; virtual ResultCode SetAlternateDesktop(bool alternate_winstation) OVERRIDE; - virtual std::wstring GetAlternateDesktop() const OVERRIDE; + virtual string16 GetAlternateDesktop() const OVERRIDE; virtual ResultCode CreateAlternateDesktop(bool alternate_winstation) OVERRIDE; virtual void DestroyAlternateDesktop() OVERRIDE; virtual ResultCode SetIntegrityLevel(IntegrityLevel integrity_level) OVERRIDE; virtual ResultCode SetDelayedIntegrityLevel( IntegrityLevel integrity_level) OVERRIDE; + virtual ResultCode SetAppContainer(const wchar_t* sid) OVERRIDE; + virtual ResultCode SetCapability(const wchar_t* sid) OVERRIDE; virtual void SetStrictInterceptions() OVERRIDE; virtual ResultCode AddRule(SubSystem subsystem, Semantics semantics, const wchar_t* pattern) OVERRIDE; @@ -62,12 +65,14 @@ class PolicyBase : public Dispatcher, public TargetPolicy { virtual bool SetupService(InterceptionManager* manager, int service) OVERRIDE; // Creates a Job object with the level specified in a previous call to - // SetJobLevel(). Returns the standard windows of ::GetLastError(). - DWORD MakeJobObject(HANDLE* job); + // SetJobLevel(). + ResultCode MakeJobObject(HANDLE* job); // Creates the two tokens with the levels specified in a previous call to - // SetTokenLevel(). Returns the standard windows of ::GetLastError(). - DWORD MakeTokens(HANDLE* initial, HANDLE* lockdown); + // SetTokenLevel(). + ResultCode MakeTokens(HANDLE* initial, HANDLE* lockdown); + + const AppContainerAttributes* GetAppContainer(); // Adds a target process to the internal list of targets. Internally a // call to TargetProcess::Init() is issued. @@ -122,11 +127,13 @@ class PolicyBase : public Dispatcher, public TargetPolicy { // Memory structure that stores the low level policy. PolicyGlobal* policy_; // The list of dlls to unload in the target process. - std::vector<std::wstring> blacklisted_dlls_; + std::vector<string16> blacklisted_dlls_; // This is a map of handle-types to names that we need to close in the // target process. A null set means we need to close all handles of the // given type. HandleCloser handle_closer_; + std::vector<string16> capabilities_; + scoped_ptr<AppContainerAttributes> appcontainer_list_; static HDESK alternate_desktop_handle_; static HWINSTA alternate_winstation_handle_; @@ -136,4 +143,4 @@ class PolicyBase : public Dispatcher, public TargetPolicy { } // namespace sandbox -#endif // SANDBOX_SRC_SANDBOX_POLICY_BASE_H_ +#endif // SANDBOX_WIN_SRC_SANDBOX_POLICY_BASE_H_ diff --git a/sandbox/win/src/sandbox_types.h b/sandbox/win/src/sandbox_types.h index ce9b767..dcf2042 100644 --- a/sandbox/win/src/sandbox_types.h +++ b/sandbox/win/src/sandbox_types.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef SANDBOX_SRC_SANDBOX_TYPES_H_ -#define SANDBOX_SRC_SANDBOX_TYPES_H_ +#ifndef SANDBOX_WIN_SRC_SANDBOX_TYPES_H_ +#define SANDBOX_WIN_SRC_SANDBOX_TYPES_H_ namespace sandbox { @@ -37,6 +37,12 @@ enum ResultCode { SBOX_ERROR_CANNOT_CREATE_WINSTATION = 12, // Failed to switch back to the interactive window station. SBOX_ERROR_FAILED_TO_SWITCH_BACK_WINSTATION = 13, + // The supplied AppContainer is not valid. + SBOX_ERROR_INVALID_APP_CONTAINER = 14, + // The supplied capability is not valid. + SBOX_ERROR_INVALID_CAPABILITY = 15, + // There is a failure initializing the AppContainer. + SBOX_ERROR_CANNOT_INIT_APPCONTAINER = 16, // Placeholder for last item of the enum. SBOX_ERROR_LAST }; @@ -78,4 +84,4 @@ enum InterceptionType { } // namespace sandbox -#endif // SANDBOX_SRC_SANDBOX_TYPES_H_ +#endif // SANDBOX_WIN_SRC_SANDBOX_TYPES_H_ diff --git a/sandbox/win/src/sync_policy_test.cc b/sandbox/win/src/sync_policy_test.cc index 6490175..87d03f1 100644 --- a/sandbox/win/src/sync_policy_test.cc +++ b/sandbox/win/src/sync_policy_test.cc @@ -2,12 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "sandbox/win/src/sync_policy_test.h" + #include "base/win/scoped_handle.h" #include "sandbox/win/src/sandbox.h" #include "sandbox/win/src/sandbox_policy.h" #include "sandbox/win/src/sandbox_factory.h" #include "sandbox/win/src/nt_internals.h" -#include "sandbox/win/tests/common/controller.h" #include "testing/gtest/include/gtest/gtest.h" namespace sandbox { diff --git a/sandbox/win/src/sync_policy_test.h b/sandbox/win/src/sync_policy_test.h new file mode 100644 index 0000000..4f354b3 --- /dev/null +++ b/sandbox/win/src/sync_policy_test.h @@ -0,0 +1,18 @@ +// 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. + +#ifndef SANDBOX_WIN_SRC_SYNC_POLICY_TEST_H_ +#define SANDBOX_WIN_SRC_SYNC_POLICY_TEST_H_ + +#include "sandbox/win/tests/common/controller.h" + +namespace sandbox { + +// Opens the named event received on argv[1]. The requested access is +// EVENT_ALL_ACCESS if argv[0] starts with 'f', or SYNCHRONIZE otherwise. +SBOX_TESTS_COMMAND int Event_Open(int argc, wchar_t **argv); + +} // namespace sandbox + +#endif // SANDBOX_WIN_SRC_SYNC_POLICY_TEST_H_ diff --git a/sandbox/win/src/target_process.cc b/sandbox/win/src/target_process.cc index 7d75fd6..164b2a9 100644 --- a/sandbox/win/src/target_process.cc +++ b/sandbox/win/src/target_process.cc @@ -172,19 +172,19 @@ DWORD TargetProcess::Create(const wchar_t* exe_path, DWORD win_result = ERROR_SUCCESS; - // Assign the suspended target to the windows job object + // Assign the suspended target to the windows job object. if (!::AssignProcessToJobObject(job_, process_info.process_handle())) { win_result = ::GetLastError(); // It might be a security breach if we let the target run outside the job - // so kill it before it causes damage + // so kill it before it causes damage. ::TerminateProcess(process_info.process_handle(), 0); return win_result; } - // Change the token of the main thread of the new process for the - // impersonation token with more rights. This allows the target to start; - // otherwise it will crash too early for us to help. - { + if (initial_token_.IsValid()) { + // Change the token of the main thread of the new process for the + // impersonation token with more rights. This allows the target to start; + // otherwise it will crash too early for us to help. HANDLE temp_thread = process_info.thread_handle(); if (!::SetThreadToken(&temp_thread, initial_token_)) { win_result = ::GetLastError(); diff --git a/sandbox/win/src/target_process.h b/sandbox/win/src/target_process.h index cffdf9c..be4cd2a 100644 --- a/sandbox/win/src/target_process.h +++ b/sandbox/win/src/target_process.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef SANDBOX_SRC_TARGET_PROCESS_H__ -#define SANDBOX_SRC_TARGET_PROCESS_H__ +#ifndef SANDBOX_WIN_SRC_TARGET_PROCESS_H_ +#define SANDBOX_WIN_SRC_TARGET_PROCESS_H_ #include <windows.h> @@ -24,6 +24,7 @@ class StartupInformation; namespace sandbox { +class AttributeList; class SharedMemIPCServer; class ThreadProvider; @@ -127,4 +128,4 @@ TargetProcess* MakeTestTargetProcess(HANDLE process, HMODULE base_address); } // namespace sandbox -#endif // SANDBOX_SRC_TARGET_PROCESS_H__ +#endif // SANDBOX_WIN_SRC_TARGET_PROCESS_H_ diff --git a/sandbox/win/tests/common/controller.h b/sandbox/win/tests/common/controller.h index b8be2a2..fd7a833 100644 --- a/sandbox/win/tests/common/controller.h +++ b/sandbox/win/tests/common/controller.h @@ -107,10 +107,12 @@ class TestRunner { // the policy manually. TargetPolicy* GetPolicy(); - // Return the process handle for an asynchronous test. + BrokerServices* broker() { return broker_; } + + // Returns the process handle for an asynchronous test. HANDLE process() { return target_process_; } - // Return the process ID for an asynchronous test. + // Returns the process ID for an asynchronous test. DWORD process_id() { return target_process_id_; } private: |