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