summaryrefslogtreecommitdiffstats
path: root/sandbox/win
diff options
context:
space:
mode:
authorrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-05 18:14:22 +0000
committerrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-05 18:14:22 +0000
commitef159f884e077a13cd142bccd9b8ae7bf1ad49cd (patch)
tree3c4f8887c1bb6aab3a90f34637dfc58c92b3c358 /sandbox/win
parent762c75eda5f802b528fbb0da09d1ee053e07409d (diff)
downloadchromium_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.gypi21
-rw-r--r--sandbox/win/src/app_container.cc174
-rw-r--r--sandbox/win/src/app_container.h68
-rw-r--r--sandbox/win/src/app_container_test.cc143
-rw-r--r--sandbox/win/src/app_container_unittest.cc58
-rw-r--r--sandbox/win/src/broker_services.cc57
-rw-r--r--sandbox/win/src/broker_services.h26
-rw-r--r--sandbox/win/src/sandbox.h15
-rw-r--r--sandbox/win/src/sandbox_policy.h33
-rw-r--r--sandbox/win/src/sandbox_policy_base.cc69
-rw-r--r--sandbox/win/src/sandbox_policy_base.h25
-rw-r--r--sandbox/win/src/sandbox_types.h12
-rw-r--r--sandbox/win/src/sync_policy_test.cc3
-rw-r--r--sandbox/win/src/sync_policy_test.h18
-rw-r--r--sandbox/win/src/target_process.cc12
-rw-r--r--sandbox/win/src/target_process.h7
-rw-r--r--sandbox/win/tests/common/controller.h6
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: