# HG changeset patch # User Bob Owen # Date 1485985575 0 # Wed Feb 01 21:46:15 2017 +0000 # Node ID 9328428e5f863472f3702057b01d472b46b7b6a2 # Parent 4c1880ac25a66dec6455dc88ba693096d65df704 Reinstate sandbox::TargetServices::BrokerDuplicateHandle. r=aklotz This basically reverts chromium commit 569193665184525ca366e65d0735f5c851106e43. 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,92 @@ +// 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 + +#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 = { + {IPC_DUPLICATEHANDLEPROXY_TAG, + {VOIDPTR_TYPE, UINT32_TYPE, UINT32_TYPE, UINT32_TYPE}}, + reinterpret_cast( + &HandleDispatcher::DuplicateHandleProxy)}; + + ipc_calls_.push_back(duplicate_handle_proxy); +} + +bool HandleDispatcher::SetupService(InterceptionManager* manager, + int service) { + // We perform no interceptions for handles right now. + switch (service) { + case IPC_DUPLICATEHANDLEPROXY_TAG: + return true; + } + + return false; +} + +bool HandleDispatcher::DuplicateHandleProxy(IPCInfo* ipc, + HANDLE source_handle, + 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(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 params; + params[HandleTarget::NAME] = ParamPickerMake(type_info->Name.Buffer); + params[HandleTarget::TARGET] = ParamPickerMake(target_process_id); + + EvalResult eval = policy_base_->EvalPolicy(IPC_DUPLICATEHANDLEPROXY_TAG, + 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 + +#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, int 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, IPC_DUPLICATEHANDLEPROXY_TAG, + source_handle, target_process_id, + desired_access, options, &answer); + if (SBOX_ALL_OK != code) + return code; + + if (answer.win32_result) { + ::SetLastError(answer.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,92 @@ +// 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 + +#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(IPC_DUPLICATEHANDLEPROXY_TAG, &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()->IsActiveTarget(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 + +#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 { IPC_NTOPENPROCESS_TAG, IPC_NTOPENPROCESSTOKEN_TAG, IPC_NTOPENPROCESSTOKENEX_TAG, IPC_CREATEPROCESSW_TAG, IPC_CREATEEVENT_TAG, IPC_OPENEVENT_TAG, IPC_NTCREATEKEY_TAG, IPC_NTOPENKEY_TAG, + IPC_DUPLICATEHANDLEPROXY_TAG, IPC_GDI_GDIDLLINITIALIZE_TAG, IPC_GDI_GETSTOCKOBJECT_TAG, IPC_USER_REGISTERCLASSW_TAG, IPC_CREATETHREAD_TAG, IPC_USER_ENUMDISPLAYMONITORS_TAG, IPC_USER_ENUMDISPLAYDEVICES_TAG, IPC_USER_GETMONITORINFO_TAG, IPC_GDI_CREATEOPMPROTECTEDOUTPUTS_TAG, 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 @@ -136,14 +136,28 @@ class TargetServices { // processing any untrusted data or running third-party code. If this call // 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; }; } // namespace sandbox #endif // SANDBOX_WIN_SRC_SANDBOX_H_ 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 @@ -21,27 +21,31 @@ 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. }; // 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 @@ -10,16 +10,17 @@ #include "base/callback.h" #include "base/logging.h" #include "base/macros.h" #include "base/stl_util.h" #include "base/strings/stringprintf.h" #include "base/win/windows_version.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" @@ -733,16 +734,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: { if (!ProcessMitigationsWin32KLockdownPolicy::GenerateRules( pattern, semantics, policy_maker_)) { NOTREACHED(); return SBOX_ERROR_BAD_PARAMS; } break; } 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 #include #include #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" @@ -259,9 +260,19 @@ void ProcessState::SetRevertedToSelf() { if (process_state_ < 3) process_state_ = 3; } 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 @@ -41,16 +41,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 #include #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" @@ -53,16 +54,20 @@ TopLevelDispatcher::TopLevelDispatcher(P ipc_targets_[IPC_OPENEVENT_TAG] = dispatcher; sync_dispatcher_.reset(dispatcher); dispatcher = new RegistryDispatcher(policy_); ipc_targets_[IPC_NTCREATEKEY_TAG] = dispatcher; ipc_targets_[IPC_NTOPENKEY_TAG] = dispatcher; registry_dispatcher_.reset(dispatcher); + dispatcher = new HandleDispatcher(policy_); + ipc_targets_[IPC_DUPLICATEHANDLEPROXY_TAG] = dispatcher; + handle_dispatcher_.reset(dispatcher); + dispatcher = new ProcessMitigationsWin32KDispatcher(policy_); ipc_targets_[IPC_GDI_GDIDLLINITIALIZE_TAG] = dispatcher; ipc_targets_[IPC_GDI_GETSTOCKOBJECT_TAG] = dispatcher; ipc_targets_[IPC_USER_REGISTERCLASSW_TAG] = dispatcher; ipc_targets_[IPC_USER_ENUMDISPLAYMONITORS_TAG] = dispatcher; ipc_targets_[IPC_USER_ENUMDISPLAYDEVICES_TAG] = dispatcher; ipc_targets_[IPC_USER_GETMONITORINFO_TAG] = dispatcher; ipc_targets_[IPC_GDI_CREATEOPMPROTECTEDOUTPUTS_TAG] = dispatcher;