diff options
author | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-01 21:49:51 +0000 |
---|---|---|
committer | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-01 21:49:51 +0000 |
commit | f1776577dd6c3b2f0a0af0eb35b6367a6b2e77d6 (patch) | |
tree | 3f7d8aa7cb93c32a138e9e414ebba4ca0ee3218e /sandbox | |
parent | f2aca70141a15aef16e2244c7dc93e58b914e6d0 (diff) | |
download | chromium_src-f1776577dd6c3b2f0a0af0eb35b6367a6b2e77d6.zip chromium_src-f1776577dd6c3b2f0a0af0eb35b6367a6b2e77d6.tar.gz chromium_src-f1776577dd6c3b2f0a0af0eb35b6367a6b2e77d6.tar.bz2 |
Revert 130716 - Use ScopedProcessInformation and other RAII types in sandbox.
BUG=127931
TBR=cpu
-------
See http://codereview.chromium.org/9700038/ for the definition of ScopedProcessInformation.
BUG=None
TEST=None
Review URL: https://chromiumcodereview.appspot.com/9959018
TBR=erikwright@chromium.org
Review URL: https://chromiumcodereview.appspot.com/10493002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@140105 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sandbox')
-rw-r--r-- | sandbox/src/Wow64.cc | 15 | ||||
-rw-r--r-- | sandbox/src/broker_services.cc | 45 | ||||
-rw-r--r-- | sandbox/src/interception_unittest.cc | 18 | ||||
-rw-r--r-- | sandbox/src/job_unittest.cc | 13 | ||||
-rw-r--r-- | sandbox/src/policy_target_test.cc | 43 | ||||
-rw-r--r-- | sandbox/src/process_policy_test.cc | 23 | ||||
-rw-r--r-- | sandbox/src/restricted_token_utils.cc | 27 | ||||
-rw-r--r-- | sandbox/src/target_process.cc | 110 | ||||
-rw-r--r-- | sandbox/src/target_process.h | 37 |
9 files changed, 168 insertions, 163 deletions
diff --git a/sandbox/src/Wow64.cc b/sandbox/src/Wow64.cc index 5098647..5faebe7 100644 --- a/sandbox/src/Wow64.cc +++ b/sandbox/src/Wow64.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -8,7 +8,6 @@ #include "base/logging.h" #include "base/memory/scoped_ptr.h" -#include "base/win/scoped_process_information.h" #include "base/win/windows_version.h" #include "sandbox/src/target_process.h" @@ -157,16 +156,18 @@ bool Wow64::RunWowHelper(void* buffer) { STARTUPINFO startup_info = {0}; startup_info.cb = sizeof(startup_info); - base::win::ScopedProcessInformation process_info; + PROCESS_INFORMATION process_info; if (!::CreateProcess(NULL, writable_command.get(), NULL, NULL, FALSE, 0, NULL, - NULL, &startup_info, process_info.Receive())) + NULL, &startup_info, &process_info)) return false; - DWORD reason = ::WaitForSingleObject(process_info.process_handle(), INFINITE); + DWORD reason = ::WaitForSingleObject(process_info.hProcess, INFINITE); DWORD code; - bool ok = - ::GetExitCodeProcess(process_info.process_handle(), &code) ? true : false; + bool ok = ::GetExitCodeProcess(process_info.hProcess, &code) ? true : false; + + ::CloseHandle(process_info.hProcess); + ::CloseHandle(process_info.hThread); if (WAIT_TIMEOUT == reason) return false; diff --git a/sandbox/src/broker_services.cc b/sandbox/src/broker_services.cc index 5ee5620..d2caa95 100644 --- a/sandbox/src/broker_services.cc +++ b/sandbox/src/broker_services.cc @@ -5,10 +5,7 @@ #include "sandbox/src/broker_services.h" #include "base/logging.h" -#include "base/memory/scoped_ptr.h" #include "base/threading/platform_thread.h" -#include "base/win/scoped_handle.h" -#include "base/win/scoped_process_information.h" #include "sandbox/src/sandbox_policy_base.h" #include "sandbox/src/sandbox.h" #include "sandbox/src/target_process.h" @@ -297,15 +294,14 @@ ResultCode BrokerServicesBase::SpawnTarget(const wchar_t* exe_path, // Construct the tokens and the job object that we are going to associate // with the soon to be created target process. - base::win::ScopedHandle lockdown_token; - base::win::ScopedHandle initial_token; - DWORD win_result = policy_base->MakeTokens(initial_token.Receive(), - lockdown_token.Receive()); + HANDLE lockdown_token = NULL; + HANDLE initial_token = NULL; + DWORD win_result = policy_base->MakeTokens(&initial_token, &lockdown_token); if (ERROR_SUCCESS != win_result) return SBOX_ERROR_GENERIC; - base::win::ScopedHandle job; - win_result = policy_base->MakeJobObject(job.Receive()); + HANDLE job = NULL; + win_result = policy_base->MakeJobObject(&job); if (ERROR_SUCCESS != win_result) return SBOX_ERROR_GENERIC; @@ -319,11 +315,9 @@ ResultCode BrokerServicesBase::SpawnTarget(const wchar_t* exe_path, // Create the TargetProces object and spawn the target suspended. Note that // Brokerservices does not own the target object. It is owned by the Policy. - base::win::ScopedProcessInformation process_info; - TargetProcess* target = new TargetProcess(initial_token.Take(), - lockdown_token.Take(), - job, - thread_pool_); + PROCESS_INFORMATION process_info = {0}; + TargetProcess* target = new TargetProcess(initial_token, lockdown_token, + job, thread_pool_); std::wstring desktop = policy_base->GetAlternateDesktop(); @@ -333,6 +327,10 @@ ResultCode BrokerServicesBase::SpawnTarget(const wchar_t* exe_path, if (ERROR_SUCCESS != win_result) return SpawnCleanup(target, win_result); + if ((INVALID_HANDLE_VALUE == process_info.hProcess) || + (INVALID_HANDLE_VALUE == process_info.hThread)) + return SpawnCleanup(target, win_result); + // Now the policy is the owner of the target. if (!policy_base->AddTarget(target)) { return SpawnCleanup(target, 0); @@ -341,15 +339,24 @@ ResultCode BrokerServicesBase::SpawnTarget(const wchar_t* exe_path, // We are going to keep a pointer to the policy because we'll call it when // the job object generates notifications using the completion port. policy_base->AddRef(); - scoped_ptr<JobTracker> tracker(new JobTracker(job.Take(), policy_base)); - if (!AssociateCompletionPort(tracker->job, job_port_, tracker.get())) + JobTracker* tracker = new JobTracker(job, policy_base); + if (!AssociateCompletionPort(job, job_port_, tracker)) return SpawnCleanup(target, 0); // Save the tracker because in cleanup we might need to force closing // the Jobs. - tracker_list_.push_back(tracker.release()); - child_process_ids_.insert(process_info.process_id()); + tracker_list_.push_back(tracker); + child_process_ids_.insert(process_info.dwProcessId); + + // We return the caller a duplicate of the process handle so they + // can close it at will. + HANDLE dup_process_handle = NULL; + if (!::DuplicateHandle(::GetCurrentProcess(), process_info.hProcess, + ::GetCurrentProcess(), &dup_process_handle, + 0, FALSE, DUPLICATE_SAME_ACCESS)) + return SpawnCleanup(target, 0); - *target_info = process_info.Take(); + *target_info = process_info; + target_info->hProcess = dup_process_handle; return SBOX_ALL_OK; } diff --git a/sandbox/src/interception_unittest.cc b/sandbox/src/interception_unittest.cc index 0dabb84..a0dd98d 100644 --- a/sandbox/src/interception_unittest.cc +++ b/sandbox/src/interception_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -79,13 +79,7 @@ TEST(InterceptionManagerTest, BufferLayout1) { wchar_t exe_name[MAX_PATH]; ASSERT_NE(0u, GetModuleFileName(NULL, exe_name, MAX_PATH - 1)); - base::win::ScopedHandle current_process; - ASSERT_TRUE( - ::DuplicateHandle(::GetCurrentProcess(), ::GetCurrentProcess(), - ::GetCurrentProcess(), current_process.Receive(), - 0, FALSE, DUPLICATE_SAME_ACCESS)); - - TargetProcess *target = MakeTestTargetProcess(current_process.Take(), + TargetProcess *target = MakeTestTargetProcess(::GetCurrentProcess(), ::GetModuleHandle(exe_name)); InterceptionManager interceptions(target, true); @@ -172,13 +166,7 @@ TEST(InterceptionManagerTest, BufferLayout2) { wchar_t exe_name[MAX_PATH]; ASSERT_NE(0u, GetModuleFileName(NULL, exe_name, MAX_PATH - 1)); - base::win::ScopedHandle current_process; - ASSERT_TRUE( - ::DuplicateHandle(::GetCurrentProcess(), ::GetCurrentProcess(), - ::GetCurrentProcess(), current_process.Receive(), - 0, FALSE, DUPLICATE_SAME_ACCESS)); - - TargetProcess *target = MakeTestTargetProcess(current_process.Take(), + TargetProcess *target = MakeTestTargetProcess(::GetCurrentProcess(), ::GetModuleHandle(exe_name)); InterceptionManager interceptions(target, true); diff --git a/sandbox/src/job_unittest.cc b/sandbox/src/job_unittest.cc index f386f1f..0f7010d 100644 --- a/sandbox/src/job_unittest.cc +++ b/sandbox/src/job_unittest.cc @@ -1,10 +1,9 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // This file contains unit tests for the job object. -#include "base/win/scoped_process_information.h" #include "sandbox/src/job.h" #include "testing/gtest/include/gtest/gtest.h" @@ -160,11 +159,11 @@ TEST(JobTest, ProcessInJob) { wchar_t notepad[] = L"notepad"; STARTUPINFO si = { sizeof(si) }; - base::win::ScopedProcessInformation pi; + PROCESS_INFORMATION pi = {0}; result = ::CreateProcess(NULL, notepad, NULL, NULL, FALSE, 0, NULL, NULL, &si, - pi.Receive()); + &pi); ASSERT_TRUE(result); - ASSERT_EQ(ERROR_SUCCESS, job.AssignProcessToJob(pi.process_handle())); + ASSERT_EQ(ERROR_SUCCESS, job.AssignProcessToJob(pi.hProcess)); // Get the job handle. HANDLE job_handle = job.Detach(); @@ -179,9 +178,9 @@ TEST(JobTest, ProcessInJob) { EXPECT_EQ(1, jbpidl.NumberOfAssignedProcesses); EXPECT_EQ(1, jbpidl.NumberOfProcessIdsInList); - EXPECT_EQ(pi.process_id(), jbpidl.ProcessIdList[0]); + EXPECT_EQ(pi.dwProcessId, jbpidl.ProcessIdList[0]); - EXPECT_TRUE(::TerminateProcess(pi.process_handle(), 0)); + EXPECT_TRUE(::TerminateProcess(pi.hProcess, 0)); EXPECT_TRUE(::CloseHandle(job_handle)); } diff --git a/sandbox/src/policy_target_test.cc b/sandbox/src/policy_target_test.cc index dd59ac8..577c8c5 100644 --- a/sandbox/src/policy_target_test.cc +++ b/sandbox/src/policy_target_test.cc @@ -1,8 +1,7 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/win/scoped_process_information.h" #include "base/win/windows_version.h" #include "sandbox/src/sandbox.h" #include "sandbox/src/sandbox_factory.h" @@ -150,9 +149,9 @@ SBOX_TESTS_COMMAND int PolicyTargetTest_process(int argc, wchar_t **argv) { // Use default values to create a new process. STARTUPINFO startup_info = {0}; startup_info.cb = sizeof(startup_info); - base::win::ScopedProcessInformation process_info; + PROCESS_INFORMATION process_info; if (!::CreateProcessW(L"foo.exe", L"foo.exe", NULL, NULL, FALSE, 0, - NULL, NULL, &startup_info, process_info.Receive())) + NULL, NULL, &startup_info, &process_info)) return SBOX_TEST_SUCCEEDED; return SBOX_TEST_FAILED; } @@ -234,31 +233,33 @@ TEST(PolicyTargetTest, DesktopPolicy) { // Launch the app. ResultCode result = SBOX_ALL_OK; - base::win::ScopedProcessInformation target; + PROCESS_INFORMATION target = {0}; TargetPolicy* policy = broker->CreatePolicy(); policy->SetAlternateDesktop(false); policy->SetTokenLevel(USER_INTERACTIVE, USER_LOCKDOWN); - result = broker->SpawnTarget( - prog_name, arguments.c_str(), policy, target.Receive()); + result = broker->SpawnTarget(prog_name, arguments.c_str(), policy, &target); policy->Release(); EXPECT_EQ(SBOX_ALL_OK, result); - EXPECT_EQ(1, ::ResumeThread(target.thread_handle())); + EXPECT_EQ(1, ::ResumeThread(target.hThread)); - EXPECT_EQ(WAIT_TIMEOUT, ::WaitForSingleObject(target.process_handle(), 2000)); + EXPECT_EQ(WAIT_TIMEOUT, ::WaitForSingleObject(target.hProcess, 2000)); - EXPECT_NE(::GetThreadDesktop(target.thread_id()), + EXPECT_NE(::GetThreadDesktop(target.dwThreadId), ::GetThreadDesktop(::GetCurrentThreadId())); std::wstring desktop_name = policy->GetAlternateDesktop(); HDESK desk = ::OpenDesktop(desktop_name.c_str(), 0, FALSE, DESKTOP_ENUMERATE); EXPECT_TRUE(NULL != desk); EXPECT_TRUE(::CloseDesktop(desk)); - EXPECT_TRUE(::TerminateProcess(target.process_handle(), 0)); + EXPECT_TRUE(::TerminateProcess(target.hProcess, 0)); - ::WaitForSingleObject(target.process_handle(), INFINITE); + ::WaitForSingleObject(target.hProcess, INFINITE); + + EXPECT_TRUE(::CloseHandle(target.hProcess)); + EXPECT_TRUE(::CloseHandle(target.hThread)); // Close the desktop handle. temp_policy = broker->CreatePolicy(); @@ -294,22 +295,21 @@ TEST(PolicyTargetTest, WinstaPolicy) { // Launch the app. ResultCode result = SBOX_ALL_OK; - base::win::ScopedProcessInformation target; + PROCESS_INFORMATION target = {0}; TargetPolicy* policy = broker->CreatePolicy(); policy->SetAlternateDesktop(true); policy->SetTokenLevel(USER_INTERACTIVE, USER_LOCKDOWN); - result = broker->SpawnTarget( - prog_name, arguments.c_str(), policy, target.Receive()); + result = broker->SpawnTarget(prog_name, arguments.c_str(), policy, &target); policy->Release(); EXPECT_EQ(SBOX_ALL_OK, result); - EXPECT_EQ(1, ::ResumeThread(target.thread_handle())); + EXPECT_EQ(1, ::ResumeThread(target.hThread)); - EXPECT_EQ(WAIT_TIMEOUT, ::WaitForSingleObject(target.process_handle(), 2000)); + EXPECT_EQ(WAIT_TIMEOUT, ::WaitForSingleObject(target.hProcess, 2000)); - EXPECT_NE(::GetThreadDesktop(target.thread_id()), + EXPECT_NE(::GetThreadDesktop(target.dwThreadId), ::GetThreadDesktop(::GetCurrentThreadId())); std::wstring desktop_name = policy->GetAlternateDesktop(); @@ -324,9 +324,12 @@ TEST(PolicyTargetTest, WinstaPolicy) { HDESK desk = ::OpenDesktop(desktop_name.c_str(), 0, FALSE, DESKTOP_ENUMERATE); // This should fail if the desktop is really on another window station. EXPECT_FALSE(NULL != desk); - EXPECT_TRUE(::TerminateProcess(target.process_handle(), 0)); + EXPECT_TRUE(::TerminateProcess(target.hProcess, 0)); + + ::WaitForSingleObject(target.hProcess, INFINITE); - ::WaitForSingleObject(target.process_handle(), INFINITE); + EXPECT_TRUE(::CloseHandle(target.hProcess)); + EXPECT_TRUE(::CloseHandle(target.hThread)); // Close the desktop handle. temp_policy = broker->CreatePolicy(); diff --git a/sandbox/src/process_policy_test.cc b/sandbox/src/process_policy_test.cc index 783446e..1bcfa88 100644 --- a/sandbox/src/process_policy_test.cc +++ b/sandbox/src/process_policy_test.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -7,7 +7,6 @@ #include "base/sys_string_conversions.h" #include "base/win/scoped_handle.h" -#include "base/win/scoped_process_information.h" #include "sandbox/src/sandbox.h" #include "sandbox/src/sandbox_policy.h" #include "sandbox/src/sandbox_factory.h" @@ -35,7 +34,7 @@ std::wstring MakeFullPathToSystem32(const wchar_t* name) { // unicode and ascii version of the api. sandbox::SboxTestResult CreateProcessHelper(const std::wstring &exe, const std::wstring &command) { - base::win::ScopedProcessInformation pi; + PROCESS_INFORMATION pi; STARTUPINFOW si = {sizeof(si)}; const wchar_t *exe_name = NULL; @@ -49,7 +48,7 @@ sandbox::SboxTestResult CreateProcessHelper(const std::wstring &exe, // Create the process with the unicode version of the API. sandbox::SboxTestResult ret1 = sandbox::SBOX_TEST_FAILED; if (!::CreateProcessW(exe_name, const_cast<wchar_t*>(cmd_line), NULL, NULL, - FALSE, 0, NULL, NULL, &si, pi.Receive())) { + FALSE, 0, NULL, NULL, &si, &pi)) { DWORD last_error = GetLastError(); if ((ERROR_NOT_ENOUGH_QUOTA == last_error) || (ERROR_ACCESS_DENIED == last_error) || @@ -62,8 +61,6 @@ sandbox::SboxTestResult CreateProcessHelper(const std::wstring &exe, ret1 = sandbox::SBOX_TEST_SUCCEEDED; } - pi.Close(); - // Do the same with the ansi version of the api STARTUPINFOA sia = {sizeof(sia)}; sandbox::SboxTestResult ret2 = sandbox::SBOX_TEST_FAILED; @@ -74,7 +71,7 @@ sandbox::SboxTestResult CreateProcessHelper(const std::wstring &exe, if (!::CreateProcessA( exe_name ? base::SysWideToMultiByte(exe_name, CP_UTF8).c_str() : NULL, cmd_line ? const_cast<char*>(narrow_cmd_line.c_str()) : NULL, - NULL, NULL, FALSE, 0, NULL, NULL, &sia, pi.Receive())) { + NULL, NULL, FALSE, 0, NULL, NULL, &sia, &pi)) { DWORD last_error = GetLastError(); if ((ERROR_NOT_ENOUGH_QUOTA == last_error) || (ERROR_ACCESS_DENIED == last_error) || @@ -173,22 +170,24 @@ SBOX_TESTS_COMMAND int Process_GetChildProcessToken(int argc, wchar_t **argv) { std::wstring path = MakeFullPathToSystem32(argv[0]); - base::win::ScopedProcessInformation pi; + PROCESS_INFORMATION pi = {0}; STARTUPINFOW si = {sizeof(si)}; if (!::CreateProcessW(path.c_str(), NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, - NULL, NULL, &si, pi.Receive())) { + NULL, NULL, &si, &pi)) { return SBOX_TEST_FAILED; } + base::win::ScopedHandle process(pi.hProcess); + base::win::ScopedHandle thread(pi.hThread); + HANDLE token = NULL; - BOOL result = - ::OpenProcessToken(pi.process_handle(), TOKEN_IMPERSONATE, &token); + BOOL result = ::OpenProcessToken(process.Get(), TOKEN_IMPERSONATE, &token); DWORD error = ::GetLastError(); base::win::ScopedHandle token_handle(token); - if (!::TerminateProcess(pi.process_handle(), 0)) + if (!::TerminateProcess(process.Get(), 0)) return SBOX_TEST_FAILED; if (result && token) diff --git a/sandbox/src/restricted_token_utils.cc b/sandbox/src/restricted_token_utils.cc index 8565f0a..ca3942e 100644 --- a/sandbox/src/restricted_token_utils.cc +++ b/sandbox/src/restricted_token_utils.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -10,7 +10,6 @@ #include "base/logging.h" #include "base/win/scoped_handle.h" -#include "base/win/scoped_process_information.h" #include "base/win/windows_version.h" #include "sandbox/src/job.h" #include "sandbox/src/restricted_token.h" @@ -183,7 +182,7 @@ DWORD StartRestrictedProcessInJob(wchar_t *command_line, // Start the process STARTUPINFO startup_info = {0}; - base::win::ScopedProcessInformation process_info; + PROCESS_INFORMATION process_info = {0}; if (!::CreateProcessAsUser(primary_token.Get(), NULL, // No application name. @@ -195,30 +194,30 @@ DWORD StartRestrictedProcessInJob(wchar_t *command_line, NULL, // Use the environment of the caller. NULL, // Use current directory of the caller. &startup_info, - process_info.Receive())) { + &process_info)) { return ::GetLastError(); } + base::win::ScopedHandle thread_handle(process_info.hThread); + base::win::ScopedHandle process_handle(process_info.hProcess); + // Change the token of the main thread of the new process for the // impersonation token with more rights. - { - HANDLE temp_thread = process_info.thread_handle(); - if (!::SetThreadToken(&temp_thread, impersonation_token.Get())) { - ::TerminateProcess(process_info.process_handle(), - 0); // exit code - return ::GetLastError(); - } + if (!::SetThreadToken(&process_info.hThread, impersonation_token.Get())) { + ::TerminateProcess(process_handle.Get(), + 0); // exit code + return ::GetLastError(); } - err_code = job.AssignProcessToJob(process_info.process_handle()); + err_code = job.AssignProcessToJob(process_handle.Get()); if (ERROR_SUCCESS != err_code) { - ::TerminateProcess(process_info.process_handle(), + ::TerminateProcess(process_handle.Get(), 0); // exit code return ::GetLastError(); } // Start the application - ::ResumeThread(process_info.thread_handle()); + ::ResumeThread(thread_handle.Get()); (*job_handle_ret) = job.Detach(); diff --git a/sandbox/src/target_process.cc b/sandbox/src/target_process.cc index fb005fa..6381777 100644 --- a/sandbox/src/target_process.cc +++ b/sandbox/src/target_process.cc @@ -15,6 +15,12 @@ namespace { +void TerminateTarget(PROCESS_INFORMATION* pi) { + ::CloseHandle(pi->hThread); + ::TerminateProcess(pi->hProcess, 0); + ::CloseHandle(pi->hProcess); +} + void CopyPolicyToTarget(const void* source, size_t size, void* dest) { if (!source || !size) return; @@ -91,8 +97,14 @@ TargetProcess::TargetProcess(HANDLE initial_token, HANDLE lockdown_token, : lockdown_token_(lockdown_token), initial_token_(initial_token), job_(job), + shared_section_(NULL), + ipc_server_(NULL), thread_pool_(thread_pool), - base_address_(NULL) { + base_address_(NULL), + exe_name_(NULL), + sandbox_process_(NULL), + sandbox_thread_(NULL), + sandbox_process_id_(0) { } TargetProcess::~TargetProcess() { @@ -105,18 +117,23 @@ TargetProcess::~TargetProcess() { // it. http://b/893891 // For now, this wait is there only to do a best effort to prevent some leaks // from showing up in purify. - ::WaitForSingleObject(sandbox_process_info_.process_handle(), 50); - if (!::GetExitCodeProcess(sandbox_process_info_.process_handle(), - &exit_code) || (STILL_ACTIVE == exit_code)) { + ::WaitForSingleObject(sandbox_process_, 50); + if (!::GetExitCodeProcess(sandbox_process_, &exit_code) || + (STILL_ACTIVE == exit_code)) { // It is an error to destroy this object while the target process is still // alive because we need to destroy the IPC subsystem and cannot risk to // have an IPC reach us after this point. return; } - // ipc_server_ references our process handle, so make sure the former is shut - // down before the latter is closed (by ScopedProcessInformation). - ipc_server_.reset(); + delete ipc_server_; + + ::CloseHandle(lockdown_token_); + ::CloseHandle(initial_token_); + ::CloseHandle(sandbox_process_); + if (shared_section_) + ::CloseHandle(shared_section_); + free(exe_name_); } // Creates the target (child) process suspended and assigns it to the job @@ -124,8 +141,8 @@ TargetProcess::~TargetProcess() { DWORD TargetProcess::Create(const wchar_t* exe_path, const wchar_t* command_line, const wchar_t* desktop, - base::win::ScopedProcessInformation* target_info) { - exe_name_.reset(_wcsdup(exe_path)); + PROCESS_INFORMATION* target_info) { + exe_name_ = _wcsdup(exe_path); // the command line needs to be writable by CreateProcess(). scoped_ptr_malloc<wchar_t> cmd_line(_wcsdup(command_line)); @@ -140,7 +157,7 @@ DWORD TargetProcess::Create(const wchar_t* exe_path, startup_info.lpDesktop = desktop_name.get(); } - base::win::ScopedProcessInformation process_info; + PROCESS_INFORMATION process_info = {0}; if (!::CreateProcessAsUserW(lockdown_token_, exe_path, @@ -152,43 +169,44 @@ DWORD TargetProcess::Create(const wchar_t* exe_path, NULL, // Use the environment of the caller. NULL, // Use current directory of the caller. &startup_info, - process_info.Receive())) { + &process_info)) { return ::GetLastError(); } - PoisonLowerAddressRange(process_info.process_handle()); + PoisonLowerAddressRange(process_info.hProcess); DWORD win_result = ERROR_SUCCESS; // Assign the suspended target to the windows job object - if (!::AssignProcessToJobObject(job_, process_info.process_handle())) { + if (!::AssignProcessToJobObject(job_, process_info.hProcess)) { win_result = ::GetLastError(); // It might be a security breach if we let the target run outside the job // so kill it before it causes damage - ::TerminateProcess(process_info.process_handle(), 0); + TerminateTarget(&process_info); return win_result; } // Change the token of the main thread of the new process for the // impersonation token with more rights. This allows the target to start; // otherwise it will crash too early for us to help. - { - HANDLE temp_thread = process_info.thread_handle(); - if (!::SetThreadToken(&temp_thread, initial_token_)) { - win_result = ::GetLastError(); - ::TerminateProcess(process_info.process_handle(), 0); - return win_result; - } + if (!SetThreadToken(&process_info.hThread, initial_token_)) { + win_result = ::GetLastError(); + TerminateTarget(&process_info); + return win_result; } CONTEXT context; context.ContextFlags = CONTEXT_ALL; - if (!::GetThreadContext(process_info.thread_handle(), &context)) { + if (!::GetThreadContext(process_info.hThread, &context)) { win_result = ::GetLastError(); - ::TerminateProcess(process_info.process_handle(), 0); + TerminateTarget(&process_info); return win_result; } + sandbox_process_ = process_info.hProcess; + sandbox_thread_ = process_info.hThread; + sandbox_process_id_ = process_info.dwProcessId; + #if defined(_WIN64) void* entry_point = reinterpret_cast<void*>(context.Rcx); #else @@ -198,26 +216,20 @@ DWORD TargetProcess::Create(const wchar_t* exe_path, void* entry_point = reinterpret_cast<void*>(context.Eax); #pragma warning(pop) #endif // _WIN64 - - if (!target_info->DuplicateFrom(process_info)) { - ::TerminateProcess(process_info.process_handle(), 0); - return ERROR_INVALID_FUNCTION; - } - base_address_ = GetBaseAddress(exe_path, entry_point); - sandbox_process_info_.Swap(&process_info); + *target_info = process_info; return win_result; } ResultCode TargetProcess::TransferVariable(const char* name, void* address, size_t size) { - if (!sandbox_process_info_.IsValid()) + if (NULL == sandbox_process_) return SBOX_ERROR_UNEXPECTED_CALL; void* child_var = address; #if SANDBOX_EXPORTS - HMODULE module = ::LoadLibrary(exe_name_.get()); + HMODULE module = ::LoadLibrary(exe_name_); if (NULL == module) return SBOX_ERROR_GENERIC; @@ -235,8 +247,8 @@ ResultCode TargetProcess::TransferVariable(const char* name, void* address, #endif SIZE_T written; - if (!::WriteProcessMemory(sandbox_process_info_.process_handle(), - child_var, address, size, &written)) + if (!::WriteProcessMemory(sandbox_process_, child_var, address, size, + &written)) return SBOX_ERROR_GENERIC; if (written != size) @@ -258,18 +270,18 @@ DWORD TargetProcess::Init(Dispatcher* ipc_dispatcher, void* policy, // We use this single memory pool for IPC and for policy. DWORD shared_mem_size = static_cast<DWORD>(shared_IPC_size + shared_policy_size); - shared_section_.Set(::CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, - PAGE_READWRITE | SEC_COMMIT, - 0, shared_mem_size, NULL)); - if (!shared_section_.IsValid()) { + shared_section_ = ::CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, + PAGE_READWRITE | SEC_COMMIT, + 0, shared_mem_size, NULL); + if (NULL == shared_section_) { return ::GetLastError(); } DWORD access = FILE_MAP_READ | FILE_MAP_WRITE; - base::win::ScopedHandle target_shared_section; + HANDLE target_shared_section = NULL; if (!::DuplicateHandle(::GetCurrentProcess(), shared_section_, - sandbox_process_info_.process_handle(), - target_shared_section.Receive(), access, FALSE, 0)) { + sandbox_process_, &target_shared_section, + access, FALSE, 0)) { return ::GetLastError(); } @@ -285,7 +297,7 @@ DWORD TargetProcess::Init(Dispatcher* ipc_dispatcher, void* policy, ResultCode ret; // Set the global variables in the target. These are not used on the broker. - g_shared_section = target_shared_section.Take(); + g_shared_section = target_shared_section; ret = TransferVariable("g_shared_section", &g_shared_section, sizeof(g_shared_section)); g_shared_section = NULL; @@ -310,31 +322,29 @@ DWORD TargetProcess::Init(Dispatcher* ipc_dispatcher, void* policy, ::GetLastError() : ERROR_INVALID_FUNCTION; } - ipc_server_.reset( - new SharedMemIPCServer(sandbox_process_info_.process_handle(), - sandbox_process_info_.process_id(), - job_, thread_pool_, ipc_dispatcher)); + ipc_server_ = new SharedMemIPCServer(sandbox_process_, sandbox_process_id_, + job_, thread_pool_, ipc_dispatcher); if (!ipc_server_->Init(shared_memory, shared_IPC_size, kIPCChannelSize)) return ERROR_NOT_ENOUGH_MEMORY; // After this point we cannot use this handle anymore. - ::CloseHandle(sandbox_process_info_.TakeThreadHandle()); + sandbox_thread_ = NULL; return ERROR_SUCCESS; } void TargetProcess::Terminate() { - if (!sandbox_process_info_.IsValid()) + if (NULL == sandbox_process_) return; - ::TerminateProcess(sandbox_process_info_.process_handle(), 0); + ::TerminateProcess(sandbox_process_, 0); } TargetProcess* MakeTestTargetProcess(HANDLE process, HMODULE base_address) { TargetProcess* target = new TargetProcess(NULL, NULL, NULL, NULL); - target->sandbox_process_info_.Receive()->hProcess = process; + target->sandbox_process_ = process; target->base_address_ = base_address; return target; } diff --git a/sandbox/src/target_process.h b/sandbox/src/target_process.h index 6e462c3..1e2ee26 100644 --- a/sandbox/src/target_process.h +++ b/sandbox/src/target_process.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -8,9 +8,6 @@ #include <windows.h> #include "base/basictypes.h" -#include "base/memory/scoped_ptr.h" -#include "base/win/scoped_handle.h" -#include "base/win/scoped_process_information.h" #include "sandbox/src/crosscall_server.h" #include "sandbox/src/sandbox_types.h" @@ -36,10 +33,8 @@ class TargetProcess { void Release() {} // Creates the new target process. The process is created suspended. - DWORD Create(const wchar_t* exe_path, - const wchar_t* command_line, - const wchar_t* desktop, - base::win::ScopedProcessInformation* target_info); + DWORD Create(const wchar_t* exe_path, const wchar_t* command_line, + const wchar_t* desktop, PROCESS_INFORMATION* target_info); // Destroys the target process. void Terminate(); @@ -51,7 +46,7 @@ class TargetProcess { // Returns the handle to the target process. HANDLE Process() const { - return sandbox_process_info_.process_handle(); + return sandbox_process_; } // Returns the handle to the job object that the target process belongs to. @@ -67,43 +62,47 @@ class TargetProcess { // Returns the name of the executable. const wchar_t* Name() const { - return exe_name_.get(); + return exe_name_; } // Returns the process id. DWORD ProcessId() const { - return sandbox_process_info_.process_id(); + return sandbox_process_id_; } // Returns the handle to the main thread. HANDLE MainThread() const { - return sandbox_process_info_.thread_handle(); + return sandbox_thread_; } // Transfers a 32-bit variable between the broker and the target. ResultCode TransferVariable(const char* name, void* address, size_t size); private: - // Details of the target process. - base::win::ScopedProcessInformation sandbox_process_info_; + // The handle to the target process. + HANDLE sandbox_process_; + // The handle to the main thread. + HANDLE sandbox_thread_; + // The process id of the target process. + DWORD sandbox_process_id_; // The token associated with the process. It provides the core of the // sbox security. - base::win::ScopedHandle lockdown_token_; + HANDLE lockdown_token_; // The token given to the initial thread so that the target process can // start. It has more powers than the lockdown_token. - base::win::ScopedHandle initial_token_; + HANDLE initial_token_; // Kernel handle to the shared memory used by the IPC server. - base::win::ScopedHandle shared_section_; + HANDLE shared_section_; // Job object containing the target process. HANDLE job_; // Reference to the IPC subsystem. - scoped_ptr<SharedMemIPCServer> ipc_server_; + SharedMemIPCServer* ipc_server_; // Provides the threads used by the IPC. This class does not own this pointer. ThreadProvider* thread_pool_; // Base address of the main executable void* base_address_; // Full name of the target executable. - scoped_ptr_malloc<wchar_t> exe_name_; + wchar_t* exe_name_; // Function used for testing. friend TargetProcess* MakeTestTargetProcess(HANDLE process, |