summaryrefslogtreecommitdiffstats
path: root/security/sandbox/chromium-shim/patches/with_update/revert_remove_BrokerDuplicateHandle.patch
diff options
context:
space:
mode:
Diffstat (limited to 'security/sandbox/chromium-shim/patches/with_update/revert_remove_BrokerDuplicateHandle.patch')
-rw-r--r--security/sandbox/chromium-shim/patches/with_update/revert_remove_BrokerDuplicateHandle.patch743
1 files changed, 0 insertions, 743 deletions
diff --git a/security/sandbox/chromium-shim/patches/with_update/revert_remove_BrokerDuplicateHandle.patch b/security/sandbox/chromium-shim/patches/with_update/revert_remove_BrokerDuplicateHandle.patch
deleted file mode 100644
index 970c0d1db2..0000000000
--- a/security/sandbox/chromium-shim/patches/with_update/revert_remove_BrokerDuplicateHandle.patch
+++ /dev/null
@@ -1,743 +0,0 @@
-# HG changeset patch
-# User Toshihito Kikuchi <tkikuchi@mozilla.com>
-# Date 1589671733 25200
-# Sat May 16 16:28:53 2020 -0700
-# Node ID 91bb5c3807cfe657cc24c9a3c217dd1f57db6d5c
-# Parent 22eb0bf7180801edf775be44cf299a50e01eb7bf
-Reinstate sandbox::TargetServices::BrokerDuplicateHandle. r=bobowen
-
-This patch reverts the commit removing sandbox::TargetServices::BrokerDuplicateHandle
-and applies the new IpcTag type.
-
-https://chromium.googlesource.com/chromium/src.git/+/569193665184525ca366e65d0735f5c851106e43
-https://chromium.googlesource.com/chromium/src.git/+/c8cff7f9663ce6d1ef35e5c717f43c867c3906eb
-
-diff --git a/security/sandbox/chromium/sandbox/win/src/handle_dispatcher.cc b/security/sandbox/chromium/sandbox/win/src/handle_dispatcher.cc
-new file mode 100644
---- /dev/null
-+++ b/security/sandbox/chromium/sandbox/win/src/handle_dispatcher.cc
-@@ -0,0 +1,93 @@
-+// 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/win/src/handle_dispatcher.h"
-+
-+#include <stdint.h>
-+
-+#include "base/win/scoped_handle.h"
-+#include "sandbox/win/src/handle_interception.h"
-+#include "sandbox/win/src/handle_policy.h"
-+#include "sandbox/win/src/ipc_tags.h"
-+#include "sandbox/win/src/policy_broker.h"
-+#include "sandbox/win/src/policy_params.h"
-+#include "sandbox/win/src/sandbox.h"
-+#include "sandbox/win/src/sandbox_nt_util.h"
-+#include "sandbox/win/src/sandbox_types.h"
-+#include "sandbox/win/src/sandbox_utils.h"
-+
-+namespace sandbox {
-+
-+HandleDispatcher::HandleDispatcher(PolicyBase* policy_base)
-+ : policy_base_(policy_base) {
-+ static const IPCCall duplicate_handle_proxy = {
-+ {IpcTag::DUPLICATEHANDLEPROXY,
-+ {VOIDPTR_TYPE, UINT32_TYPE, UINT32_TYPE, UINT32_TYPE}},
-+ reinterpret_cast<CallbackGeneric>(
-+ &HandleDispatcher::DuplicateHandleProxy)};
-+
-+ ipc_calls_.push_back(duplicate_handle_proxy);
-+}
-+
-+bool HandleDispatcher::SetupService(InterceptionManager* manager,
-+ IpcTag service) {
-+ // We perform no interceptions for handles right now.
-+ switch (service) {
-+ case IpcTag::DUPLICATEHANDLEPROXY:
-+ return true;
-+
-+ default:
-+ return false;
-+ }
-+}
-+
-+bool HandleDispatcher::DuplicateHandleProxy(IPCInfo* ipc,
-+ HANDLE source_handle,
-+ uint32_t target_process_id,
-+ uint32_t desired_access,
-+ uint32_t options) {
-+ static NtQueryObject QueryObject = NULL;
-+ if (!QueryObject)
-+ ResolveNTFunctionPtr("NtQueryObject", &QueryObject);
-+
-+ // Get a copy of the handle for use in the broker process.
-+ HANDLE handle_temp;
-+ if (!::DuplicateHandle(ipc->client_info->process, source_handle,
-+ ::GetCurrentProcess(), &handle_temp,
-+ 0, FALSE, DUPLICATE_SAME_ACCESS | options)) {
-+ ipc->return_info.win32_result = ::GetLastError();
-+ return false;
-+ }
-+ options &= ~DUPLICATE_CLOSE_SOURCE;
-+ base::win::ScopedHandle handle(handle_temp);
-+
-+ // 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);
-+ NTSTATUS error =
-+ QueryObject(handle.Get(), ObjectTypeInformation, type_info, size, &size);
-+ if (!NT_SUCCESS(error)) {
-+ ipc->return_info.nt_status = error;
-+ return false;
-+ }
-+ type_info->Name.Buffer[type_info->Name.Length / sizeof(wchar_t)] = L'\0';
-+
-+ CountedParameterSet<HandleTarget> params;
-+ params[HandleTarget::NAME] = ParamPickerMake(type_info->Name.Buffer);
-+ params[HandleTarget::TARGET] = ParamPickerMake(target_process_id);
-+
-+ EvalResult eval = policy_base_->EvalPolicy(IpcTag::DUPLICATEHANDLEPROXY,
-+ params.GetBase());
-+ ipc->return_info.win32_result =
-+ HandlePolicy::DuplicateHandleProxyAction(eval, handle.Get(),
-+ target_process_id,
-+ &ipc->return_info.handle,
-+ desired_access, options);
-+ return true;
-+}
-+
-+} // namespace sandbox
-+
-diff --git a/security/sandbox/chromium/sandbox/win/src/handle_dispatcher.h b/security/sandbox/chromium/sandbox/win/src/handle_dispatcher.h
-new file mode 100644
---- /dev/null
-+++ b/security/sandbox/chromium/sandbox/win/src/handle_dispatcher.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_DISPATCHER_H_
-+#define SANDBOX_SRC_HANDLE_DISPATCHER_H_
-+
-+#include <stdint.h>
-+
-+#include "base/macros.h"
-+#include "sandbox/win/src/crosscall_server.h"
-+#include "sandbox/win/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() override {}
-+
-+ // Dispatcher interface.
-+ bool SetupService(InterceptionManager* manager, IpcTag service) override;
-+
-+ private:
-+ // Processes IPC requests coming from calls to
-+ // TargetServices::DuplicateHandle() in the target.
-+ bool DuplicateHandleProxy(IPCInfo* ipc,
-+ HANDLE source_handle,
-+ uint32_t target_process_id,
-+ uint32_t desired_access,
-+ uint32_t options);
-+
-+ PolicyBase* policy_base_;
-+ DISALLOW_COPY_AND_ASSIGN(HandleDispatcher);
-+};
-+
-+} // namespace sandbox
-+
-+#endif // SANDBOX_SRC_HANDLE_DISPATCHER_H_
-+
-diff --git a/security/sandbox/chromium/sandbox/win/src/handle_interception.cc b/security/sandbox/chromium/sandbox/win/src/handle_interception.cc
-new file mode 100644
---- /dev/null
-+++ b/security/sandbox/chromium/sandbox/win/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/win/src/handle_interception.h"
-+
-+#include "sandbox/win/src/crosscall_client.h"
-+#include "sandbox/win/src/ipc_tags.h"
-+#include "sandbox/win/src/sandbox_factory.h"
-+#include "sandbox/win/src/sandbox_nt_util.h"
-+#include "sandbox/win/src/sharedmem_ipc_client.h"
-+#include "sandbox/win/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, IpcTag::DUPLICATEHANDLEPROXY,
-+ source_handle, target_process_id,
-+ desired_access, options, &answer);
-+ if (SBOX_ALL_OK != code)
-+ return code;
-+
-+ if (answer.win32_result) {
-+ ::SetLastError(answer.win32_result);
-+ return SBOX_ERROR_GENERIC;
-+ }
-+
-+ *target_handle = answer.handle;
-+ return SBOX_ALL_OK;
-+}
-+
-+} // namespace sandbox
-+
-diff --git a/security/sandbox/chromium/sandbox/win/src/handle_interception.h b/security/sandbox/chromium/sandbox/win/src/handle_interception.h
-new file mode 100644
---- /dev/null
-+++ b/security/sandbox/chromium/sandbox/win/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/win/src/nt_internals.h"
-+#include "sandbox/win/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/security/sandbox/chromium/sandbox/win/src/handle_policy.cc b/security/sandbox/chromium/sandbox/win/src/handle_policy.cc
-new file mode 100644
---- /dev/null
-+++ b/security/sandbox/chromium/sandbox/win/src/handle_policy.cc
-@@ -0,0 +1,93 @@
-+// 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/win/src/handle_policy.h"
-+
-+#include <string>
-+
-+#include "base/win/scoped_handle.h"
-+#include "sandbox/win/src/broker_services.h"
-+#include "sandbox/win/src/ipc_tags.h"
-+#include "sandbox/win/src/policy_engine_opcodes.h"
-+#include "sandbox/win/src/policy_params.h"
-+#include "sandbox/win/src/sandbox_types.h"
-+#include "sandbox/win/src/sandbox_utils.h"
-+
-+namespace sandbox {
-+
-+bool HandlePolicy::GenerateRules(const wchar_t* type_name,
-+ TargetPolicy::Semantics semantics,
-+ LowLevelPolicy* policy) {
-+ PolicyRule duplicate_rule(ASK_BROKER);
-+
-+ switch (semantics) {
-+ case TargetPolicy::HANDLES_DUP_ANY: {
-+ if (!duplicate_rule.AddNumberMatch(IF_NOT, HandleTarget::TARGET,
-+ ::GetCurrentProcessId(), EQUAL)) {
-+ return false;
-+ }
-+ break;
-+ }
-+
-+ case TargetPolicy::HANDLES_DUP_BROKER: {
-+ if (!duplicate_rule.AddNumberMatch(IF, HandleTarget::TARGET,
-+ ::GetCurrentProcessId(), EQUAL)) {
-+ return false;
-+ }
-+ break;
-+ }
-+
-+ default:
-+ return false;
-+ }
-+ if (!duplicate_rule.AddStringMatch(IF, HandleTarget::NAME, type_name,
-+ CASE_INSENSITIVE)) {
-+ return false;
-+ }
-+ if (!policy->AddRule(IpcTag::DUPLICATEHANDLEPROXY, &duplicate_rule)) {
-+ return false;
-+ }
-+ return true;
-+}
-+
-+DWORD HandlePolicy::DuplicateHandleProxyAction(EvalResult eval_result,
-+ 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;
-+ }
-+
-+ base::win::ScopedHandle remote_target_process;
-+ if (target_process_id != ::GetCurrentProcessId()) {
-+ // Sandboxed children are dynamic, so we check that manually.
-+ if (!BrokerServicesBase::GetInstance()->IsSafeDuplicationTarget(
-+ target_process_id)) {
-+ return ERROR_ACCESS_DENIED;
-+ }
-+
-+ remote_target_process.Set(::OpenProcess(PROCESS_DUP_HANDLE, FALSE,
-+ target_process_id));
-+ if (!remote_target_process.IsValid())
-+ return ::GetLastError();
-+ }
-+
-+ // If the policy didn't block us and we have no valid target, then the broker
-+ // (this process) is the valid target.
-+ HANDLE target_process = remote_target_process.IsValid() ?
-+ remote_target_process.Get() : ::GetCurrentProcess();
-+ if (!::DuplicateHandle(::GetCurrentProcess(), source_handle, target_process,
-+ target_handle, desired_access, FALSE,
-+ options)) {
-+ return ::GetLastError();
-+ }
-+
-+ return ERROR_SUCCESS;
-+}
-+
-+} // namespace sandbox
-+
-diff --git a/security/sandbox/chromium/sandbox/win/src/handle_policy.h b/security/sandbox/chromium/sandbox/win/src/handle_policy.h
-new file mode 100644
---- /dev/null
-+++ b/security/sandbox/chromium/sandbox/win/src/handle_policy.h
-@@ -0,0 +1,39 @@
-+// 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 "sandbox/win/src/crosscall_server.h"
-+#include "sandbox/win/src/policy_low_level.h"
-+#include "sandbox/win/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,
-+ 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/security/sandbox/chromium/sandbox/win/src/handle_policy_test.cc b/security/sandbox/chromium/sandbox/win/src/handle_policy_test.cc
-new file mode 100644
---- /dev/null
-+++ b/security/sandbox/chromium/sandbox/win/src/handle_policy_test.cc
-@@ -0,0 +1,114 @@
-+// 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/strings/stringprintf.h"
-+#include "sandbox/win/src/handle_policy.h"
-+#include "sandbox/win/src/nt_internals.h"
-+#include "sandbox/win/src/sandbox.h"
-+#include "sandbox/win/src/sandbox_factory.h"
-+#include "sandbox/win/src/sandbox_policy.h"
-+#include "sandbox/win/src/win_utils.h"
-+#include "sandbox/win/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.Get(), 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.
-+ base::string16 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()));
-+}
-+
-+// Tests that duplicating an object works only when the policy allows it.
-+TEST(HandlePolicyTest, DuplicatePeerHandle) {
-+ TestRunner target;
-+ TestRunner runner;
-+
-+ // Kick off an asynchronous target process for testing.
-+ target.SetAsynchronous(true);
-+ target.SetUnsandboxed(true);
-+ EXPECT_EQ(SBOX_TEST_SUCCEEDED, target.RunTest(L"Handle_WaitProcess 30000"));
-+
-+ // First test that we fail to open the event.
-+ base::string16 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()));
-+}
-+
-+// Tests that duplicating an object works only when the policy allows it.
-+TEST(HandlePolicyTest, DuplicateBrokerHandle) {
-+ TestRunner runner;
-+
-+ // First test that we fail to open the event.
-+ base::string16 cmd_line = base::StringPrintf(L"Handle_DuplicateEvent %d",
-+ ::GetCurrentProcessId());
-+ EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(cmd_line.c_str()));
-+
-+ // Add the peer rule and make sure we fail again.
-+ EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_HANDLES,
-+ TargetPolicy::HANDLES_DUP_ANY,
-+ L"Event"));
-+ EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(cmd_line.c_str()));
-+
-+
-+ // Now successfully open the event after adding a broker handle rule.
-+ EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_HANDLES,
-+ TargetPolicy::HANDLES_DUP_BROKER,
-+ L"Event"));
-+ EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(cmd_line.c_str()));
-+}
-+
-+} // namespace sandbox
-+
-diff --git a/security/sandbox/chromium/sandbox/win/src/ipc_tags.h b/security/sandbox/chromium/sandbox/win/src/ipc_tags.h
---- a/security/sandbox/chromium/sandbox/win/src/ipc_tags.h
-+++ b/security/sandbox/chromium/sandbox/win/src/ipc_tags.h
-@@ -23,16 +23,17 @@ enum class IpcTag {
- NTOPENPROCESS,
- NTOPENPROCESSTOKEN,
- NTOPENPROCESSTOKENEX,
- CREATEPROCESSW,
- CREATEEVENT,
- OPENEVENT,
- NTCREATEKEY,
- NTOPENKEY,
-+ DUPLICATEHANDLEPROXY,
- GDI_GDIDLLINITIALIZE,
- GDI_GETSTOCKOBJECT,
- USER_REGISTERCLASSW,
- CREATETHREAD,
- USER_ENUMDISPLAYMONITORS,
- USER_ENUMDISPLAYDEVICES,
- USER_GETMONITORINFO,
- GDI_CREATEOPMPROTECTEDOUTPUTS,
-diff --git a/security/sandbox/chromium/sandbox/win/src/sandbox.h b/security/sandbox/chromium/sandbox/win/src/sandbox.h
---- a/security/sandbox/chromium/sandbox/win/src/sandbox.h
-+++ b/security/sandbox/chromium/sandbox/win/src/sandbox.h
-@@ -161,16 +161,30 @@ class TargetServices {
- // fails the current process could be terminated immediately.
- virtual void LowerToken() = 0;
-
- // Returns the ProcessState object. Through that object it's possible to have
- // 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;
-+
- protected:
- ~TargetServices() {}
- };
-
- class PolicyInfo {
- public:
- // Returns a JSON representation of the policy snapshot.
- // This pointer has the same lifetime as this PolicyInfo object.
-diff --git a/security/sandbox/chromium/sandbox/win/src/sandbox_policy.h b/security/sandbox/chromium/sandbox/win/src/sandbox_policy.h
---- a/security/sandbox/chromium/sandbox/win/src/sandbox_policy.h
-+++ b/security/sandbox/chromium/sandbox/win/src/sandbox_policy.h
-@@ -25,28 +25,32 @@ class TargetPolicy {
- // exactly like the CreateProcess API does. See the comment at the top of
- // process_thread_dispatcher.cc for more details.
- enum SubSystem {
- SUBSYS_FILES, // Creation and opening of files and pipes.
- 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_HANDLES, // Duplication of handles to other processes.
- SUBSYS_WIN32K_LOCKDOWN, // Win32K Lockdown related policy.
- SUBSYS_SIGNED_BINARY // Signed binary policy.
- };
-
- // Allowable semantics when a rule is matched.
- enum Semantics {
- FILES_ALLOW_ANY, // Allows open or create for any kind of access that
- // the file system supports.
- FILES_ALLOW_READONLY, // Allows open or create with read access only.
- 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.
-+ HANDLES_DUP_BROKER, // Allows duplicating handles to the broker process.
- 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.
- // No other parameters besides the command line are
- // passed to the child process.
- PROCESS_ALL_EXEC, // Allows the creation of a process and return full
- // access on the returned handles.
- // This flag can be used only when the main token of
-diff --git a/security/sandbox/chromium/sandbox/win/src/sandbox_policy_base.cc b/security/sandbox/chromium/sandbox/win/src/sandbox_policy_base.cc
---- a/security/sandbox/chromium/sandbox/win/src/sandbox_policy_base.cc
-+++ b/security/sandbox/chromium/sandbox/win/src/sandbox_policy_base.cc
-@@ -12,16 +12,17 @@
- #include "base/logging.h"
- #include "base/macros.h"
- #include "base/stl_util.h"
- #include "base/strings/stringprintf.h"
- #include "base/win/win_util.h"
- #include "base/win/windows_version.h"
- #include "sandbox/win/src/acl.h"
- #include "sandbox/win/src/filesystem_policy.h"
-+#include "sandbox/win/src/handle_policy.h"
- #include "sandbox/win/src/interception.h"
- #include "sandbox/win/src/job.h"
- #include "sandbox/win/src/named_pipe_policy.h"
- #include "sandbox/win/src/policy_broker.h"
- #include "sandbox/win/src/policy_engine_processor.h"
- #include "sandbox/win/src/policy_low_level.h"
- #include "sandbox/win/src/process_mitigations.h"
- #include "sandbox/win/src/process_mitigations_win32k_policy.h"
-@@ -754,16 +755,24 @@ ResultCode PolicyBase::AddRuleInternal(S
- }
- case SUBSYS_REGISTRY: {
- if (!RegistryPolicy::GenerateRules(pattern, semantics, policy_maker_)) {
- NOTREACHED();
- return SBOX_ERROR_BAD_PARAMS;
- }
- break;
- }
-+ case SUBSYS_HANDLES: {
-+ if (!HandlePolicy::GenerateRules(pattern, semantics, policy_maker_)) {
-+ NOTREACHED();
-+ return SBOX_ERROR_BAD_PARAMS;
-+ }
-+ break;
-+ }
-+
- case SUBSYS_WIN32K_LOCKDOWN: {
- // Win32k intercept rules only supported on Windows 8 and above. This must
- // match the version checks in process_mitigations.cc for consistency.
- if (base::win::GetVersion() >= base::win::Version::WIN8) {
- DCHECK_EQ(MITIGATION_WIN32K_DISABLE,
- mitigations_ & MITIGATION_WIN32K_DISABLE)
- << "Enable MITIGATION_WIN32K_DISABLE before adding win32k policy "
- "rules.";
-diff --git a/security/sandbox/chromium/sandbox/win/src/target_services.cc b/security/sandbox/chromium/sandbox/win/src/target_services.cc
---- a/security/sandbox/chromium/sandbox/win/src/target_services.cc
-+++ b/security/sandbox/chromium/sandbox/win/src/target_services.cc
-@@ -7,16 +7,17 @@
- #include <new>
-
- #include <process.h>
- #include <stdint.h>
-
- #include "base/win/windows_version.h"
- #include "sandbox/win/src/crosscall_client.h"
- #include "sandbox/win/src/handle_closer_agent.h"
-+#include "sandbox/win/src/handle_interception.h"
- #include "sandbox/win/src/heap_helper.h"
- #include "sandbox/win/src/ipc_tags.h"
- #include "sandbox/win/src/process_mitigations.h"
- #include "sandbox/win/src/restricted_token_utils.h"
- #include "sandbox/win/src/sandbox.h"
- #include "sandbox/win/src/sandbox_nt_util.h"
- #include "sandbox/win/src/sandbox_types.h"
- #include "sandbox/win/src/sharedmem_ipc_client.h"
-@@ -239,9 +240,19 @@ void ProcessState::SetRevertedToSelf() {
- if (process_state_ < ProcessStateInternal::REVERTED_TO_SELF)
- process_state_ = ProcessStateInternal::REVERTED_TO_SELF;
- }
-
- void ProcessState::SetCsrssConnected(bool csrss_connected) {
- csrss_connected_ = csrss_connected;
- }
-
-+
-+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/security/sandbox/chromium/sandbox/win/src/target_services.h b/security/sandbox/chromium/sandbox/win/src/target_services.h
---- a/security/sandbox/chromium/sandbox/win/src/target_services.h
-+++ b/security/sandbox/chromium/sandbox/win/src/target_services.h
-@@ -40,16 +40,21 @@ class ProcessState {
- class TargetServicesBase : public TargetServices {
- public:
- TargetServicesBase();
-
- // Public interface of TargetServices.
- ResultCode Init() override;
- void LowerToken() override;
- ProcessState* GetState() override;
-+ ResultCode DuplicateHandle(HANDLE source_handle,
-+ DWORD target_process_id,
-+ HANDLE* target_handle,
-+ DWORD desired_access,
-+ DWORD options) override;
-
- // Factory method.
- static TargetServicesBase* GetInstance();
-
- // Sends a simple IPC Message that has a well-known answer. Returns true
- // if the IPC was successful and false otherwise. There are 2 versions of
- // this test: 1 and 2. The first one send a simple message while the
- // second one send a message with an in/out param.
-diff --git a/security/sandbox/chromium/sandbox/win/src/top_level_dispatcher.cc b/security/sandbox/chromium/sandbox/win/src/top_level_dispatcher.cc
---- a/security/sandbox/chromium/sandbox/win/src/top_level_dispatcher.cc
-+++ b/security/sandbox/chromium/sandbox/win/src/top_level_dispatcher.cc
-@@ -5,16 +5,17 @@
- #include "sandbox/win/src/top_level_dispatcher.h"
-
- #include <stdint.h>
- #include <string.h>
-
- #include "base/logging.h"
- #include "sandbox/win/src/crosscall_server.h"
- #include "sandbox/win/src/filesystem_dispatcher.h"
-+#include "sandbox/win/src/handle_dispatcher.h"
- #include "sandbox/win/src/interception.h"
- #include "sandbox/win/src/internal_types.h"
- #include "sandbox/win/src/ipc_tags.h"
- #include "sandbox/win/src/named_pipe_dispatcher.h"
- #include "sandbox/win/src/process_mitigations_win32k_dispatcher.h"
- #include "sandbox/win/src/process_thread_dispatcher.h"
- #include "sandbox/win/src/registry_dispatcher.h"
- #include "sandbox/win/src/sandbox_policy_base.h"
-@@ -55,16 +56,20 @@ TopLevelDispatcher::TopLevelDispatcher(P
- ipc_targets_[static_cast<size_t>(IpcTag::OPENEVENT)] = dispatcher;
- sync_dispatcher_.reset(dispatcher);
-
- dispatcher = new RegistryDispatcher(policy_);
- ipc_targets_[static_cast<size_t>(IpcTag::NTCREATEKEY)] = dispatcher;
- ipc_targets_[static_cast<size_t>(IpcTag::NTOPENKEY)] = dispatcher;
- registry_dispatcher_.reset(dispatcher);
-
-+ dispatcher = new HandleDispatcher(policy_);
-+ ipc_targets_[static_cast<size_t>(IpcTag::DUPLICATEHANDLEPROXY)] = dispatcher;
-+ handle_dispatcher_.reset(dispatcher);
-+
- dispatcher = new ProcessMitigationsWin32KDispatcher(policy_);
- ipc_targets_[static_cast<size_t>(IpcTag::GDI_GDIDLLINITIALIZE)] = dispatcher;
- ipc_targets_[static_cast<size_t>(IpcTag::GDI_GETSTOCKOBJECT)] = dispatcher;
- ipc_targets_[static_cast<size_t>(IpcTag::USER_REGISTERCLASSW)] = dispatcher;
- ipc_targets_[static_cast<size_t>(IpcTag::USER_ENUMDISPLAYMONITORS)] =
- dispatcher;
- ipc_targets_[static_cast<size_t>(IpcTag::USER_ENUMDISPLAYDEVICES)] =
- dispatcher;