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.
5 // This file contains the validation tests for the sandbox.
6 // It includes the tests that need to be performed inside the
11 #include "base/win/windows_version.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "sandbox/win/tests/common/controller.h"
15 #pragma comment(lib, "shlwapi.lib")
19 void TestProcessAccess(sandbox::TestRunner
* runner
, DWORD target
) {
20 const wchar_t *kCommandTemplate
= L
"OpenProcessCmd %d %d";
21 wchar_t command
[1024] = {0};
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
));
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;
60 if (!::GetVolumeInformationW(expand
, NULL
, 0, 0, NULL
, &fs_flags
, NULL
, 0))
62 if (fs_flags
& FILE_PERSISTENT_ACLS
) return true;
66 // Tests if the suite is working properly.
67 TEST(ValidationSuite
, TestSuite
) {
69 ASSERT_EQ(SBOX_TEST_PING_OK
, runner
.RunTest(L
"ping"));
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%\\"));
83 EXPECT_EQ(SBOX_TEST_DENIED
, runner
.RunTest(L
"OpenFileCmd %SystemDrive%"));
84 EXPECT_EQ(SBOX_TEST_DENIED
, runner
.RunTest(L
"OpenFileCmd %SystemRoot%"));
85 EXPECT_EQ(SBOX_TEST_DENIED
, runner
.RunTest(L
"OpenFileCmd %ProgramFiles%"));
86 EXPECT_EQ(SBOX_TEST_DENIED
,
87 runner
.RunTest(L
"OpenFileCmd %SystemRoot%\\System32"));
88 EXPECT_EQ(SBOX_TEST_DENIED
,
89 runner
.RunTest(L
"OpenFileCmd %SystemRoot%\\explorer.exe"));
90 EXPECT_EQ(SBOX_TEST_DENIED
,
91 runner
.RunTest(L
"OpenFileCmd %SystemRoot%\\Cursors\\arrow_i.cur"));
92 EXPECT_EQ(SBOX_TEST_DENIED
,
93 runner
.RunTest(L
"OpenFileCmd %AllUsersProfile%"));
94 EXPECT_EQ(SBOX_TEST_DENIED
, runner
.RunTest(L
"OpenFileCmd %Temp%"));
95 EXPECT_EQ(SBOX_TEST_DENIED
, runner
.RunTest(L
"OpenFileCmd %AppData%"));
98 // Tests if the registry is correctly protected by the sandbox.
99 TEST(ValidationSuite
, TestRegistry
) {
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
,
107 L
"\"Software\\Microsoft\\Windows NT\\CurrentVersion\\WinLogon\""));
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
) {
114 runner
.GetPolicy()->SetAlternateDesktop(true);
115 runner
.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW
);
116 EXPECT_EQ(SBOX_TEST_DENIED
, runner
.RunTest(L
"OpenInteractiveDesktop NULL"));
117 EXPECT_EQ(SBOX_TEST_DENIED
, runner
.RunTest(L
"SwitchToSboxDesktop NULL"));
120 // Tests that the permissions on the Windowstation does not allow the sandbox
121 // to get to the interactive desktop or to make the sbox desktop interactive.
122 TEST(ValidationSuite
, TestAlternateDesktop
) {
123 base::win::Version version
= base::win::GetVersion();
124 if (version
< base::win::VERSION_WIN7
)
128 EXPECT_EQ(SBOX_TEST_DENIED
, runner
.RunTest(L
"EnumAlternateWinsta NULL"));
130 wchar_t command
[1024] = {0};
131 runner
.SetTimeout(3600000);
132 runner
.GetPolicy()->SetAlternateDesktop(true);
133 runner
.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW
);
134 base::string16 desktop_name
= runner
.GetPolicy()->GetAlternateDesktop();
135 desktop_name
= desktop_name
.substr(desktop_name
.find('\\') + 1);
136 wsprintf(command
, L
"OpenAlternateDesktop %lS", desktop_name
.c_str());
137 EXPECT_EQ(SBOX_TEST_DENIED
, runner
.RunTest(command
));
140 // Tests if the windows are correctly protected by the sandbox.
141 TEST(ValidationSuite
, TestWindows
) {
143 wchar_t command
[1024] = {0};
145 wsprintf(command
, L
"ValidWindow %Id",
146 reinterpret_cast<size_t>(::GetDesktopWindow()));
147 EXPECT_EQ(SBOX_TEST_DENIED
, runner
.RunTest(command
));
149 wsprintf(command
, L
"ValidWindow %Id",
150 reinterpret_cast<size_t>(::FindWindow(NULL
, NULL
)));
151 EXPECT_EQ(SBOX_TEST_DENIED
, runner
.RunTest(command
));
154 // Tests that a locked-down process cannot open another locked-down process.
155 TEST(ValidationSuite
, TestProcessDenyLockdown
) {
159 target
.SetAsynchronous(true);
161 EXPECT_EQ(SBOX_TEST_SUCCEEDED
, target
.RunTest(L
"SleepCmd 30000"));
163 TestProcessAccess(&runner
, target
.process_id());
166 // Tests that a low-integrity process cannot open a locked-down process (due
167 // to the integrity label changing after startup via SetDelayedIntegrityLevel).
168 TEST(ValidationSuite
, TestProcessDenyLowIntegrity
) {
169 // This test applies only to Vista and above.
170 if (base::win::GetVersion() < base::win::VERSION_VISTA
)
176 target
.SetAsynchronous(true);
177 target
.GetPolicy()->SetDelayedIntegrityLevel(INTEGRITY_LEVEL_LOW
);
179 runner
.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW
);
180 runner
.GetPolicy()->SetTokenLevel(USER_RESTRICTED_SAME_ACCESS
,
183 EXPECT_EQ(SBOX_TEST_SUCCEEDED
, target
.RunTest(L
"SleepCmd 30000"));
185 TestProcessAccess(&runner
, target
.process_id());
188 // Tests that a locked-down process cannot open a low-integrity process.
189 TEST(ValidationSuite
, TestProcessDenyBelowLowIntegrity
) {
190 // This test applies only to Vista and above.
191 if (base::win::GetVersion() < base::win::VERSION_VISTA
)
197 target
.SetAsynchronous(true);
198 target
.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW
);
199 target
.GetPolicy()->SetTokenLevel(USER_RESTRICTED_SAME_ACCESS
,
202 runner
.GetPolicy()->SetDelayedIntegrityLevel(INTEGRITY_LEVEL_UNTRUSTED
);
203 runner
.GetPolicy()->SetTokenLevel(USER_RESTRICTED_SAME_ACCESS
,
206 EXPECT_EQ(SBOX_TEST_SUCCEEDED
, target
.RunTest(L
"SleepCmd 30000"));
208 TestProcessAccess(&runner
, target
.process_id());
211 // Tests if the threads are correctly protected by the sandbox.
212 TEST(ValidationSuite
, TestThread
) {
214 wchar_t command
[1024] = {0};
216 wsprintf(command
, L
"OpenThreadCmd %d", ::GetCurrentThreadId());
217 EXPECT_EQ(SBOX_TEST_DENIED
, runner
.RunTest(command
));
220 // Tests if an over-limit allocation will be denied.
221 TEST(ValidationSuite
, TestMemoryLimit
) {
223 wchar_t command
[1024] = {0};
224 const int kAllocationSize
= 256 * 1024 * 1024;
226 wsprintf(command
, L
"AllocateCmd %d", kAllocationSize
);
227 runner
.GetPolicy()->SetJobMemoryLimit(kAllocationSize
);
228 EXPECT_EQ(SBOX_FATAL_MEMORY_EXCEEDED
, runner
.RunTest(command
));
231 // Tests a large allocation will succeed absent limits.
232 TEST(ValidationSuite
, TestMemoryNoLimit
) {
234 wchar_t command
[1024] = {0};
235 const int kAllocationSize
= 256 * 1024 * 1024;
237 wsprintf(command
, L
"AllocateCmd %d", kAllocationSize
);
238 EXPECT_EQ(SBOX_TEST_SUCCEEDED
, runner
.RunTest(command
));
241 } // namespace sandbox