| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/sys_string_conversions.h" | 8 #include "base/sys_string_conversions.h" |
| 9 #include "base/win/scoped_handle.h" | 9 #include "base/win/scoped_handle.h" |
| 10 #include "base/win/scoped_process_information.h" |
| 10 #include "sandbox/src/sandbox.h" | 11 #include "sandbox/src/sandbox.h" |
| 11 #include "sandbox/src/sandbox_policy.h" | 12 #include "sandbox/src/sandbox_policy.h" |
| 12 #include "sandbox/src/sandbox_factory.h" | 13 #include "sandbox/src/sandbox_factory.h" |
| 13 #include "sandbox/tests/common/controller.h" | 14 #include "sandbox/tests/common/controller.h" |
| 14 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
| 15 | 16 |
| 16 namespace { | 17 namespace { |
| 17 | 18 |
| 18 // 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 |
| 19 // we use GetSystemWindowsDirectoryW which does not query the registry so | 20 // we use GetSystemWindowsDirectoryW which does not query the registry so |
| 20 // it is safe to use after revert. | 21 // it is safe to use after revert. |
| 21 std::wstring MakeFullPathToSystem32(const wchar_t* name) { | 22 std::wstring MakeFullPathToSystem32(const wchar_t* name) { |
| 22 wchar_t windows_path[MAX_PATH] = {0}; | 23 wchar_t windows_path[MAX_PATH] = {0}; |
| 23 ::GetSystemWindowsDirectoryW(windows_path, MAX_PATH); | 24 ::GetSystemWindowsDirectoryW(windows_path, MAX_PATH); |
| 24 std::wstring full_path(windows_path); | 25 std::wstring full_path(windows_path); |
| 25 if (full_path.empty()) { | 26 if (full_path.empty()) { |
| 26 return full_path; | 27 return full_path; |
| 27 } | 28 } |
| 28 full_path += L"\\system32\\"; | 29 full_path += L"\\system32\\"; |
| 29 full_path += name; | 30 full_path += name; |
| 30 return full_path; | 31 return full_path; |
| 31 } | 32 } |
| 32 | 33 |
| 33 // Creates a process with the |exe| and |command| parameter using the | 34 // Creates a process with the |exe| and |command| parameter using the |
| 34 // unicode and ascii version of the api. | 35 // unicode and ascii version of the api. |
| 35 sandbox::SboxTestResult CreateProcessHelper(const std::wstring &exe, | 36 sandbox::SboxTestResult CreateProcessHelper(const std::wstring &exe, |
| 36 const std::wstring &command) { | 37 const std::wstring &command) { |
| 37 PROCESS_INFORMATION pi; | 38 base::win::ScopedProcessInformation pi; |
| 38 STARTUPINFOW si = {sizeof(si)}; | 39 STARTUPINFOW si = {sizeof(si)}; |
| 39 | 40 |
| 40 const wchar_t *exe_name = NULL; | 41 const wchar_t *exe_name = NULL; |
| 41 if (!exe.empty()) | 42 if (!exe.empty()) |
| 42 exe_name = exe.c_str(); | 43 exe_name = exe.c_str(); |
| 43 | 44 |
| 44 const wchar_t *cmd_line = NULL; | 45 const wchar_t *cmd_line = NULL; |
| 45 if (!command.empty()) | 46 if (!command.empty()) |
| 46 cmd_line = command.c_str(); | 47 cmd_line = command.c_str(); |
| 47 | 48 |
| 48 // Create the process with the unicode version of the API. | 49 // Create the process with the unicode version of the API. |
| 49 sandbox::SboxTestResult ret1 = sandbox::SBOX_TEST_FAILED; | 50 sandbox::SboxTestResult ret1 = sandbox::SBOX_TEST_FAILED; |
| 50 if (!::CreateProcessW(exe_name, const_cast<wchar_t*>(cmd_line), NULL, NULL, | 51 if (!::CreateProcessW(exe_name, const_cast<wchar_t*>(cmd_line), NULL, NULL, |
| 51 FALSE, 0, NULL, NULL, &si, &pi)) { | 52 FALSE, 0, NULL, NULL, &si, pi.Receive())) { |
| 52 DWORD last_error = GetLastError(); | 53 DWORD last_error = GetLastError(); |
| 53 if ((ERROR_NOT_ENOUGH_QUOTA == last_error) || | 54 if ((ERROR_NOT_ENOUGH_QUOTA == last_error) || |
| 54 (ERROR_ACCESS_DENIED == last_error) || | 55 (ERROR_ACCESS_DENIED == last_error) || |
| 55 (ERROR_FILE_NOT_FOUND == last_error)) { | 56 (ERROR_FILE_NOT_FOUND == last_error)) { |
| 56 ret1 = sandbox::SBOX_TEST_DENIED; | 57 ret1 = sandbox::SBOX_TEST_DENIED; |
| 57 } else { | 58 } else { |
| 58 ret1 = sandbox::SBOX_TEST_FAILED; | 59 ret1 = sandbox::SBOX_TEST_FAILED; |
| 59 } | 60 } |
| 60 } else { | 61 } else { |
| 61 ret1 = sandbox::SBOX_TEST_SUCCEEDED; | 62 ret1 = sandbox::SBOX_TEST_SUCCEEDED; |
| 62 } | 63 } |
| 63 | 64 |
| 65 pi.Close(); |
| 66 |
| 64 // Do the same with the ansi version of the api | 67 // Do the same with the ansi version of the api |
| 65 STARTUPINFOA sia = {sizeof(sia)}; | 68 STARTUPINFOA sia = {sizeof(sia)}; |
| 66 sandbox::SboxTestResult ret2 = sandbox::SBOX_TEST_FAILED; | 69 sandbox::SboxTestResult ret2 = sandbox::SBOX_TEST_FAILED; |
| 67 | 70 |
| 68 std::string narrow_cmd_line; | 71 std::string narrow_cmd_line; |
| 69 if (cmd_line) | 72 if (cmd_line) |
| 70 narrow_cmd_line = base::SysWideToMultiByte(cmd_line, CP_UTF8); | 73 narrow_cmd_line = base::SysWideToMultiByte(cmd_line, CP_UTF8); |
| 71 if (!::CreateProcessA( | 74 if (!::CreateProcessA( |
| 72 exe_name ? base::SysWideToMultiByte(exe_name, CP_UTF8).c_str() : NULL, | 75 exe_name ? base::SysWideToMultiByte(exe_name, CP_UTF8).c_str() : NULL, |
| 73 cmd_line ? const_cast<char*>(narrow_cmd_line.c_str()) : NULL, | 76 cmd_line ? const_cast<char*>(narrow_cmd_line.c_str()) : NULL, |
| 74 NULL, NULL, FALSE, 0, NULL, NULL, &sia, &pi)) { | 77 NULL, NULL, FALSE, 0, NULL, NULL, &sia, pi.Receive())) { |
| 75 DWORD last_error = GetLastError(); | 78 DWORD last_error = GetLastError(); |
| 76 if ((ERROR_NOT_ENOUGH_QUOTA == last_error) || | 79 if ((ERROR_NOT_ENOUGH_QUOTA == last_error) || |
| 77 (ERROR_ACCESS_DENIED == last_error) || | 80 (ERROR_ACCESS_DENIED == last_error) || |
| 78 (ERROR_FILE_NOT_FOUND == last_error)) { | 81 (ERROR_FILE_NOT_FOUND == last_error)) { |
| 79 ret2 = sandbox::SBOX_TEST_DENIED; | 82 ret2 = sandbox::SBOX_TEST_DENIED; |
| 80 } else { | 83 } else { |
| 81 ret2 = sandbox::SBOX_TEST_FAILED; | 84 ret2 = sandbox::SBOX_TEST_FAILED; |
| 82 } | 85 } |
| 83 } else { | 86 } else { |
| 84 ret2 = sandbox::SBOX_TEST_SUCCEEDED; | 87 ret2 = sandbox::SBOX_TEST_SUCCEEDED; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 // 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. |
| 164 SBOX_TESTS_COMMAND int Process_GetChildProcessToken(int argc, wchar_t **argv) { | 167 SBOX_TESTS_COMMAND int Process_GetChildProcessToken(int argc, wchar_t **argv) { |
| 165 if (argc != 1) | 168 if (argc != 1) |
| 166 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; | 169 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; |
| 167 | 170 |
| 168 if ((NULL == argv) || (NULL == argv[0])) | 171 if ((NULL == argv) || (NULL == argv[0])) |
| 169 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; | 172 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; |
| 170 | 173 |
| 171 std::wstring path = MakeFullPathToSystem32(argv[0]); | 174 std::wstring path = MakeFullPathToSystem32(argv[0]); |
| 172 | 175 |
| 173 PROCESS_INFORMATION pi = {0}; | 176 base::win::ScopedProcessInformation pi; |
| 174 STARTUPINFOW si = {sizeof(si)}; | 177 STARTUPINFOW si = {sizeof(si)}; |
| 175 | 178 |
| 176 if (!::CreateProcessW(path.c_str(), NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, | 179 if (!::CreateProcessW(path.c_str(), NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, |
| 177 NULL, NULL, &si, &pi)) { | 180 NULL, NULL, &si, pi.Receive())) { |
| 178 return SBOX_TEST_FAILED; | 181 return SBOX_TEST_FAILED; |
| 179 } | 182 } |
| 180 | 183 |
| 181 base::win::ScopedHandle process(pi.hProcess); | |
| 182 base::win::ScopedHandle thread(pi.hThread); | |
| 183 | |
| 184 HANDLE token = NULL; | 184 HANDLE token = NULL; |
| 185 BOOL result = ::OpenProcessToken(process.Get(), TOKEN_IMPERSONATE, &token); | 185 BOOL result = |
| 186 ::OpenProcessToken(pi.process_handle(), TOKEN_IMPERSONATE, &token); |
| 186 DWORD error = ::GetLastError(); | 187 DWORD error = ::GetLastError(); |
| 187 | 188 |
| 188 base::win::ScopedHandle token_handle(token); | 189 base::win::ScopedHandle token_handle(token); |
| 189 | 190 |
| 190 if (!::TerminateProcess(process.Get(), 0)) | 191 if (!::TerminateProcess(pi.process_handle(), 0)) |
| 191 return SBOX_TEST_FAILED; | 192 return SBOX_TEST_FAILED; |
| 192 | 193 |
| 193 if (result && token) | 194 if (result && token) |
| 194 return SBOX_TEST_SUCCEEDED; | 195 return SBOX_TEST_SUCCEEDED; |
| 195 | 196 |
| 196 if (ERROR_ACCESS_DENIED == error) | 197 if (ERROR_ACCESS_DENIED == error) |
| 197 return SBOX_TEST_DENIED; | 198 return SBOX_TEST_DENIED; |
| 198 | 199 |
| 199 return SBOX_TEST_FAILED; | 200 return SBOX_TEST_FAILED; |
| 200 } | 201 } |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 ASSERT_TRUE(!exe_path.empty()); | 286 ASSERT_TRUE(!exe_path.empty()); |
| 286 EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_PROCESS, | 287 EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_PROCESS, |
| 287 TargetPolicy::PROCESS_ALL_EXEC, | 288 TargetPolicy::PROCESS_ALL_EXEC, |
| 288 exe_path.c_str())); | 289 exe_path.c_str())); |
| 289 | 290 |
| 290 EXPECT_EQ(SBOX_TEST_SUCCEEDED, | 291 EXPECT_EQ(SBOX_TEST_SUCCEEDED, |
| 291 runner.RunTest(L"Process_GetChildProcessToken findstr.exe")); | 292 runner.RunTest(L"Process_GetChildProcessToken findstr.exe")); |
| 292 } | 293 } |
| 293 | 294 |
| 294 } // namespace sandbox | 295 } // namespace sandbox |
| OLD | NEW |