summaryrefslogtreecommitdiffstats
path: root/sandbox/src
diff options
context:
space:
mode:
authorjschuh@chromium.org <jschuh@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-29 15:29:56 +0000
committerjschuh@chromium.org <jschuh@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-29 15:29:56 +0000
commitf6e06204466d7ce6d33a3f5a9cf3ae2128561df7 (patch)
tree13b24c2df28443793ee04ae4cf340bbf370bf8ed /sandbox/src
parentb54b3fae08eee524456da5fdc598485e251cc8a0 (diff)
downloadchromium_src-f6e06204466d7ce6d33a3f5a9cf3ae2128561df7.zip
chromium_src-f6e06204466d7ce6d33a3f5a9cf3ae2128561df7.tar.gz
chromium_src-f6e06204466d7ce6d33a3f5a9cf3ae2128561df7.tar.bz2
Add a sandbox API for broker handle duplication
BUG=119250 Review URL: https://chromiumcodereview.appspot.com/9838083 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@129627 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sandbox/src')
-rw-r--r--sandbox/src/broker_services.cc12
-rw-r--r--sandbox/src/broker_services.h14
-rw-r--r--sandbox/src/handle_dispatcher.cc88
-rw-r--r--sandbox/src/handle_dispatcher.h37
-rw-r--r--sandbox/src/handle_interception.cc45
-rw-r--r--sandbox/src/handle_interception.h24
-rw-r--r--sandbox/src/handle_policy.cc71
-rw-r--r--sandbox/src/handle_policy.h41
-rw-r--r--sandbox/src/handle_policy_test.cc69
-rw-r--r--sandbox/src/ipc_tags.h3
-rw-r--r--sandbox/src/sandbox.h16
-rw-r--r--sandbox/src/sandbox_policy.h7
-rw-r--r--sandbox/src/sandbox_policy_base.cc15
-rw-r--r--sandbox/src/target_services.cc12
-rw-r--r--sandbox/src/target_services.h7
15 files changed, 451 insertions, 10 deletions
diff --git a/sandbox/src/broker_services.cc b/sandbox/src/broker_services.cc
index f6a0577..ff5be3a 100644
--- a/sandbox/src/broker_services.cc
+++ b/sandbox/src/broker_services.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -184,6 +184,10 @@ DWORD WINAPI BrokerServicesBase::TargetEventsThread(PVOID param) {
case JOB_OBJECT_MSG_EXIT_PROCESS:
case JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS: {
+ {
+ AutoLock lock(&broker->lock_);
+ broker->child_process_ids_.erase(reinterpret_cast<DWORD>(ovl));
+ }
--target_counter;
if (0 == target_counter)
::SetEvent(no_targets);
@@ -292,6 +296,7 @@ ResultCode BrokerServicesBase::SpawnTarget(const wchar_t* exe_path,
// Save the tracker because in cleanup we might need to force closing
// the Jobs.
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.
@@ -312,4 +317,9 @@ ResultCode BrokerServicesBase::WaitForAllTargets() {
return SBOX_ALL_OK;
}
+bool BrokerServicesBase::IsActiveTarget(DWORD process_id) {
+ AutoLock lock(&lock_);
+ return child_process_ids_.find(process_id) != child_process_ids_.end();
+}
+
} // namespace sandbox
diff --git a/sandbox/src/broker_services.h b/sandbox/src/broker_services.h
index 3e57dd2..8e4cb54 100644
--- a/sandbox/src/broker_services.h
+++ b/sandbox/src/broker_services.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -6,6 +6,7 @@
#define SANDBOX_SRC_BROKER_SERVICES_H__
#include <list>
+#include <set>
#include "base/basictypes.h"
#include "sandbox/src/crosscall_server.h"
#include "sandbox/src/job.h"
@@ -32,7 +33,7 @@ class BrokerServicesBase : public BrokerServices,
~BrokerServicesBase();
- // The next four methods are the BrokerServices interface
+ // The next five methods are the BrokerServices interface
virtual ResultCode Init();
virtual TargetPolicy* CreatePolicy();
@@ -44,6 +45,12 @@ class BrokerServicesBase : public BrokerServices,
virtual ResultCode WaitForAllTargets();
+ // Checks if the supplied process ID matches one of the broker's active
+ // target processes
+ // Returns:
+ // true if there is an active target process for this ID, otherwise false.
+ bool IsActiveTarget(DWORD process_id);
+
private:
// Helper structure that allows the Broker to associate a job notification
// with a job object and with a policy.
@@ -85,6 +92,9 @@ class BrokerServicesBase : public BrokerServices,
typedef std::list<JobTracker*> JobTrackerList;
JobTrackerList tracker_list_;
+ // Provides a fast lookup to identify sandboxed processes.
+ std::set<DWORD> child_process_ids_;
+
DISALLOW_COPY_AND_ASSIGN(BrokerServicesBase);
};
diff --git a/sandbox/src/handle_dispatcher.cc b/sandbox/src/handle_dispatcher.cc
new file mode 100644
index 0000000..921a42f
--- /dev/null
+++ b/sandbox/src/handle_dispatcher.cc
@@ -0,0 +1,88 @@
+// Copyright (c) 2012 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 "sandbox/src/handle_dispatcher.h"
+
+#include "base/win/scoped_handle.h"
+#include "sandbox/src/handle_interception.h"
+#include "sandbox/src/handle_policy.h"
+#include "sandbox/src/ipc_tags.h"
+#include "sandbox/src/policy_broker.h"
+#include "sandbox/src/policy_params.h"
+#include "sandbox/src/sandbox.h"
+#include "sandbox/src/sandbox_nt_util.h"
+#include "sandbox/src/sandbox_types.h"
+#include "sandbox/src/sandbox_utils.h"
+
+namespace sandbox {
+
+HandleDispatcher::HandleDispatcher(PolicyBase* policy_base)
+ : policy_base_(policy_base) {
+ static const IPCCall duplicate_handle_proxy = {
+ {IPC_DUPLICATEHANDLEPROXY_TAG, VOIDPTR_TYPE, ULONG_TYPE, ULONG_TYPE,
+ ULONG_TYPE},
+ reinterpret_cast<CallbackGeneric>(&HandleDispatcher::DuplicateHandleProxy)
+ };
+
+ ipc_calls_.push_back(duplicate_handle_proxy);
+}
+
+bool HandleDispatcher::SetupService(InterceptionManager* manager,
+ int service) {
+ // We perform no interceptions for handles right now.
+ switch (service) {
+ case IPC_DUPLICATEHANDLEPROXY_TAG:
+ return true;
+ }
+
+ return false;
+}
+
+bool HandleDispatcher::DuplicateHandleProxy(IPCInfo* ipc,
+ HANDLE source_handle,
+ DWORD target_process_id,
+ DWORD desired_access,
+ DWORD options) {
+ NTSTATUS error;
+ static NtQueryObject QueryObject = NULL;
+ if (!QueryObject)
+ ResolveNTFunctionPtr("NtQueryObject", &QueryObject);
+
+ // Get a copy of the handle for use in the broker process.
+ base::win::ScopedHandle handle;
+ if (!::DuplicateHandle(ipc->client_info->process, source_handle,
+ ::GetCurrentProcess(), handle.Receive(),
+ 0, FALSE, 0)) {
+ ipc->return_info.win32_result = ::GetLastError();
+ return false;
+ }
+
+ // Get the object type (32 characters is safe; current max is 14).
+ BYTE buffer[sizeof(OBJECT_TYPE_INFORMATION) + 32 * sizeof(wchar_t)];
+ OBJECT_TYPE_INFORMATION* type_info =
+ reinterpret_cast<OBJECT_TYPE_INFORMATION*>(buffer);
+ ULONG size = sizeof(buffer) - sizeof(wchar_t);
+ error = QueryObject(handle, ObjectTypeInformation, type_info, size, &size);
+ if (!NT_SUCCESS(error)) {
+ ipc->return_info.win32_result = error;
+ return false;
+ }
+ type_info->Name.Buffer[type_info->Name.Length / sizeof(wchar_t)] = L'\0';
+
+ CountedParameterSet<NameBased> params;
+ params[NameBased::NAME] = ParamPickerMake(type_info->Name.Buffer);
+
+ EvalResult eval = policy_base_->EvalPolicy(IPC_DUPLICATEHANDLEPROXY_TAG,
+ params.GetBase());
+ ipc->return_info.win32_result =
+ HandlePolicy::DuplicateHandleProxyAction(eval, *ipc->client_info,
+ source_handle,
+ target_process_id,
+ &ipc->return_info.handle,
+ desired_access, options);
+ return true;
+}
+
+} // namespace sandbox
+
diff --git a/sandbox/src/handle_dispatcher.h b/sandbox/src/handle_dispatcher.h
new file mode 100644
index 0000000..c1abc28
--- /dev/null
+++ b/sandbox/src/handle_dispatcher.h
@@ -0,0 +1,37 @@
+// Copyright (c) 2012 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.
+
+#ifndef SANDBOX_SRC_HANDLE_DISPATCHER_H_
+#define SANDBOX_SRC_HANDLE_DISPATCHER_H_
+
+#include "base/basictypes.h"
+#include "sandbox/src/crosscall_server.h"
+#include "sandbox/src/sandbox_policy_base.h"
+
+namespace sandbox {
+
+// This class handles handle-related IPC calls.
+class HandleDispatcher : public Dispatcher {
+ public:
+ explicit HandleDispatcher(PolicyBase* policy_base);
+ ~HandleDispatcher() {}
+
+ // Dispatcher interface.
+ virtual bool SetupService(InterceptionManager* manager, int service);
+
+ private:
+ // Processes IPC requests coming from calls to
+ // TargetServices::DuplicateHandle() in the target.
+ bool DuplicateHandleProxy(IPCInfo* ipc, HANDLE source_handle,
+ DWORD target_process_id, DWORD desired_access,
+ DWORD options);
+
+ PolicyBase* policy_base_;
+ DISALLOW_COPY_AND_ASSIGN(HandleDispatcher);
+};
+
+} // namespace sandbox
+
+#endif // SANDBOX_SRC_HANDLE_DISPATCHER_H_
+
diff --git a/sandbox/src/handle_interception.cc b/sandbox/src/handle_interception.cc
new file mode 100644
index 0000000..0f7b9f8
--- /dev/null
+++ b/sandbox/src/handle_interception.cc
@@ -0,0 +1,45 @@
+// Copyright (c) 2012 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 "sandbox/src/handle_interception.h"
+
+#include "sandbox/src/crosscall_client.h"
+#include "sandbox/src/ipc_tags.h"
+#include "sandbox/src/sandbox_factory.h"
+#include "sandbox/src/sandbox_nt_util.h"
+#include "sandbox/src/sharedmem_ipc_client.h"
+#include "sandbox/src/target_services.h"
+
+namespace sandbox {
+
+ResultCode DuplicateHandleProxy(HANDLE source_handle,
+ DWORD target_process_id,
+ HANDLE* target_handle,
+ DWORD desired_access,
+ DWORD options) {
+ *target_handle = NULL;
+
+ void* memory = GetGlobalIPCMemory();
+ if (NULL == memory)
+ return SBOX_ERROR_NO_SPACE;
+
+ SharedMemIPCClient ipc(memory);
+ CrossCallReturn answer = {0};
+ ResultCode code = CrossCall(ipc, IPC_DUPLICATEHANDLEPROXY_TAG,
+ source_handle, target_process_id,
+ desired_access, options, &answer);
+ if (SBOX_ALL_OK != code)
+ return code;
+
+ if (answer.win32_result) {
+ ::SetLastError(answer.nt_status);
+ return SBOX_ERROR_GENERIC;
+ }
+
+ *target_handle = answer.handle;
+ return SBOX_ALL_OK;
+}
+
+} // namespace sandbox
+
diff --git a/sandbox/src/handle_interception.h b/sandbox/src/handle_interception.h
new file mode 100644
index 0000000..543c7ba
--- /dev/null
+++ b/sandbox/src/handle_interception.h
@@ -0,0 +1,24 @@
+// Copyright (c) 2012 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 "sandbox/src/nt_internals.h"
+#include "sandbox/src/sandbox_types.h"
+
+#ifndef SANDBOX_SRC_HANDLE_INTERCEPTION_H_
+#define SANDBOX_SRC_HANDLE_INTERCEPTION_H_
+
+namespace sandbox {
+
+// TODO(jschuh) Add an interception to catch dangerous DuplicateHandle calls.
+
+ResultCode DuplicateHandleProxy(HANDLE source_handle,
+ DWORD target_process_id,
+ HANDLE* target_handle,
+ DWORD desired_access,
+ DWORD options);
+
+} // namespace sandbox
+
+#endif // SANDBOX_SRC_HANDLE_INTERCEPTION_H_
+
diff --git a/sandbox/src/handle_policy.cc b/sandbox/src/handle_policy.cc
new file mode 100644
index 0000000..ef06e32
--- /dev/null
+++ b/sandbox/src/handle_policy.cc
@@ -0,0 +1,71 @@
+// Copyright (c) 2012 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 "sandbox/src/handle_policy.h"
+
+#include <string>
+
+#include "base/win/scoped_handle.h"
+#include "sandbox/src/broker_services.h"
+#include "sandbox/src/ipc_tags.h"
+#include "sandbox/src/policy_engine_opcodes.h"
+#include "sandbox/src/policy_params.h"
+#include "sandbox/src/sandbox_types.h"
+#include "sandbox/src/sandbox_utils.h"
+
+namespace sandbox {
+
+bool HandlePolicy::GenerateRules(const wchar_t* type_name,
+ TargetPolicy::Semantics semantics,
+ LowLevelPolicy* policy) {
+ // We don't support any other semantics for handles yet.
+ if (TargetPolicy::HANDLES_DUP_ANY != semantics) {
+ return false;
+ }
+ PolicyRule duplicate_rule(ASK_BROKER);
+ if (!duplicate_rule.AddStringMatch(IF, NameBased::NAME, type_name,
+ CASE_INSENSITIVE)) {
+ return false;
+ }
+ if (!policy->AddRule(IPC_DUPLICATEHANDLEPROXY_TAG, &duplicate_rule)) {
+ return false;
+ }
+ return true;
+}
+
+DWORD HandlePolicy::DuplicateHandleProxyAction(EvalResult eval_result,
+ const ClientInfo& client_info,
+ HANDLE source_handle,
+ DWORD target_process_id,
+ HANDLE* target_handle,
+ DWORD desired_access,
+ DWORD options) {
+ // The only action supported is ASK_BROKER which means duplicate the handle.
+ if (ASK_BROKER != eval_result) {
+ return ERROR_ACCESS_DENIED;
+ }
+
+ // Make sure the target is one of our sandboxed children.
+ if (!BrokerServicesBase::GetInstance()->IsActiveTarget(target_process_id)) {
+ return ERROR_ACCESS_DENIED;
+ }
+
+ base::win::ScopedHandle target_process(::OpenProcess(PROCESS_DUP_HANDLE,
+ FALSE,
+ target_process_id));
+ if (NULL == target_process)
+ return ::GetLastError();
+
+ DWORD result = ERROR_SUCCESS;
+ if (!::DuplicateHandle(client_info.process, source_handle, target_process,
+ target_handle, desired_access, FALSE,
+ options)) {
+ return ::GetLastError();
+ }
+
+ return ERROR_SUCCESS;
+}
+
+} // namespace sandbox
+
diff --git a/sandbox/src/handle_policy.h b/sandbox/src/handle_policy.h
new file mode 100644
index 0000000..c3b7156
--- /dev/null
+++ b/sandbox/src/handle_policy.h
@@ -0,0 +1,41 @@
+// Copyright (c) 2012 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.
+
+#ifndef SANDBOX_SRC_HANDLE_POLICY_H_
+#define SANDBOX_SRC_HANDLE_POLICY_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "sandbox/src/crosscall_server.h"
+#include "sandbox/src/policy_low_level.h"
+#include "sandbox/src/sandbox_policy.h"
+
+namespace sandbox {
+
+enum EvalResult;
+
+// This class centralizes most of the knowledge related to handle policy.
+class HandlePolicy {
+ public:
+ // Creates the required low-level policy rules to evaluate a high-level
+ // policy rule for handles, in particular duplicate action.
+ static bool GenerateRules(const wchar_t* type_name,
+ TargetPolicy::Semantics semantics,
+ LowLevelPolicy* policy);
+
+ // Processes a 'TargetPolicy::DuplicateHandle()' request from the target.
+ static DWORD DuplicateHandleProxyAction(EvalResult eval_result,
+ const ClientInfo& client_info,
+ HANDLE source_handle,
+ DWORD target_process_id,
+ HANDLE* target_handle,
+ DWORD desired_access,
+ DWORD options);
+};
+
+} // namespace sandbox
+
+#endif // SANDBOX_SRC_HANDLE_POLICY_H_
+
diff --git a/sandbox/src/handle_policy_test.cc b/sandbox/src/handle_policy_test.cc
new file mode 100644
index 0000000..bccca67
--- /dev/null
+++ b/sandbox/src/handle_policy_test.cc
@@ -0,0 +1,69 @@
+// Copyright (c) 2012 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/stringprintf.h"
+#include "sandbox/src/handle_policy.h"
+#include "sandbox/src/nt_internals.h"
+#include "sandbox/src/sandbox.h"
+#include "sandbox/src/sandbox_factory.h"
+#include "sandbox/src/sandbox_policy.h"
+#include "sandbox/src/win_utils.h"
+#include "sandbox/tests/common/controller.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace sandbox {
+
+// Just waits for the supplied number of milliseconds.
+SBOX_TESTS_COMMAND int Handle_WaitProcess(int argc, wchar_t **argv) {
+ if (argc != 1)
+ return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
+
+ ::Sleep(::wcstoul(argv[0], NULL, 10));
+ return SBOX_TEST_TIMED_OUT;
+}
+
+// Attempts to duplicate an event handle into the target process.
+SBOX_TESTS_COMMAND int Handle_DuplicateEvent(int argc, wchar_t **argv) {
+ if (argc != 1)
+ return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
+
+ // Create a test event to use as a handle.
+ base::win::ScopedHandle test_event;
+ test_event.Set(::CreateEvent(NULL, TRUE, TRUE, NULL));
+ if (!test_event.IsValid())
+ return SBOX_TEST_FIRST_ERROR;
+
+ // Get the target process ID.
+ DWORD target_process_id = ::wcstoul(argv[0], NULL, 10);
+
+ HANDLE handle = NULL;
+ ResultCode result = SandboxFactory::GetTargetServices()->DuplicateHandle(
+ test_event, target_process_id, &handle, 0, DUPLICATE_SAME_ACCESS);
+
+ return (result == SBOX_ALL_OK) ? SBOX_TEST_SUCCEEDED : SBOX_TEST_DENIED;
+}
+
+// Tests that duplicating an object works only when the policy allows it.
+TEST(HandlePolicyTest, DuplicateHandle) {
+ TestRunner target;
+ TestRunner runner;
+
+ // Kick off an asynchronous target process for testing.
+ target.SetAsynchronous(true);
+ EXPECT_EQ(SBOX_TEST_SUCCEEDED, target.RunTest(L"Handle_WaitProcess 30000"));
+
+ // First test that we fail to open the event.
+ std::wstring cmd_line = base::StringPrintf(L"Handle_DuplicateEvent %d",
+ target.process_id());
+ EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(cmd_line.c_str()));
+
+ // Now successfully open the event after adding a duplicate handle rule.
+ EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_HANDLES,
+ TargetPolicy::HANDLES_DUP_ANY,
+ L"Event"));
+ EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(cmd_line.c_str()));
+}
+
+} // namespace sandbox
+
diff --git a/sandbox/src/ipc_tags.h b/sandbox/src/ipc_tags.h
index 397a529f..4e3a806 100644
--- a/sandbox/src/ipc_tags.h
+++ b/sandbox/src/ipc_tags.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -28,6 +28,7 @@ enum {
IPC_OPENEVENT_TAG,
IPC_NTCREATEKEY_TAG,
IPC_NTOPENKEY_TAG,
+ IPC_DUPLICATEHANDLEPROXY_TAG,
IPC_LAST_TAG
};
diff --git a/sandbox/src/sandbox.h b/sandbox/src/sandbox.h
index bbc4f77..683bda7 100644
--- a/sandbox/src/sandbox.h
+++ b/sandbox/src/sandbox.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -126,6 +126,20 @@ class TargetServices {
// information about the current state of the process, such as whether
// LowerToken has been called or not.
virtual ProcessState* GetState() = 0;
+
+ // Requests the broker to duplicate the supplied handle into the target
+ // process. The target process must be an active sandbox child process
+ // and the source process must have a corresponding policy allowing
+ // handle duplication for this object type.
+ // Returns:
+ // ALL_OK if successful. All other return values imply failure.
+ // If the return is ERROR_GENERIC, you can call ::GetLastError() to get
+ // more information.
+ virtual ResultCode DuplicateHandle(HANDLE source_handle,
+ DWORD target_process_id,
+ HANDLE* target_handle,
+ DWORD desired_access,
+ DWORD options) = 0;
};
} // namespace sandbox
diff --git a/sandbox/src/sandbox_policy.h b/sandbox/src/sandbox_policy.h
index 4f21158..1f561f5 100644
--- a/sandbox/src/sandbox_policy.h
+++ b/sandbox/src/sandbox_policy.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -128,7 +128,8 @@ class TargetPolicy {
SUBSYS_NAMED_PIPES, // Creation of named pipes.
SUBSYS_PROCESS, // Creation of child processes.
SUBSYS_REGISTRY, // Creation and opening of registry keys.
- SUBSYS_SYNC // Creation of named sync objects.
+ SUBSYS_SYNC, // Creation of named sync objects.
+ SUBSYS_HANDLES // Duplication of handles to other processes.
};
// Allowable semantics when a rule is matched.
@@ -139,6 +140,8 @@ class TargetPolicy {
FILES_ALLOW_QUERY, // Allows access to query the attributes of a file.
FILES_ALLOW_DIR_ANY, // Allows open or create with directory semantics
// only.
+ HANDLES_DUP_ANY, // Allows duplicating handles opened with any
+ // access permissions.
NAMEDPIPES_ALLOW_ANY, // Allows creation of a named pipe.
PROCESS_MIN_EXEC, // Allows to create a process with minimal rights
// over the resulting process and thread handles.
diff --git a/sandbox/src/sandbox_policy_base.cc b/sandbox/src/sandbox_policy_base.cc
index e65f648..587d59d 100644
--- a/sandbox/src/sandbox_policy_base.cc
+++ b/sandbox/src/sandbox_policy_base.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -9,6 +9,8 @@
#include "base/logging.h"
#include "sandbox/src/filesystem_dispatcher.h"
#include "sandbox/src/filesystem_policy.h"
+#include "sandbox/src/handle_dispatcher.h"
+#include "sandbox/src/handle_policy.h"
#include "sandbox/src/job.h"
#include "sandbox/src/interception.h"
#include "sandbox/src/named_pipe_dispatcher.h"
@@ -96,6 +98,9 @@ PolicyBase::PolicyBase()
dispatcher = new RegistryDispatcher(this);
ipc_targets_[IPC_NTCREATEKEY_TAG] = dispatcher;
ipc_targets_[IPC_NTOPENKEY_TAG] = dispatcher;
+
+ dispatcher = new HandleDispatcher(this);
+ ipc_targets_[IPC_DUPLICATEHANDLEPROXY_TAG] = dispatcher;
}
PolicyBase::~PolicyBase() {
@@ -109,6 +114,7 @@ PolicyBase::~PolicyBase() {
delete ipc_targets_[IPC_NTOPENTHREAD_TAG];
delete ipc_targets_[IPC_CREATEEVENT_TAG];
delete ipc_targets_[IPC_NTCREATEKEY_TAG];
+ delete ipc_targets_[IPC_DUPLICATEHANDLEPROXY_TAG];
delete policy_maker_;
delete policy_;
::DeleteCriticalSection(&lock_);
@@ -320,6 +326,13 @@ ResultCode PolicyBase::AddRule(SubSystem subsystem, Semantics semantics,
}
break;
}
+ case SUBSYS_HANDLES: {
+ if (!HandlePolicy::GenerateRules(pattern, semantics, policy_maker_)) {
+ NOTREACHED();
+ return SBOX_ERROR_BAD_PARAMS;
+ }
+ break;
+ }
default: {
return SBOX_ERROR_UNSUPPORTED;
}
diff --git a/sandbox/src/target_services.cc b/sandbox/src/target_services.cc
index 9b91a1c..e13a3d6 100644
--- a/sandbox/src/target_services.cc
+++ b/sandbox/src/target_services.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -9,6 +9,7 @@
#include "base/basictypes.h"
#include "sandbox/src/crosscall_client.h"
#include "sandbox/src/handle_closer_agent.h"
+#include "sandbox/src/handle_interception.h"
#include "sandbox/src/ipc_tags.h"
#include "sandbox/src/restricted_token_utils.h"
#include "sandbox/src/sandbox.h"
@@ -175,4 +176,13 @@ void ProcessState::SetRevertedToSelf() {
process_state_ = 3;
}
+ResultCode TargetServicesBase::DuplicateHandle(HANDLE source_handle,
+ DWORD target_process_id,
+ HANDLE* target_handle,
+ DWORD desired_access,
+ DWORD options) {
+ return sandbox::DuplicateHandleProxy(source_handle, target_process_id,
+ target_handle, desired_access, options);
+}
+
} // namespace sandbox
diff --git a/sandbox/src/target_services.h b/sandbox/src/target_services.h
index 7099098..c4bf4f6 100644
--- a/sandbox/src/target_services.h
+++ b/sandbox/src/target_services.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -46,6 +46,11 @@ class TargetServicesBase : public TargetServices {
virtual ResultCode Init();
virtual void LowerToken();
virtual ProcessState* GetState();
+ virtual ResultCode DuplicateHandle(HANDLE source_handle,
+ DWORD target_process_id,
+ HANDLE* target_handle,
+ DWORD desired_access,
+ DWORD options);
// Factory method.
static TargetServicesBase* GetInstance();