summaryrefslogtreecommitdiffstats
path: root/sandbox
diff options
context:
space:
mode:
Diffstat (limited to 'sandbox')
-rw-r--r--sandbox/src/restricted_token_utils.cc17
-rw-r--r--sandbox/src/security_level.h1
-rw-r--r--sandbox/tests/validation_tests/commands.cc22
-rw-r--r--sandbox/tests/validation_tests/commands.h4
-rw-r--r--sandbox/tests/validation_tests/suite.cc93
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.