summaryrefslogtreecommitdiffstats
path: root/security/sandbox/chromium-shim/patches
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:13:27 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:13:27 +0000
commit40a355a42d4a9444dc753c04c6608dade2f06a23 (patch)
tree871fc667d2de662f171103ce5ec067014ef85e61 /security/sandbox/chromium-shim/patches
parentAdding upstream version 124.0.1. (diff)
downloadfirefox-adbda400be353e676059e335c3c0aaf99e719475.tar.xz
firefox-adbda400be353e676059e335c3c0aaf99e719475.zip
Adding upstream version 125.0.1.upstream/125.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'security/sandbox/chromium-shim/patches')
-rw-r--r--security/sandbox/chromium-shim/patches/with_update/fix_max_syscalls_linux_aarch64.patch25
-rwxr-xr-xsecurity/sandbox/chromium-shim/patches/with_update/patch_order.txt3
-rw-r--r--security/sandbox/chromium-shim/patches/with_update/revert_remove_AddTargetPeer.patch310
-rw-r--r--security/sandbox/chromium-shim/patches/with_update/revert_remove_BrokerDuplicateHandle.patch743
4 files changed, 26 insertions, 1055 deletions
diff --git a/security/sandbox/chromium-shim/patches/with_update/fix_max_syscalls_linux_aarch64.patch b/security/sandbox/chromium-shim/patches/with_update/fix_max_syscalls_linux_aarch64.patch
new file mode 100644
index 0000000000..c5f816213a
--- /dev/null
+++ b/security/sandbox/chromium-shim/patches/with_update/fix_max_syscalls_linux_aarch64.patch
@@ -0,0 +1,25 @@
+# HG changeset patch
+# User Paul Bone <pbone@mozilla.org>
+# Date 1708492973 -39600
+# Wed Feb 21 16:22:53 2024 +1100
+# Node ID 501cb36ee885ebd0939e1892f821d55ac149ceec
+# Parent cf015b6f24b494190f562b255147f96e8b8b4139
+Bug 1866396 - Hard code the number of system calls for Linux on aarch64 r=jld
+
+Differential Revision: https://phabricator.services.mozilla.com/D202293
+
+diff --git a/security/sandbox/chromium/sandbox/linux/bpf_dsl/linux_syscall_ranges.h b/security/sandbox/chromium/sandbox/linux/bpf_dsl/linux_syscall_ranges.h
+--- a/security/sandbox/chromium/sandbox/linux/bpf_dsl/linux_syscall_ranges.h
++++ b/security/sandbox/chromium/sandbox/linux/bpf_dsl/linux_syscall_ranges.h
+@@ -51,9 +51,9 @@
+
+ #elif defined(__aarch64__)
+
+-#include <asm-generic/unistd.h>
++// The unistd.h included in the sysroot has a very old __NR_syscalls
+ #define MIN_SYSCALL 0u
+-#define MAX_PUBLIC_SYSCALL __NR_syscalls
++#define MAX_PUBLIC_SYSCALL (MIN_SYSCALL + 1024u)
+ #define MAX_SYSCALL MAX_PUBLIC_SYSCALL
+
+ #else
diff --git a/security/sandbox/chromium-shim/patches/with_update/patch_order.txt b/security/sandbox/chromium-shim/patches/with_update/patch_order.txt
index 8d40aeaa7f..028348a0f0 100755
--- a/security/sandbox/chromium-shim/patches/with_update/patch_order.txt
+++ b/security/sandbox/chromium-shim/patches/with_update/patch_order.txt
@@ -1,5 +1,3 @@
-revert_remove_AddTargetPeer.patch
-revert_remove_BrokerDuplicateHandle.patch
replace_ScopedNativeLibrary_in_ApplyMitigationsToCurrentThread.patch
ifdef_out_FromStringInternal.patch
add_option_to_not_use_restricting_sids.patch
@@ -32,3 +30,4 @@ derive_sid_from_name.patch
add_loongarch_defines.patch
block_NtImpersonateAnonymousToken_before_LowerToken.patch
fix_broker_alive_mutex.patch
+fix_max_syscalls_linux_aarch64.patch
diff --git a/security/sandbox/chromium-shim/patches/with_update/revert_remove_AddTargetPeer.patch b/security/sandbox/chromium-shim/patches/with_update/revert_remove_AddTargetPeer.patch
deleted file mode 100644
index 04020b60b7..0000000000
--- a/security/sandbox/chromium-shim/patches/with_update/revert_remove_AddTargetPeer.patch
+++ /dev/null
@@ -1,310 +0,0 @@
-# HG changeset patch
-# User Toshihito Kikuchi <tkikuchi@mozilla.com>
-# Date 1589671259 25200
-# Sat May 16 16:20:59 2020 -0700
-# Node ID 0b5183a01df78cc85264f2eae2c4d8e407bb1112
-# Parent d093cd9ccfcf06f4a1f0d7f1a4bd0f143ef92b4b
-Add BrokerServicesBase::IsSafeDuplicationTarget. r=bobowen
-
-This patch adds BrokerServicesBase::IsSafeDuplicationTarget and
-BrokerServicesBase::AddTargetPeer using the new ProcessTracker introduced by
-https://chromium.googlesource.com/chromium/src.git/+/3d8382cf9dd44cf9c05e43e42c500f4825e1fed8
-We need these methods for HandlePolicy which is added as a different patch.
-
-Chromium used to have AddTargetPeer and IsActiveTarget, but removed by
-the following commits because they were no longer used in Chromium.
-https://chromium.googlesource.com/chromium/src.git/+/996b42db5296bd3d11b3d7fde1a4602bbcefed2c
-https://chromium.googlesource.com/chromium/src.git/+/e615a1152ac6e10f1a91f0629fb8b5ca223ffbdc
-
-diff --git a/security/sandbox/chromium/sandbox/win/src/broker_services.cc b/security/sandbox/chromium/sandbox/win/src/broker_services.cc
---- a/security/sandbox/chromium/sandbox/win/src/broker_services.cc
-+++ b/security/sandbox/chromium/sandbox/win/src/broker_services.cc
-@@ -154,16 +154,18 @@ namespace sandbox {
- BrokerServicesBase::BrokerServicesBase() {}
-
- // The broker uses a dedicated worker thread that services the job completion
- // port to perform policy notifications and associated cleanup tasks.
- ResultCode BrokerServicesBase::Init() {
- if (job_port_.IsValid() || thread_pool_)
- return SBOX_ERROR_UNEXPECTED_CALL;
-
-+ ::InitializeCriticalSection(&lock_);
-+
- job_port_.Set(::CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr, 0, 0));
- if (!job_port_.IsValid())
- return SBOX_ERROR_CANNOT_INIT_BROKERSERVICES;
-
- no_targets_.Set(::CreateEventW(nullptr, true, false, nullptr));
-
- job_thread_.Set(::CreateThread(nullptr, 0, // Default security and stack.
- TargetEventsThread, this, 0, nullptr));
-@@ -191,16 +193,17 @@ BrokerServicesBase::~BrokerServicesBase(
-
- if (job_thread_.IsValid() &&
- WAIT_TIMEOUT == ::WaitForSingleObject(job_thread_.Get(), 1000)) {
- // Cannot clean broker services.
- NOTREACHED();
- return;
- }
- thread_pool_.reset();
-+ ::DeleteCriticalSection(&lock_);
- }
-
- scoped_refptr<TargetPolicy> BrokerServicesBase::CreatePolicy() {
- // If you change the type of the object being created here you must also
- // change the downcast to it in SpawnTarget().
- scoped_refptr<TargetPolicy> policy(new PolicyBase);
- // PolicyBase starts with refcount 1.
- policy->Release();
-@@ -283,16 +286,21 @@ DWORD WINAPI BrokerServicesBase::TargetE
- if (1 == target_counter) {
- ::ResetEvent(no_targets);
- }
- break;
- }
-
- case JOB_OBJECT_MSG_EXIT_PROCESS:
- case JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS: {
-+ {
-+ AutoLock lock(&broker->lock_);
-+ broker->active_targets_.erase(
-+ static_cast<DWORD>(reinterpret_cast<uintptr_t>(ovl)));
-+ }
- size_t erase_result = child_process_ids.erase(
- static_cast<DWORD>(reinterpret_cast<uintptr_t>(ovl)));
- if (erase_result != 1U) {
- // The process was untracked e.g. a child process of the target.
- --untracked_target_counter;
- DCHECK(untracked_target_counter >= 0);
- }
- --target_counter;
-@@ -348,27 +356,31 @@ DWORD WINAPI BrokerServicesBase::TargetE
- tracker->wait_handle = INVALID_HANDLE_VALUE;
- }
- processes.push_back(std::move(tracker));
-
- } else if (THREAD_CTRL_PROCESS_SIGNALLED == key) {
- ProcessTracker* tracker =
- static_cast<ProcessTracker*>(reinterpret_cast<void*>(ovl));
-
-+ {
-+ AutoLock lock(&broker->lock_);
-+ broker->active_targets_.erase(tracker->process_id);
-+ }
-+
- ::UnregisterWait(tracker->wait_handle);
- tracker->wait_handle = INVALID_HANDLE_VALUE;
-
- // PID is unique until the process handle is closed in dtor.
- processes.erase(std::remove_if(processes.begin(), processes.end(),
- [&](auto&& p) -> bool {
- return p->process_id ==
- tracker->process_id;
- }),
- processes.end());
--
- } else if (THREAD_CTRL_GET_POLICY_INFO == key) {
- // Clone the policies for sandbox diagnostics.
- std::unique_ptr<PolicyDiagnosticsReceiver> receiver;
- receiver.reset(static_cast<PolicyDiagnosticsReceiver*>(
- reinterpret_cast<void*>(ovl)));
- // The PollicyInfo ctor copies essential information from the trackers.
- auto policy_list = std::make_unique<PolicyDiagnosticList>();
- for (auto&& process_tracker : processes) {
-@@ -637,47 +649,79 @@ ResultCode BrokerServicesBase::SpawnTarg
- // the tracker. The worker thread takes ownership of these objects.
- CHECK(::PostQueuedCompletionStatus(
- job_port_.Get(), 0, THREAD_CTRL_NEW_JOB_TRACKER,
- reinterpret_cast<LPOVERLAPPED>(tracker)));
- // There is no obvious recovery after failure here. Previous version with
- // SpawnCleanup() caused deletion of TargetProcess twice. crbug.com/480639
- CHECK(
- AssociateCompletionPort(tracker->job.Get(), job_port_.Get(), tracker));
-+
-+ AutoLock lock(&lock_);
-+ active_targets_.insert(process_info.process_id());
- } else {
-- // Duplicate the process handle to give the tracking machinery
-- // something valid to wait on in the tracking thread.
-- HANDLE tmp_process_handle = INVALID_HANDLE_VALUE;
-- if (!::DuplicateHandle(::GetCurrentProcess(), process_info.process_handle(),
-- ::GetCurrentProcess(), &tmp_process_handle,
-- SYNCHRONIZE, false, 0 /*no options*/)) {
-- *last_error = ::GetLastError();
-+ result = AddTargetPeerInternal(process_info.process_handle(),
-+ process_info.process_id(),
-+ policy_base, last_error);
-+ if (result != SBOX_ALL_OK) {
- // This may fail in the same way as Job associated processes.
- // crbug.com/480639.
- SpawnCleanup(target);
-- return SBOX_ERROR_CANNOT_DUPLICATE_PROCESS_HANDLE;
-+ return result;
- }
-- base::win::ScopedHandle dup_process_handle(tmp_process_handle);
-- ProcessTracker* tracker = new ProcessTracker(
-- policy_base, process_info.process_id(), std::move(dup_process_handle));
-- // The tracker and policy will leak if this call fails.
-- ::PostQueuedCompletionStatus(job_port_.Get(), 0,
-- THREAD_CTRL_NEW_PROCESS_TRACKER,
-- reinterpret_cast<LPOVERLAPPED>(tracker));
- }
-
- *target_info = process_info.Take();
- return result;
- }
-
- ResultCode BrokerServicesBase::WaitForAllTargets() {
- ::WaitForSingleObject(no_targets_.Get(), INFINITE);
- return SBOX_ALL_OK;
- }
-
-+bool BrokerServicesBase::IsSafeDuplicationTarget(DWORD process_id) {
-+ AutoLock lock(&lock_);
-+ return active_targets_.find(process_id) != active_targets_.end();
-+}
-+
-+ResultCode BrokerServicesBase::AddTargetPeerInternal(
-+ HANDLE peer_process_handle,
-+ DWORD peer_process_id,
-+ scoped_refptr<PolicyBase> policy_base,
-+ DWORD* last_error) {
-+ // Duplicate the process handle to give the tracking machinery
-+ // something valid to wait on in the tracking thread.
-+ HANDLE tmp_process_handle = INVALID_HANDLE_VALUE;
-+ if (!::DuplicateHandle(::GetCurrentProcess(), peer_process_handle,
-+ ::GetCurrentProcess(), &tmp_process_handle,
-+ SYNCHRONIZE, false, 0 /*no options*/)) {
-+ *last_error = ::GetLastError();
-+ return SBOX_ERROR_CANNOT_DUPLICATE_PROCESS_HANDLE;
-+ }
-+ base::win::ScopedHandle dup_process_handle(tmp_process_handle);
-+ ProcessTracker* tracker = new ProcessTracker(
-+ policy_base, peer_process_id, std::move(dup_process_handle));
-+ // The tracker and policy will leak if this call fails.
-+ ::PostQueuedCompletionStatus(job_port_.Get(), 0,
-+ THREAD_CTRL_NEW_PROCESS_TRACKER,
-+ reinterpret_cast<LPOVERLAPPED>(tracker));
-+
-+ AutoLock lock(&lock_);
-+ active_targets_.insert(peer_process_id);
-+
-+ return SBOX_ALL_OK;
-+}
-+
-+ResultCode BrokerServicesBase::AddTargetPeer(HANDLE peer_process) {
-+ DWORD last_error;
-+ return AddTargetPeerInternal(peer_process, ::GetProcessId(peer_process),
-+ nullptr, &last_error);
-+}
-+
- ResultCode BrokerServicesBase::GetPolicyDiagnostics(
- std::unique_ptr<PolicyDiagnosticsReceiver> receiver) {
- CHECK(job_thread_.IsValid());
- // Post to the job thread.
- if (!::PostQueuedCompletionStatus(
- job_port_.Get(), 0, THREAD_CTRL_GET_POLICY_INFO,
- reinterpret_cast<LPOVERLAPPED>(receiver.get()))) {
- receiver->OnError(SBOX_ERROR_GENERIC);
-diff --git a/security/sandbox/chromium/sandbox/win/src/broker_services.h b/security/sandbox/chromium/sandbox/win/src/broker_services.h
---- a/security/sandbox/chromium/sandbox/win/src/broker_services.h
-+++ b/security/sandbox/chromium/sandbox/win/src/broker_services.h
-@@ -13,16 +13,17 @@
-
- #include "base/compiler_specific.h"
- #include "base/macros.h"
- #include "base/memory/scoped_refptr.h"
- #include "base/win/scoped_handle.h"
- #include "sandbox/win/src/crosscall_server.h"
- #include "sandbox/win/src/job.h"
- #include "sandbox/win/src/sandbox.h"
-+#include "sandbox/win/src/sandbox_policy_base.h"
- #include "sandbox/win/src/sharedmem_ipc_server.h"
- #include "sandbox/win/src/win2k_threadpool.h"
- #include "sandbox/win/src/win_utils.h"
-
- namespace sandbox {
-
- // BrokerServicesBase ---------------------------------------------------------
- // Broker implementation version 0
-@@ -43,16 +44,24 @@ class BrokerServicesBase final : public
- scoped_refptr<TargetPolicy> CreatePolicy() override;
- ResultCode SpawnTarget(const wchar_t* exe_path,
- const wchar_t* command_line,
- scoped_refptr<TargetPolicy> policy,
- ResultCode* last_warning,
- DWORD* last_error,
- PROCESS_INFORMATION* target) override;
- ResultCode WaitForAllTargets() override;
-+ ResultCode AddTargetPeer(HANDLE peer_process) override;
-+
-+ // Checks if the supplied process ID matches one of the broker's active
-+ // target processes. We use this method for the specific purpose of
-+ // checking if we can safely duplicate a handle to the supplied process
-+ // in DuplicateHandleProxyAction.
-+ bool IsSafeDuplicationTarget(DWORD process_id);
-+
- ResultCode GetPolicyDiagnostics(
- std::unique_ptr<PolicyDiagnosticsReceiver> receiver) override;
-
- private:
- // The routine that the worker thread executes. It is in charge of
- // notifications and cleanup-related tasks.
- static DWORD WINAPI TargetEventsThread(PVOID param);
-
-@@ -65,14 +74,27 @@ class BrokerServicesBase final : public
- base::win::ScopedHandle no_targets_;
-
- // Handle to the worker thread that reacts to job notifications.
- base::win::ScopedHandle job_thread_;
-
- // Provides a pool of threads that are used to wait on the IPC calls.
- std::unique_ptr<ThreadProvider> thread_pool_;
-
-+ // The set representing the broker's active target processes including
-+ // both sandboxed and unsandboxed peer processes.
-+ std::set<DWORD> active_targets_;
-+
-+ // Lock used to protect active_targets_ from being simultaneously accessed
-+ // by multiple threads.
-+ CRITICAL_SECTION lock_;
-+
-+ ResultCode AddTargetPeerInternal(HANDLE peer_process_handle,
-+ DWORD peer_process_id,
-+ scoped_refptr<PolicyBase> policy_base,
-+ DWORD* last_error);
-+
- DISALLOW_COPY_AND_ASSIGN(BrokerServicesBase);
- };
-
- } // namespace sandbox
-
- #endif // SANDBOX_WIN_SRC_BROKER_SERVICES_H_
-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
-@@ -96,16 +96,24 @@ class BrokerServices {
-
- // This call blocks (waits) for all the targets to terminate.
- // 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 WaitForAllTargets() = 0;
-
-+ // Adds an unsandboxed process as a peer for policy decisions (e.g.
-+ // HANDLES_DUP_ANY policy).
-+ // 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 AddTargetPeer(HANDLE peer_process) = 0;
-+
- // This call creates a snapshot of policies managed by the sandbox and
- // returns them via a helper class.
- // Parameters:
- // receiver: The |PolicyDiagnosticsReceiver| implementation will be
- // called to accept the results of the call.
- // Returns:
- // ALL_OK if the request was dispatched. All other return values
- // imply failure, and the responder will not receive its completion
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;