summaryrefslogtreecommitdiffstats
path: root/sandbox
diff options
context:
space:
mode:
authorrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-01 21:49:51 +0000
committerrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-01 21:49:51 +0000
commitf1776577dd6c3b2f0a0af0eb35b6367a6b2e77d6 (patch)
tree3f7d8aa7cb93c32a138e9e414ebba4ca0ee3218e /sandbox
parentf2aca70141a15aef16e2244c7dc93e58b914e6d0 (diff)
downloadchromium_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.cc15
-rw-r--r--sandbox/src/broker_services.cc45
-rw-r--r--sandbox/src/interception_unittest.cc18
-rw-r--r--sandbox/src/job_unittest.cc13
-rw-r--r--sandbox/src/policy_target_test.cc43
-rw-r--r--sandbox/src/process_policy_test.cc23
-rw-r--r--sandbox/src/restricted_token_utils.cc27
-rw-r--r--sandbox/src/target_process.cc110
-rw-r--r--sandbox/src/target_process.h37
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,