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(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 201