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 17namespace { 18 19void 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 48namespace 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). 53bool 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. 67TEST(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. 73TEST(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. 99TEST(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. 112TEST(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. 120TEST(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. 132TEST(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). 146TEST(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. 168TEST(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. 192TEST(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