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