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/win/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(true); 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 that the permissions on the Windowstation does not allow the sandbox 120 // to get to the interactive desktop or to make the sbox desktop interactive. 121 TEST(ValidationSuite, TestAlternateDesktop) { 122 base::win::Version version = base::win::GetVersion(); 123 if (version < base::win::VERSION_WIN7) 124 return; 125 126 TestRunner runner; 127 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"EnumAlternateWinsta NULL")); 128 129 wchar_t command[1024] = {0}; 130 runner.SetTimeout(3600000); 131 runner.GetPolicy()->SetAlternateDesktop(true); 132 runner.GetPolicy()->SetDelayedIntegrityLevel(INTEGRITY_LEVEL_UNTRUSTED); 133 base::string16 desktop_name = runner.GetPolicy()->GetAlternateDesktop(); 134 desktop_name = desktop_name.substr(desktop_name.find('\\') + 1); 135 wsprintf(command, L"OpenAlternateDesktop %lS", desktop_name.c_str()); 136 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(command)); 137 } 138 139 // Tests if the windows are correctly protected by the sandbox. 140 TEST(ValidationSuite, TestWindows) { 141 TestRunner runner; 142 wchar_t command[1024] = {0}; 143 144 wsprintf(command, L"ValidWindow %d", ::GetDesktopWindow()); 145 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(command)); 146 147 wsprintf(command, L"ValidWindow %d", ::FindWindow(NULL, NULL)); 148 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(command)); 149 } 150 151 // Tests that a locked-down process cannot open another locked-down process. 152 TEST(ValidationSuite, TestProcessDenyLockdown) { 153 TestRunner runner; 154 TestRunner target; 155 wchar_t command[1024] = {0}; 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 // This test applies only to Vista and above. 168 if (base::win::Version() < base::win::VERSION_VISTA) 169 return; 170 171 TestRunner runner; 172 TestRunner target; 173 wchar_t command[1024] = {0}; 174 175 target.SetAsynchronous(true); 176 target.GetPolicy()->SetDelayedIntegrityLevel(INTEGRITY_LEVEL_LOW); 177 178 runner.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW); 179 runner.GetPolicy()->SetTokenLevel(USER_RESTRICTED_SAME_ACCESS, 180 USER_INTERACTIVE); 181 182 EXPECT_EQ(SBOX_TEST_SUCCEEDED, target.RunTest(L"SleepCmd 30000")); 183 184 TestProcessAccess(&runner, target.process_id()); 185 } 186 187 // Tests that a locked-down process cannot open a low-integrity process. 188 TEST(ValidationSuite, TestProcessDenyBelowLowIntegrity) { 189 // This test applies only to Vista and above. 190 if (base::win::Version() < base::win::VERSION_VISTA) 191 return; 192 193 TestRunner runner; 194 TestRunner target; 195 wchar_t command[1024] = {0}; 196 197 target.SetAsynchronous(true); 198 target.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW); 199 target.GetPolicy()->SetTokenLevel(USER_RESTRICTED_SAME_ACCESS, 200 USER_INTERACTIVE); 201 202 runner.GetPolicy()->SetDelayedIntegrityLevel(INTEGRITY_LEVEL_UNTRUSTED); 203 runner.GetPolicy()->SetTokenLevel(USER_RESTRICTED_SAME_ACCESS, 204 USER_INTERACTIVE); 205 206 EXPECT_EQ(SBOX_TEST_SUCCEEDED, target.RunTest(L"SleepCmd 30000")); 207 208 TestProcessAccess(&runner, target.process_id()); 209 } 210 211 // Tests if the threads are correctly protected by the sandbox. 212 TEST(ValidationSuite, TestThread) { 213 TestRunner runner; 214 wchar_t command[1024] = {0}; 215 216 wsprintf(command, L"OpenThreadCmd %d", ::GetCurrentThreadId()); 217 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(command)); 218 } 219 220 } // namespace sandbox 221