| 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 | |
| 11 #include "base/win/windows_version.h" | |
| 12 #include "testing/gtest/include/gtest/gtest.h" | |
| 13 #include "sandbox/tests/common/controller.h" | |
| 14 | |
| 15 #pragma comment(lib, "shlwapi.lib") | |
| 16 | |
| 17 namespace { | |
| 18 | |
| 19 void TestProcessAccess(sandbox::TestRunner* runner, DWORD target) { | |
| 20 const wchar_t *kCommandTemplate = L"OpenProcessCmd %d %d"; | |
| 21 wchar_t command[1024] = {0}; | |
| 22 | |
| 23 // Test all the scary process permissions. | |
| 24 wsprintf(command, kCommandTemplate, target, PROCESS_CREATE_THREAD); | |
| 25 EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command)); | |
| 26 wsprintf(command, kCommandTemplate, target, PROCESS_DUP_HANDLE); | |
| 27 EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command)); | |
| 28 wsprintf(command, kCommandTemplate, target, PROCESS_SET_INFORMATION); | |
| 29 EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command)); | |
| 30 wsprintf(command, kCommandTemplate, target, PROCESS_VM_OPERATION); | |
| 31 EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command)); | |
| 32 wsprintf(command, kCommandTemplate, target, PROCESS_VM_READ); | |
| 33 EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command)); | |
| 34 wsprintf(command, kCommandTemplate, target, PROCESS_VM_WRITE); | |
| 35 EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command)); | |
| 36 wsprintf(command, kCommandTemplate, target, PROCESS_QUERY_INFORMATION); | |
| 37 EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command)); | |
| 38 wsprintf(command, kCommandTemplate, target, WRITE_DAC); | |
| 39 EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command)); | |
| 40 wsprintf(command, kCommandTemplate, target, WRITE_OWNER); | |
| 41 EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command)); | |
| 42 wsprintf(command, kCommandTemplate, target, READ_CONTROL); | |
| 43 EXPECT_EQ(sandbox::SBOX_TEST_DENIED, runner->RunTest(command)); | |
| 44 } | |
| 45 | |
| 46 } // namespace | |
| 47 | |
| 48 namespace sandbox { | |
| 49 | |
| 50 // Returns true if the volume that contains any_path supports ACL security. The | |
| 51 // input path can contain unexpanded environment strings. Returns false on any | |
| 52 // failure or if the file system does not support file security (such as FAT). | |
| 53 bool VolumeSupportsACLs(const wchar_t* any_path) { | |
| 54 wchar_t expand[MAX_PATH +1]; | |
| 55 DWORD len =::ExpandEnvironmentStringsW(any_path, expand, _countof(expand)); | |
| 56 if (0 == len) return false; | |
| 57 if (len > _countof(expand)) return false; | |
| 58 if (!::PathStripToRootW(expand)) return false; | |
| 59 DWORD fs_flags = 0; | |
| 60 if (!::GetVolumeInformationW(expand, NULL, 0, 0, NULL, &fs_flags, NULL, 0)) | |
| 61 return false; | |
| 62 if (fs_flags & FILE_PERSISTENT_ACLS) return true; | |
| 63 return false; | |
| 64 } | |
| 65 | |
| 66 // Tests if the suite is working properly. | |
| 67 TEST(ValidationSuite, TestSuite) { | |
| 68 TestRunner runner; | |
| 69 ASSERT_EQ(SBOX_TEST_PING_OK, runner.RunTest(L"ping")); | |
| 70 } | |
| 71 | |
| 72 // Tests if the file system is correctly protected by the sandbox. | |
| 73 TEST(ValidationSuite, TestFileSystem) { | |
| 74 // Do not perform the test if the system is using FAT or any other | |
| 75 // file system that does not have file security. | |
| 76 ASSERT_TRUE(VolumeSupportsACLs(L"%SystemDrive%\\")); | |
| 77 ASSERT_TRUE(VolumeSupportsACLs(L"%SystemRoot%\\")); | |
| 78 ASSERT_TRUE(VolumeSupportsACLs(L"%ProgramFiles%\\")); | |
| 79 ASSERT_TRUE(VolumeSupportsACLs(L"%Temp%\\")); | |
| 80 ASSERT_TRUE(VolumeSupportsACLs(L"%AppData%\\")); | |
| 81 | |
| 82 TestRunner runner; | |
| 83 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenFile %SystemDrive%")); | |
| 84 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenFile %SystemRoot%")); | |
| 85 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenFile %ProgramFiles%")); | |
| 86 EXPECT_EQ(SBOX_TEST_DENIED, | |
| 87 runner.RunTest(L"OpenFile %SystemRoot%\\System32")); | |
| 88 EXPECT_EQ(SBOX_TEST_DENIED, | |
| 89 runner.RunTest(L"OpenFile %SystemRoot%\\explorer.exe")); | |
| 90 EXPECT_EQ(SBOX_TEST_DENIED, | |
| 91 runner.RunTest(L"OpenFile %SystemRoot%\\Cursors\\arrow_i.cur")); | |
| 92 EXPECT_EQ(SBOX_TEST_DENIED, | |
| 93 runner.RunTest(L"OpenFile %AllUsersProfile%")); | |
| 94 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenFile %Temp%")); | |
| 95 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenFile %AppData%")); | |
| 96 } | |
| 97 | |
| 98 // Tests if the registry is correctly protected by the sandbox. | |
| 99 TEST(ValidationSuite, TestRegistry) { | |
| 100 TestRunner runner; | |
| 101 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenKey HKLM")); | |
| 102 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenKey HKCU")); | |
| 103 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenKey HKU")); | |
| 104 EXPECT_EQ(SBOX_TEST_DENIED, | |
| 105 runner.RunTest( | |
| 106 L"OpenKey HKLM " | |
| 107 L"\"Software\\Microsoft\\Windows NT\\CurrentVersion\\WinLogon\"")); | |
| 108 } | |
| 109 | |
| 110 // Tests that the permissions on the Windowstation does not allow the sandbox | |
| 111 // to get to the interactive desktop or to make the sbox desktop interactive. | |
| 112 TEST(ValidationSuite, TestDesktop) { | |
| 113 TestRunner runner; | |
| 114 runner.GetPolicy()->SetAlternateDesktop(false); | |
| 115 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenInteractiveDesktop NULL")); | |
| 116 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"SwitchToSboxDesktop NULL")); | |
| 117 } | |
| 118 | |
| 119 // Tests if the windows are correctly protected by the sandbox. | |
| 120 TEST(ValidationSuite, TestWindows) { | |
| 121 TestRunner runner; | |
| 122 wchar_t command[1024] = {0}; | |
| 123 | |
| 124 wsprintf(command, L"ValidWindow %d", ::GetDesktopWindow()); | |
| 125 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(command)); | |
| 126 | |
| 127 wsprintf(command, L"ValidWindow %d", ::FindWindow(NULL, NULL)); | |
| 128 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(command)); | |
| 129 } | |
| 130 | |
| 131 // Tests that a locked-down process cannot open another locked-down process. | |
| 132 TEST(ValidationSuite, TestProcessDenyLockdown) { | |
| 133 TestRunner runner; | |
| 134 TestRunner target; | |
| 135 wchar_t command[1024] = {0}; | |
| 136 | |
| 137 target.SetAsynchronous(true); | |
| 138 | |
| 139 EXPECT_EQ(SBOX_TEST_SUCCEEDED, target.RunTest(L"SleepCmd 30000")); | |
| 140 | |
| 141 TestProcessAccess(&runner, target.process_id()); | |
| 142 } | |
| 143 | |
| 144 // Tests that a low-integrity process cannot open a locked-down process (due | |
| 145 // to the integrity label changing after startup via SetDelayedIntegrityLevel). | |
| 146 TEST(ValidationSuite, TestProcessDenyLowIntegrity) { | |
| 147 // This test applies only to Vista and above. | |
| 148 if (base::win::Version() < base::win::VERSION_VISTA) | |
| 149 return; | |
| 150 | |
| 151 TestRunner runner; | |
| 152 TestRunner target; | |
| 153 wchar_t command[1024] = {0}; | |
| 154 | |
| 155 target.SetAsynchronous(true); | |
| 156 target.GetPolicy()->SetDelayedIntegrityLevel(INTEGRITY_LEVEL_LOW); | |
| 157 | |
| 158 runner.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW); | |
| 159 runner.GetPolicy()->SetTokenLevel(USER_RESTRICTED_SAME_ACCESS, | |
| 160 USER_INTERACTIVE); | |
| 161 | |
| 162 EXPECT_EQ(SBOX_TEST_SUCCEEDED, target.RunTest(L"SleepCmd 30000")); | |
| 163 | |
| 164 TestProcessAccess(&runner, target.process_id()); | |
| 165 } | |
| 166 | |
| 167 // Tests that a locked-down process cannot open a low-integrity process. | |
| 168 TEST(ValidationSuite, TestProcessDenyBelowLowIntegrity) { | |
| 169 // This test applies only to Vista and above. | |
| 170 if (base::win::Version() < base::win::VERSION_VISTA) | |
| 171 return; | |
| 172 | |
| 173 TestRunner runner; | |
| 174 TestRunner target; | |
| 175 wchar_t command[1024] = {0}; | |
| 176 | |
| 177 target.SetAsynchronous(true); | |
| 178 target.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW); | |
| 179 target.GetPolicy()->SetTokenLevel(USER_RESTRICTED_SAME_ACCESS, | |
| 180 USER_INTERACTIVE); | |
| 181 | |
| 182 runner.GetPolicy()->SetDelayedIntegrityLevel(INTEGRITY_LEVEL_UNTRUSTED); | |
| 183 runner.GetPolicy()->SetTokenLevel(USER_RESTRICTED_SAME_ACCESS, | |
| 184 USER_INTERACTIVE); | |
| 185 | |
| 186 EXPECT_EQ(SBOX_TEST_SUCCEEDED, target.RunTest(L"SleepCmd 30000")); | |
| 187 | |
| 188 TestProcessAccess(&runner, target.process_id()); | |
| 189 } | |
| 190 | |
| 191 // Tests if the threads are correctly protected by the sandbox. | |
| 192 TEST(ValidationSuite, TestThread) { | |
| 193 TestRunner runner; | |
| 194 wchar_t command[1024] = {0}; | |
| 195 | |
| 196 wsprintf(command, L"OpenThreadCmd %d", ::GetCurrentThreadId()); | |
| 197 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(command)); | |
| 198 } | |
| 199 | |
| 200 } // namespace sandbox | |
| OLD | NEW |