OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <memory> | 5 #include <memory> |
6 #include <string> | 6 #include <string> |
7 | 7 |
8 #include "base/string16.h" | |
9 #include "base/sys_string_conversions.h" | 8 #include "base/sys_string_conversions.h" |
10 #include "base/win/scoped_handle.h" | 9 #include "base/win/scoped_handle.h" |
11 #include "base/win/scoped_process_information.h" | 10 #include "base/win/scoped_process_information.h" |
12 #include "base/win/windows_version.h" | |
13 #include "sandbox/win/src/sandbox.h" | 11 #include "sandbox/win/src/sandbox.h" |
14 #include "sandbox/win/src/sandbox_policy.h" | 12 #include "sandbox/win/src/sandbox_policy.h" |
15 #include "sandbox/win/src/sandbox_factory.h" | 13 #include "sandbox/win/src/sandbox_factory.h" |
16 #include "sandbox/win/tests/common/controller.h" | 14 #include "sandbox/win/tests/common/controller.h" |
17 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
18 | 16 |
19 namespace { | 17 namespace { |
20 | 18 |
21 // While the shell API provides better calls than this home brew function | 19 // While the shell API provides better calls than this home brew function |
22 // we use GetSystemWindowsDirectoryW which does not query the registry so | 20 // we use GetSystemWindowsDirectoryW which does not query the registry so |
23 // it is safe to use after revert. | 21 // it is safe to use after revert. |
24 string16 MakeFullPathToSystem32(const wchar_t* name) { | 22 std::wstring MakeFullPathToSystem32(const wchar_t* name) { |
25 wchar_t windows_path[MAX_PATH] = {0}; | 23 wchar_t windows_path[MAX_PATH] = {0}; |
26 ::GetSystemWindowsDirectoryW(windows_path, MAX_PATH); | 24 ::GetSystemWindowsDirectoryW(windows_path, MAX_PATH); |
27 string16 full_path(windows_path); | 25 std::wstring full_path(windows_path); |
28 if (full_path.empty()) { | 26 if (full_path.empty()) { |
29 return full_path; | 27 return full_path; |
30 } | 28 } |
31 full_path += L"\\system32\\"; | 29 full_path += L"\\system32\\"; |
32 full_path += name; | 30 full_path += name; |
33 return full_path; | 31 return full_path; |
34 } | 32 } |
35 | 33 |
36 // Creates a process with the |exe| and |command| parameter using the | 34 // Creates a process with the |exe| and |command| parameter using the |
37 // unicode and ascii version of the api. | 35 // unicode and ascii version of the api. |
38 sandbox::SboxTestResult CreateProcessHelper(const string16& exe, | 36 sandbox::SboxTestResult CreateProcessHelper(const std::wstring &exe, |
39 const string16& command) { | 37 const std::wstring &command) { |
40 base::win::ScopedProcessInformation pi; | 38 base::win::ScopedProcessInformation pi; |
41 STARTUPINFOW si = {sizeof(si)}; | 39 STARTUPINFOW si = {sizeof(si)}; |
42 | 40 |
43 const wchar_t *exe_name = NULL; | 41 const wchar_t *exe_name = NULL; |
44 if (!exe.empty()) | 42 if (!exe.empty()) |
45 exe_name = exe.c_str(); | 43 exe_name = exe.c_str(); |
46 | 44 |
47 const wchar_t *cmd_line = NULL; | 45 const wchar_t *cmd_line = NULL; |
48 if (!command.empty()) | 46 if (!command.empty()) |
49 cmd_line = command.c_str(); | 47 cmd_line = command.c_str(); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 if (ret1 == ret2) | 90 if (ret1 == ret2) |
93 return ret1; | 91 return ret1; |
94 | 92 |
95 return sandbox::SBOX_TEST_FAILED; | 93 return sandbox::SBOX_TEST_FAILED; |
96 } | 94 } |
97 | 95 |
98 } // namespace | 96 } // namespace |
99 | 97 |
100 namespace sandbox { | 98 namespace sandbox { |
101 | 99 |
102 SBOX_TESTS_COMMAND int Process_RunApp1(int argc, wchar_t **argv) { | 100 // Tries to create the process in argv[0] using 7 different ways. |
| 101 // Since we also try the Ansi and Unicode version of the CreateProcess API, |
| 102 // The process referenced by argv[0] will be spawned 14 times. |
| 103 SBOX_TESTS_COMMAND int Process_RunApp(int argc, wchar_t **argv) { |
103 if (argc != 1) { | 104 if (argc != 1) { |
104 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; | 105 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; |
105 } | 106 } |
106 if ((NULL == argv) || (NULL == argv[0])) { | 107 if ((NULL == argv) || (NULL == argv[0])) { |
107 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; | 108 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; |
108 } | 109 } |
109 string16 path = MakeFullPathToSystem32(argv[0]); | 110 std::wstring path = MakeFullPathToSystem32(argv[0]); |
110 | 111 |
111 // TEST 1: Try with the path in the app_name. | 112 // TEST 1: Try with the path in the app_name. |
112 return CreateProcessHelper(path, string16()); | 113 int result1 = CreateProcessHelper(path, std::wstring()); |
113 } | |
114 | |
115 SBOX_TESTS_COMMAND int Process_RunApp2(int argc, wchar_t **argv) { | |
116 if (argc != 1) { | |
117 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; | |
118 } | |
119 if ((NULL == argv) || (NULL == argv[0])) { | |
120 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; | |
121 } | |
122 string16 path = MakeFullPathToSystem32(argv[0]); | |
123 | 114 |
124 // TEST 2: Try with the path in the cmd_line. | 115 // TEST 2: Try with the path in the cmd_line. |
125 string16 cmd_line = L"\""; | 116 std::wstring cmd_line = L"\""; |
126 cmd_line += path; | 117 cmd_line += path; |
127 cmd_line += L"\""; | 118 cmd_line += L"\""; |
128 return CreateProcessHelper(string16(), cmd_line); | 119 int result2 = CreateProcessHelper(std::wstring(), cmd_line); |
129 } | |
130 | |
131 SBOX_TESTS_COMMAND int Process_RunApp3(int argc, wchar_t **argv) { | |
132 if (argc != 1) { | |
133 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; | |
134 } | |
135 if ((NULL == argv) || (NULL == argv[0])) { | |
136 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; | |
137 } | |
138 | 120 |
139 // TEST 3: Try file name in the cmd_line. | 121 // TEST 3: Try file name in the cmd_line. |
140 return CreateProcessHelper(string16(), argv[0]); | 122 int result3 = CreateProcessHelper(std::wstring(), argv[0]); |
141 } | |
142 | |
143 SBOX_TESTS_COMMAND int Process_RunApp4(int argc, wchar_t **argv) { | |
144 if (argc != 1) { | |
145 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; | |
146 } | |
147 if ((NULL == argv) || (NULL == argv[0])) { | |
148 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; | |
149 } | |
150 | 123 |
151 // TEST 4: Try file name in the app_name and current directory sets correctly. | 124 // TEST 4: Try file name in the app_name and current directory sets correctly. |
152 string16 system32 = MakeFullPathToSystem32(L""); | 125 std::wstring system32 = MakeFullPathToSystem32(L""); |
153 wchar_t current_directory[MAX_PATH + 1]; | 126 wchar_t current_directory[MAX_PATH + 1]; |
154 int result4; | 127 int result4; |
155 bool test_succeeded = false; | 128 bool test_succeeded = false; |
156 DWORD ret = ::GetCurrentDirectory(MAX_PATH, current_directory); | 129 DWORD ret = ::GetCurrentDirectory(MAX_PATH, current_directory); |
157 if (!ret) | 130 if (0 != ret && ret < MAX_PATH) { |
158 return SBOX_TEST_FIRST_ERROR; | |
159 | |
160 if (ret < MAX_PATH) { | |
161 current_directory[ret] = L'\\'; | 131 current_directory[ret] = L'\\'; |
162 current_directory[ret+1] = L'\0'; | 132 current_directory[ret+1] = L'\0'; |
163 if (::SetCurrentDirectory(system32.c_str())) { | 133 if (::SetCurrentDirectory(system32.c_str())) { |
164 result4 = CreateProcessHelper(argv[0], string16()); | 134 result4 = CreateProcessHelper(argv[0], std::wstring()); |
165 if (::SetCurrentDirectory(current_directory)) { | 135 if (::SetCurrentDirectory(current_directory)) { |
166 test_succeeded = true; | 136 test_succeeded = true; |
167 } | 137 } |
168 } else { | |
169 return SBOX_TEST_SECOND_ERROR; | |
170 } | 138 } |
171 } | 139 } |
172 if (!test_succeeded) | 140 if (!test_succeeded) |
173 result4 = SBOX_TEST_FAILED; | 141 result4 = SBOX_TEST_FAILED; |
174 | 142 |
175 return result4; | |
176 } | |
177 | |
178 SBOX_TESTS_COMMAND int Process_RunApp5(int argc, wchar_t **argv) { | |
179 if (argc != 1) { | |
180 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; | |
181 } | |
182 if ((NULL == argv) || (NULL == argv[0])) { | |
183 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; | |
184 } | |
185 string16 path = MakeFullPathToSystem32(argv[0]); | |
186 | |
187 // TEST 5: Try with the path in the cmd_line and arguments. | 143 // TEST 5: Try with the path in the cmd_line and arguments. |
188 string16 cmd_line = L"\""; | 144 cmd_line = L"\""; |
189 cmd_line += path; | 145 cmd_line += path; |
190 cmd_line += L"\" /I"; | 146 cmd_line += L"\" /INSERT"; |
191 return CreateProcessHelper(string16(), cmd_line); | 147 int result5 = CreateProcessHelper(std::wstring(), cmd_line); |
192 } | |
193 | |
194 SBOX_TESTS_COMMAND int Process_RunApp6(int argc, wchar_t **argv) { | |
195 if (argc != 1) { | |
196 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; | |
197 } | |
198 if ((NULL == argv) || (NULL == argv[0])) { | |
199 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; | |
200 } | |
201 | 148 |
202 // TEST 6: Try with the file_name in the cmd_line and arguments. | 149 // TEST 6: Try with the file_name in the cmd_line and arguments. |
203 string16 cmd_line = argv[0]; | 150 cmd_line = argv[0]; |
204 cmd_line += L" /I"; | 151 cmd_line += L" /INSERT"; |
205 return CreateProcessHelper(string16(), cmd_line); | 152 int result6 = CreateProcessHelper(std::wstring(), cmd_line); |
| 153 |
| 154 // TEST 7: Try with the path without the drive. |
| 155 cmd_line = path.substr(path.find(L'\\')); |
| 156 int result7 = CreateProcessHelper(std::wstring(), cmd_line); |
| 157 |
| 158 // Check if they all returned the same thing. |
| 159 if ((result1 == result2) && (result2 == result3) && (result3 == result4) && |
| 160 (result4 == result5) && (result5 == result6) && (result6 == result7)) |
| 161 return result1; |
| 162 |
| 163 return SBOX_TEST_FAILED; |
206 } | 164 } |
207 | 165 |
208 // Creates a process and checks if it's possible to get a handle to it's token. | 166 // Creates a process and checks if it's possible to get a handle to it's token. |
209 SBOX_TESTS_COMMAND int Process_GetChildProcessToken(int argc, wchar_t **argv) { | 167 SBOX_TESTS_COMMAND int Process_GetChildProcessToken(int argc, wchar_t **argv) { |
210 if (argc != 1) | 168 if (argc != 1) |
211 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; | 169 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; |
212 | 170 |
213 if ((NULL == argv) || (NULL == argv[0])) | 171 if ((NULL == argv) || (NULL == argv[0])) |
214 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; | 172 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; |
215 | 173 |
216 string16 path = MakeFullPathToSystem32(argv[0]); | 174 std::wstring path = MakeFullPathToSystem32(argv[0]); |
217 | 175 |
218 base::win::ScopedProcessInformation pi; | 176 base::win::ScopedProcessInformation pi; |
219 STARTUPINFOW si = {sizeof(si)}; | 177 STARTUPINFOW si = {sizeof(si)}; |
220 | 178 |
221 if (!::CreateProcessW(path.c_str(), NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, | 179 if (!::CreateProcessW(path.c_str(), NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, |
222 NULL, NULL, &si, pi.Receive())) { | 180 NULL, NULL, &si, pi.Receive())) { |
223 return SBOX_TEST_FAILED; | 181 return SBOX_TEST_FAILED; |
224 } | 182 } |
225 | 183 |
226 HANDLE token = NULL; | 184 HANDLE token = NULL; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 | 229 |
272 // Check the working case. | 230 // Check the working case. |
273 runner.GetPolicy()->SetTokenLevel(USER_INTERACTIVE, USER_INTERACTIVE); | 231 runner.GetPolicy()->SetTokenLevel(USER_INTERACTIVE, USER_INTERACTIVE); |
274 | 232 |
275 EXPECT_EQ(SBOX_ALL_OK, | 233 EXPECT_EQ(SBOX_ALL_OK, |
276 runner.GetPolicy()->AddRule(TargetPolicy::SUBSYS_PROCESS, | 234 runner.GetPolicy()->AddRule(TargetPolicy::SUBSYS_PROCESS, |
277 TargetPolicy::PROCESS_ALL_EXEC, | 235 TargetPolicy::PROCESS_ALL_EXEC, |
278 L"this is not important")); | 236 L"this is not important")); |
279 } | 237 } |
280 | 238 |
281 TEST(ProcessPolicyTest, CreateProcessAW) { | 239 // This test is disabled. See bug 1305476. |
| 240 TEST(ProcessPolicyTest, DISABLED_RunFindstrExe) { |
282 TestRunner runner; | 241 TestRunner runner; |
283 string16 exe_path = MakeFullPathToSystem32(L"findstr.exe"); | 242 std::wstring exe_path = MakeFullPathToSystem32(L"findstr.exe"); |
284 string16 system32 = MakeFullPathToSystem32(L""); | 243 std::wstring system32 = MakeFullPathToSystem32(L""); |
285 ASSERT_TRUE(!exe_path.empty()); | 244 ASSERT_TRUE(!exe_path.empty()); |
286 EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_PROCESS, | 245 EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_PROCESS, |
287 TargetPolicy::PROCESS_MIN_EXEC, | 246 TargetPolicy::PROCESS_MIN_EXEC, |
288 exe_path.c_str())); | 247 exe_path.c_str())); |
289 | 248 |
290 // Need to add directory rules for the directories that we use in | 249 // Need to add directory rules for the directories that we use in |
291 // SetCurrentDirectory. | 250 // SetCurrentDirectory. |
292 EXPECT_TRUE(runner.AddFsRule(TargetPolicy::FILES_ALLOW_DIR_ANY, | 251 EXPECT_TRUE(runner.AddFsRule(TargetPolicy::FILES_ALLOW_DIR_ANY, |
293 system32.c_str())); | 252 system32.c_str())); |
294 | 253 |
295 wchar_t current_directory[MAX_PATH]; | 254 wchar_t current_directory[MAX_PATH]; |
296 DWORD ret = ::GetCurrentDirectory(MAX_PATH, current_directory); | 255 DWORD ret = ::GetCurrentDirectory(MAX_PATH, current_directory); |
297 ASSERT_TRUE(0 != ret && ret < MAX_PATH); | 256 ASSERT_TRUE(0 != ret && ret < MAX_PATH); |
298 | 257 |
299 wcscat_s(current_directory, MAX_PATH, L"\\"); | 258 wcscat_s(current_directory, MAX_PATH, L"\\"); |
300 EXPECT_TRUE(runner.AddFsRule(TargetPolicy::FILES_ALLOW_DIR_ANY, | 259 EXPECT_TRUE(runner.AddFsRule(TargetPolicy::FILES_ALLOW_DIR_ANY, |
301 current_directory)); | 260 current_directory)); |
302 | 261 |
303 SboxTestResult expected = SBOX_TEST_SECOND_ERROR; | 262 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Process_RunApp findstr.exe")); |
304 if (base::win::OSInfo::GetInstance()->version() < base::win::VERSION_VISTA) | 263 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Process_RunApp calc.exe")); |
305 expected = SBOX_TEST_DENIED; | |
306 | |
307 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Process_RunApp1 calc.exe")); | |
308 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Process_RunApp2 calc.exe")); | |
309 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Process_RunApp3 calc.exe")); | |
310 EXPECT_EQ(expected, runner.RunTest(L"Process_RunApp4 calc.exe")); | |
311 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Process_RunApp5 calc.exe")); | |
312 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Process_RunApp6 calc.exe")); | |
313 | |
314 if (base::win::OSInfo::GetInstance()->version() < base::win::VERSION_VISTA) | |
315 expected = SBOX_TEST_SUCCEEDED; | |
316 | |
317 EXPECT_EQ(SBOX_TEST_SUCCEEDED, | |
318 runner.RunTest(L"Process_RunApp1 findstr.exe")); | |
319 EXPECT_EQ(SBOX_TEST_SUCCEEDED, | |
320 runner.RunTest(L"Process_RunApp2 findstr.exe")); | |
321 EXPECT_EQ(SBOX_TEST_SUCCEEDED, | |
322 runner.RunTest(L"Process_RunApp3 findstr.exe")); | |
323 EXPECT_EQ(expected, runner.RunTest(L"Process_RunApp4 findstr.exe")); | |
324 EXPECT_EQ(SBOX_TEST_SUCCEEDED, | |
325 runner.RunTest(L"Process_RunApp5 findstr.exe")); | |
326 EXPECT_EQ(SBOX_TEST_SUCCEEDED, | |
327 runner.RunTest(L"Process_RunApp6 findstr.exe")); | |
328 } | 264 } |
329 | 265 |
330 TEST(ProcessPolicyTest, OpenToken) { | 266 TEST(ProcessPolicyTest, OpenToken) { |
331 TestRunner runner; | 267 TestRunner runner; |
332 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Process_OpenToken")); | 268 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Process_OpenToken")); |
333 } | 269 } |
334 | 270 |
335 TEST(ProcessPolicyTest, TestGetProcessTokenMinAccess) { | 271 TEST(ProcessPolicyTest, TestGetProcessTokenMinAccess) { |
336 TestRunner runner; | 272 TestRunner runner; |
337 string16 exe_path = MakeFullPathToSystem32(L"findstr.exe"); | 273 std::wstring exe_path = MakeFullPathToSystem32(L"findstr.exe"); |
338 ASSERT_TRUE(!exe_path.empty()); | 274 ASSERT_TRUE(!exe_path.empty()); |
339 EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_PROCESS, | 275 EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_PROCESS, |
340 TargetPolicy::PROCESS_MIN_EXEC, | 276 TargetPolicy::PROCESS_MIN_EXEC, |
341 exe_path.c_str())); | 277 exe_path.c_str())); |
342 | 278 |
343 EXPECT_EQ(SBOX_TEST_DENIED, | 279 EXPECT_EQ(SBOX_TEST_DENIED, |
344 runner.RunTest(L"Process_GetChildProcessToken findstr.exe")); | 280 runner.RunTest(L"Process_GetChildProcessToken findstr.exe")); |
345 } | 281 } |
346 | 282 |
347 TEST(ProcessPolicyTest, TestGetProcessTokenMaxAccess) { | 283 TEST(ProcessPolicyTest, TestGetProcessTokenMaxAccess) { |
348 TestRunner runner(JOB_UNPROTECTED, USER_INTERACTIVE, USER_INTERACTIVE); | 284 TestRunner runner(JOB_UNPROTECTED, USER_INTERACTIVE, USER_INTERACTIVE); |
349 string16 exe_path = MakeFullPathToSystem32(L"findstr.exe"); | 285 std::wstring exe_path = MakeFullPathToSystem32(L"findstr.exe"); |
350 ASSERT_TRUE(!exe_path.empty()); | 286 ASSERT_TRUE(!exe_path.empty()); |
351 EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_PROCESS, | 287 EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_PROCESS, |
352 TargetPolicy::PROCESS_ALL_EXEC, | 288 TargetPolicy::PROCESS_ALL_EXEC, |
353 exe_path.c_str())); | 289 exe_path.c_str())); |
354 | 290 |
355 EXPECT_EQ(SBOX_TEST_SUCCEEDED, | 291 EXPECT_EQ(SBOX_TEST_SUCCEEDED, |
356 runner.RunTest(L"Process_GetChildProcessToken findstr.exe")); | 292 runner.RunTest(L"Process_GetChildProcessToken findstr.exe")); |
357 } | 293 } |
358 | 294 |
359 } // namespace sandbox | 295 } // namespace sandbox |
OLD | NEW |