| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 // This file contains the validation tests for the sandbox. | |
| 6 // It includes the tests that need to be performed inside the | |
| 7 // sandbox. | |
| 8 | |
| 9 #include <shlwapi.h> | |
| 10 #include <stddef.h> | |
| 11 | |
| 12 #include "base/win/windows_version.h" | |
| 13 #include "sandbox/win/tests/common/controller.h" | |
| 14 #include "testing/gtest/include/gtest/gtest.h" | |
| 15 | |
| 16 #pragma comment(lib, "shlwapi.lib") | |
| 17 | |
| 18 namespace { | |
| 19 | |
| 20 void TestProcessAccess(sandbox::TestRunner* runner, DWORD target) { | |
| 21 const wchar_t *kCommandTemplate = L"OpenProcessCmd %d %d"; | |
| 22 wchar_t command[1024] = {0}; | |
| 23 | |
| 24 // Test all the scary process permissions. | |
| 25 wsprintf(command, kCommandTemplate, target, PROCESS_CREATE_THREAD); | |
| 26 EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command)); | |
| 27 wsprintf(command, kCommandTemplate, target, PROCESS_DUP_HANDLE); | |
| 28 EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command)); | |
| 29 wsprintf(command, kCommandTemplate, target, PROCESS_SET_INFORMATION); | |
| 30 EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command)); | |
| 31 wsprintf(command, kCommandTemplate, target, PROCESS_VM_OPERATION); | |
| 32 EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command)); | |
| 33 wsprintf(command, kCommandTemplate, target, PROCESS_VM_READ); | |
| 34 EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command)); | |
| 35 wsprintf(command, kCommandTemplate, target, PROCESS_VM_WRITE); | |
| 36 EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command)); | |
| 37 wsprintf(command, kCommandTemplate, target, PROCESS_QUERY_INFORMATION); | |
| 38 EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command)); | |
| 39 wsprintf(command, kCommandTemplate, target, WRITE_DAC); | |
| 40 EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command)); | |
| 41 wsprintf(command, kCommandTemplate, target, WRITE_OWNER); | |
| 42 EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command)); | |
| 43 wsprintf(command, kCommandTemplate, target, READ_CONTROL); | |
| 44 EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command)); | |
| 45 } | |
| 46 | |
| 47 } // namespace | |
| 48 | |
| 49 namespace sandbox { | |
| 50 | |
| 51 // Returns true if the volume that contains any_path supports ACL security. The | |
| 52 // input path can contain unexpanded environment strings. Returns false on any | |
| 53 // failure or if the file system does not support file security (such as FAT). | |
| 54 bool VolumeSupportsACLs(const wchar_t* any_path) { | |
| 55 wchar_t expand[MAX_PATH +1]; | |
| 56 DWORD len =::ExpandEnvironmentStringsW(any_path, expand, _countof(expand)); | |
| 57 if (0 == len) return false; | |
| 58 if (len > _countof(expand)) return false; | |
| 59 if (!::PathStripToRootW(expand)) return false; | |
| 60 DWORD fs_flags = 0; | |
| 61 if (!::GetVolumeInformationW(expand, NULL, 0, 0, NULL, &fs_flags, NULL, 0)) | |
| 62 return false; | |
| 63 if (fs_flags & FILE_PERSISTENT_ACLS) return true; | |
| 64 return false; | |
| 65 } | |
| 66 | |
| 67 // Tests if the suite is working properly. | |
| 68 TEST(ValidationSuite, TestSuite) { | |
| 69 TestRunner runner; | |
| 70 ASSERT_EQ(SBOX_TEST_PING_OK, runner.RunTest(L"ping")); | |
| 71 } | |
| 72 | |
| 73 // Tests if the file system is correctly protected by the sandbox. | |
| 74 TEST(ValidationSuite, TestFileSystem) { | |
| 75 // Do not perform the test if the system is using FAT or any other | |
| 76 // file system that does not have file security. | |
| 77 ASSERT_TRUE(VolumeSupportsACLs(L"%SystemDrive%\\")); | |
| 78 ASSERT_TRUE(VolumeSupportsACLs(L"%SystemRoot%\\")); | |
| 79 ASSERT_TRUE(VolumeSupportsACLs(L"%ProgramFiles%\\")); | |
| 80 ASSERT_TRUE(VolumeSupportsACLs(L"%Temp%\\")); | |
| 81 ASSERT_TRUE(VolumeSupportsACLs(L"%AppData%\\")); | |
| 82 | |
| 83 TestRunner runner; | |
| 84 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenFileCmd %SystemDrive%")); | |
| 85 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenFileCmd %SystemRoot%")); | |
| 86 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenFileCmd %ProgramFiles%")); | |
| 87 EXPECT_EQ(SBOX_TEST_DENIED, | |
| 88 runner.RunTest(L"OpenFileCmd %SystemRoot%\\System32")); | |
| 89 EXPECT_EQ(SBOX_TEST_DENIED, | |
| 90 runner.RunTest(L"OpenFileCmd %SystemRoot%\\explorer.exe")); | |
| 91 EXPECT_EQ(SBOX_TEST_DENIED, | |
| 92 runner.RunTest(L"OpenFileCmd %SystemRoot%\\Cursors\\arrow_i.cur")); | |
| 93 EXPECT_EQ(SBOX_TEST_DENIED, | |
| 94 runner.RunTest(L"OpenFileCmd %AllUsersProfile%")); | |
| 95 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenFileCmd %Temp%")); | |
| 96 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenFileCmd %AppData%")); | |
| 97 } | |
| 98 | |
| 99 // Tests if the registry is correctly protected by the sandbox. | |
| 100 TEST(ValidationSuite, TestRegistry) { | |
| 101 TestRunner runner; | |
| 102 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenKey HKLM")); | |
| 103 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenKey HKCU")); | |
| 104 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenKey HKU")); | |
| 105 EXPECT_EQ(SBOX_TEST_DENIED, | |
| 106 runner.RunTest( | |
| 107 L"OpenKey HKLM " | |
| 108 L"\"Software\\Microsoft\\Windows NT\\CurrentVersion\\WinLogon\"")); | |
| 109 } | |
| 110 | |
| 111 // Tests that the permissions on the Windowstation does not allow the sandbox | |
| 112 // to get to the interactive desktop or to make the sbox desktop interactive. | |
| 113 TEST(ValidationSuite, TestDesktop) { | |
| 114 TestRunner runner; | |
| 115 runner.GetPolicy()->SetAlternateDesktop(true); | |
| 116 runner.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW); | |
| 117 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenInteractiveDesktop NULL")); | |
| 118 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"SwitchToSboxDesktop NULL")); | |
| 119 } | |
| 120 | |
| 121 // Tests that the permissions on the Windowstation does not allow the sandbox | |
| 122 // to get to the interactive desktop or to make the sbox desktop interactive. | |
| 123 TEST(ValidationSuite, TestAlternateDesktop) { | |
| 124 | |
| 125 TestRunner runner; | |
| 126 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"EnumAlternateWinsta NULL")); | |
| 127 | |
| 128 wchar_t command[1024] = {0}; | |
| 129 runner.SetTimeout(3600000); | |
| 130 runner.GetPolicy()->SetAlternateDesktop(true); | |
| 131 runner.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW); | |
| 132 base::string16 desktop_name = runner.GetPolicy()->GetAlternateDesktop(); | |
| 133 desktop_name = desktop_name.substr(desktop_name.find('\\') + 1); | |
| 134 wsprintf(command, L"OpenAlternateDesktop %lS", desktop_name.c_str()); | |
| 135 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(command)); | |
| 136 } | |
| 137 | |
| 138 // Tests if the windows are correctly protected by the sandbox. | |
| 139 TEST(ValidationSuite, TestWindows) { | |
| 140 TestRunner runner; | |
| 141 wchar_t command[1024] = {0}; | |
| 142 | |
| 143 wsprintf(command, L"ValidWindow %Id", | |
| 144 reinterpret_cast<size_t>(::GetDesktopWindow())); | |
| 145 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(command)); | |
| 146 | |
| 147 wsprintf(command, L"ValidWindow %Id", | |
| 148 reinterpret_cast<size_t>(::FindWindow(NULL, NULL))); | |
| 149 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(command)); | |
| 150 } | |
| 151 | |
| 152 // Tests that a locked-down process cannot open another locked-down process. | |
| 153 TEST(ValidationSuite, TestProcessDenyLockdown) { | |
| 154 TestRunner runner; | |
| 155 TestRunner target; | |
| 156 | |
| 157 target.SetAsynchronous(true); | |
| 158 | |
| 159 EXPECT_EQ(SBOX_TEST_SUCCEEDED, target.RunTest(L"SleepCmd 30000")); | |
| 160 | |
| 161 TestProcessAccess(&runner, target.process_id()); | |
| 162 } | |
| 163 | |
| 164 // Tests that a low-integrity process cannot open a locked-down process (due | |
| 165 // to the integrity label changing after startup via SetDelayedIntegrityLevel). | |
| 166 TEST(ValidationSuite, TestProcessDenyLowIntegrity) { | |
| 167 | |
| 168 TestRunner runner; | |
| 169 TestRunner target; | |
| 170 | |
| 171 target.SetAsynchronous(true); | |
| 172 target.GetPolicy()->SetDelayedIntegrityLevel(INTEGRITY_LEVEL_LOW); | |
| 173 | |
| 174 runner.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW); | |
| 175 runner.GetPolicy()->SetTokenLevel(USER_RESTRICTED_SAME_ACCESS, | |
| 176 USER_INTERACTIVE); | |
| 177 | |
| 178 EXPECT_EQ(SBOX_TEST_SUCCEEDED, target.RunTest(L"SleepCmd 30000")); | |
| 179 | |
| 180 TestProcessAccess(&runner, target.process_id()); | |
| 181 } | |
| 182 | |
| 183 // Tests that a locked-down process cannot open a low-integrity process. | |
| 184 TEST(ValidationSuite, TestProcessDenyBelowLowIntegrity) { | |
| 185 | |
| 186 TestRunner runner; | |
| 187 TestRunner target; | |
| 188 | |
| 189 target.SetAsynchronous(true); | |
| 190 target.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW); | |
| 191 target.GetPolicy()->SetTokenLevel(USER_RESTRICTED_SAME_ACCESS, | |
| 192 USER_INTERACTIVE); | |
| 193 | |
| 194 runner.GetPolicy()->SetDelayedIntegrityLevel(INTEGRITY_LEVEL_UNTRUSTED); | |
| 195 runner.GetPolicy()->SetTokenLevel(USER_RESTRICTED_SAME_ACCESS, | |
| 196 USER_INTERACTIVE); | |
| 197 | |
| 198 EXPECT_EQ(SBOX_TEST_SUCCEEDED, target.RunTest(L"SleepCmd 30000")); | |
| 199 | |
| 200 TestProcessAccess(&runner, target.process_id()); | |
| 201 } | |
| 202 | |
| 203 // Tests if the threads are correctly protected by the sandbox. | |
| 204 TEST(ValidationSuite, TestThread) { | |
| 205 TestRunner runner; | |
| 206 wchar_t command[1024] = {0}; | |
| 207 | |
| 208 wsprintf(command, L"OpenThreadCmd %d", ::GetCurrentThreadId()); | |
| 209 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(command)); | |
| 210 } | |
| 211 | |
| 212 // Tests if an over-limit allocation will be denied. | |
| 213 TEST(ValidationSuite, TestMemoryLimit) { | |
| 214 TestRunner runner; | |
| 215 wchar_t command[1024] = {0}; | |
| 216 const int kAllocationSize = 256 * 1024 * 1024; | |
| 217 | |
| 218 wsprintf(command, L"AllocateCmd %d", kAllocationSize); | |
| 219 runner.GetPolicy()->SetJobMemoryLimit(kAllocationSize); | |
| 220 EXPECT_EQ(SBOX_FATAL_MEMORY_EXCEEDED, runner.RunTest(command)); | |
| 221 } | |
| 222 | |
| 223 // Tests a large allocation will succeed absent limits. | |
| 224 TEST(ValidationSuite, TestMemoryNoLimit) { | |
| 225 TestRunner runner; | |
| 226 wchar_t command[1024] = {0}; | |
| 227 const int kAllocationSize = 256 * 1024 * 1024; | |
| 228 | |
| 229 wsprintf(command, L"AllocateCmd %d", kAllocationSize); | |
| 230 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(command)); | |
| 231 } | |
| 232 | |
| 233 } // namespace sandbox | |
| OLD | NEW |