diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:13:27 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:13:27 +0000 |
commit | 40a355a42d4a9444dc753c04c6608dade2f06a23 (patch) | |
tree | 871fc667d2de662f171103ce5ec067014ef85e61 /security/sandbox/chromium-shim/patches/with_update/revert_remove_BrokerDuplicateHandle.patch | |
parent | Adding upstream version 124.0.1. (diff) | |
download | firefox-40a355a42d4a9444dc753c04c6608dade2f06a23.tar.xz firefox-40a355a42d4a9444dc753c04c6608dade2f06a23.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/with_update/revert_remove_BrokerDuplicateHandle.patch')
-rw-r--r-- | security/sandbox/chromium-shim/patches/with_update/revert_remove_BrokerDuplicateHandle.patch | 743 |
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; |