diff options
Diffstat (limited to 'sandbox')
-rw-r--r-- | sandbox/src/restricted_token_utils.cc | 17 | ||||
-rw-r--r-- | sandbox/src/security_level.h | 1 | ||||
-rw-r--r-- | sandbox/tests/validation_tests/commands.cc | 22 | ||||
-rw-r--r-- | sandbox/tests/validation_tests/commands.h | 4 | ||||
-rw-r--r-- | sandbox/tests/validation_tests/suite.cc | 93 |
5 files changed, 112 insertions, 25 deletions
diff --git a/sandbox/src/restricted_token_utils.cc b/sandbox/src/restricted_token_utils.cc index d327c5f..8565f0a 100644 --- a/sandbox/src/restricted_token_utils.cc +++ b/sandbox/src/restricted_token_utils.cc @@ -278,6 +278,8 @@ const wchar_t* GetIntegrityLevelString(IntegrityLevel integrity_level) { return L"S-1-16-4096"; case INTEGRITY_LEVEL_BELOW_LOW: return L"S-1-16-2048"; + case INTEGRITY_LEVEL_UNTRUSTED: + return L"S-1-16-0"; case INTEGRITY_LEVEL_LAST: return NULL; } @@ -315,22 +317,13 @@ DWORD SetProcessIntegrityLevel(IntegrityLevel integrity_level) { if (base::win::GetVersion() < base::win::VERSION_VISTA) return ERROR_SUCCESS; - const wchar_t* integrity_level_str = GetIntegrityLevelString(integrity_level); - if (!integrity_level_str) { + // We don't check for an invalid level here because we'll just let it + // fail on the SetTokenIntegrityLevel call later on. + if (integrity_level == INTEGRITY_LEVEL_LAST) { // No mandatory level specified, we don't change it. return ERROR_SUCCESS; } - // Before we can change the token, we need to change the security label on the - // process so it is still possible to open the process with the new token. - std::wstring ace_access = SDDL_NO_READ_UP; - ace_access += SDDL_NO_WRITE_UP; - DWORD error = SetObjectIntegrityLabel(::GetCurrentProcess(), SE_KERNEL_OBJECT, - ace_access.c_str(), - integrity_level_str); - if (ERROR_SUCCESS != error) - return error; - HANDLE token_handle; if (!::OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_DEFAULT, &token_handle)) diff --git a/sandbox/src/security_level.h b/sandbox/src/security_level.h index d83514a..467f96f 100644 --- a/sandbox/src/security_level.h +++ b/sandbox/src/security_level.h @@ -17,6 +17,7 @@ enum IntegrityLevel { INTEGRITY_LEVEL_MEDIUM_LOW, INTEGRITY_LEVEL_LOW, INTEGRITY_LEVEL_BELOW_LOW, + INTEGRITY_LEVEL_UNTRUSTED, INTEGRITY_LEVEL_LAST }; diff --git a/sandbox/tests/validation_tests/commands.cc b/sandbox/tests/validation_tests/commands.cc index 4d9eba4..d99451f 100644 --- a/sandbox/tests/validation_tests/commands.cc +++ b/sandbox/tests/validation_tests/commands.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. +// 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. @@ -88,15 +88,16 @@ int TestValidWindow(HWND window) { } SBOX_TESTS_COMMAND int OpenProcessCmd(int argc, wchar_t **argv) { - if (1 != argc) + if (2 != argc) return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; - DWORD process_id = _wtoi(argv[0]); - return TestOpenProcess(process_id); + DWORD process_id = _wtol(argv[0]); + DWORD access_mask = _wtol(argv[1]); + return TestOpenProcess(process_id, access_mask); } -int TestOpenProcess(DWORD process_id) { - HANDLE process = ::OpenProcess(PROCESS_VM_READ, +int TestOpenProcess(DWORD process_id, DWORD access_mask) { + HANDLE process = ::OpenProcess(access_mask, FALSE, // Do not inherit handle. process_id); if (NULL == process) { @@ -249,4 +250,13 @@ int TestSwitchDesktop() { return SBOX_TEST_DENIED; } +SBOX_TESTS_COMMAND int SleepCmd(int argc, wchar_t **argv) { + if (1 != argc) + return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; + + ::Sleep(_wtoi(argv[0])); + return SBOX_TEST_SUCCEEDED; +} + + } // namespace sandbox diff --git a/sandbox/tests/validation_tests/commands.h b/sandbox/tests/validation_tests/commands.h index 47f7c26..9b797a5 100644 --- a/sandbox/tests/validation_tests/commands.h +++ b/sandbox/tests/validation_tests/commands.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// 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. @@ -11,7 +11,7 @@ namespace sandbox { int TestValidWindow(HWND window); // Tries to open the process_id. Returns a SboxTestResult. -int TestOpenProcess(DWORD process_id); +int TestOpenProcess(DWORD process_id, DWORD access_mask); // Tries to open thread_id. Returns a SboxTestResult. int TestOpenThread(DWORD thread_id); diff --git a/sandbox/tests/validation_tests/suite.cc b/sandbox/tests/validation_tests/suite.cc index a5886cd..3147f70 100644 --- a/sandbox/tests/validation_tests/suite.cc +++ b/sandbox/tests/validation_tests/suite.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. +// 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. @@ -8,11 +8,43 @@ #include <shlwapi.h> +#include "base/win/windows_version.h" #include "testing/gtest/include/gtest/gtest.h" #include "sandbox/tests/common/controller.h" #pragma comment(lib, "shlwapi.lib") +namespace { + +void TestProcessAccess(sandbox::TestRunner* runner, DWORD target) { + const wchar_t *kCommandTemplate = L"OpenProcessCmd %d %d"; + wchar_t command[1024] = {0}; + + // Test all the scary process permissions. + wsprintf(command, kCommandTemplate, target, PROCESS_CREATE_THREAD); + EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command)); + wsprintf(command, kCommandTemplate, target, PROCESS_DUP_HANDLE); + EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command)); + wsprintf(command, kCommandTemplate, target, PROCESS_SET_INFORMATION); + EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command)); + wsprintf(command, kCommandTemplate, target, PROCESS_VM_OPERATION); + EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command)); + wsprintf(command, kCommandTemplate, target, PROCESS_VM_READ); + EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command)); + wsprintf(command, kCommandTemplate, target, PROCESS_VM_WRITE); + EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command)); + wsprintf(command, kCommandTemplate, target, PROCESS_QUERY_INFORMATION); + EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command)); + wsprintf(command, kCommandTemplate, target, WRITE_DAC); + EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command)); + wsprintf(command, kCommandTemplate, target, WRITE_OWNER); + EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command)); + wsprintf(command, kCommandTemplate, target, READ_CONTROL); + EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command)); +} + +} // namespace + namespace sandbox { // Returns true if the volume that contains any_path supports ACL security. The @@ -96,13 +128,64 @@ TEST(ValidationSuite, TestWindows) { EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(command)); } -// Tests if the processes are correctly protected by the sandbox. -TEST(ValidationSuite, TestProcess) { +// Tests that a locked-down process cannot open another locked-down process. +TEST(ValidationSuite, TestProcessDenyLockdown) { TestRunner runner; + TestRunner target; wchar_t command[1024] = {0}; - wsprintf(command, L"OpenProcessCmd %d", ::GetCurrentProcessId()); - EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(command)); + target.SetAsynchronous(true); + + EXPECT_EQ(SBOX_TEST_SUCCEEDED, target.RunTest(L"SleepCmd 30000")); + + TestProcessAccess(&runner, target.process_id()); +} + +// Tests that a low-integrity process cannot open a locked-down process (due +// to the integrity label changing after startup via SetDelayedIntegrityLevel). +TEST(ValidationSuite, TestProcessDenyLowIntegrity) { + // This test applies only to Vista and above. + if (base::win::Version() < base::win::VERSION_VISTA) + return; + + TestRunner runner; + TestRunner target; + wchar_t command[1024] = {0}; + + target.SetAsynchronous(true); + target.GetPolicy()->SetDelayedIntegrityLevel(INTEGRITY_LEVEL_LOW); + + runner.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW); + runner.GetPolicy()->SetTokenLevel(USER_RESTRICTED_SAME_ACCESS, + USER_INTERACTIVE); + + EXPECT_EQ(SBOX_TEST_SUCCEEDED, target.RunTest(L"SleepCmd 30000")); + + TestProcessAccess(&runner, target.process_id()); +} + +// Tests that a locked-down process cannot open a low-integrity process. +TEST(ValidationSuite, TestProcessDenyBelowLowIntegrity) { + // This test applies only to Vista and above. + if (base::win::Version() < base::win::VERSION_VISTA) + return; + + TestRunner runner; + TestRunner target; + wchar_t command[1024] = {0}; + + target.SetAsynchronous(true); + target.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW); + target.GetPolicy()->SetTokenLevel(USER_RESTRICTED_SAME_ACCESS, + USER_INTERACTIVE); + + runner.GetPolicy()->SetDelayedIntegrityLevel(INTEGRITY_LEVEL_UNTRUSTED); + runner.GetPolicy()->SetTokenLevel(USER_RESTRICTED_SAME_ACCESS, + USER_INTERACTIVE); + + EXPECT_EQ(SBOX_TEST_SUCCEEDED, target.RunTest(L"SleepCmd 30000")); + + TestProcessAccess(&runner, target.process_id()); } // Tests if the threads are correctly protected by the sandbox. |