Bug 1878638 p3: Remove sandbox DuplicateHandle brokering. r=handyman

This was removed from chromium and we no longer need to add it back.

Differential Revision: https://phabricator.services.mozilla.com/D200904
This commit is contained in:
Bob Owen 2024-02-22 19:03:56 +00:00
parent 30b777cfd9
commit bf1aba0029
19 changed files with 1 additions and 1250 deletions

View file

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please # changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more. # don't change CLOBBER for WebIDL changes any more.
Modified build files in third_party/libwebrtc - Bug 1876843 - Vendor libwebrtc from 24510d43dc Removed proxying objects - Bug 1878638: Remove handle duplication rules for Windows process sandboxes

View file

@ -1,5 +1,4 @@
revert_remove_AddTargetPeer.patch revert_remove_AddTargetPeer.patch
revert_remove_BrokerDuplicateHandle.patch
replace_ScopedNativeLibrary_in_ApplyMitigationsToCurrentThread.patch replace_ScopedNativeLibrary_in_ApplyMitigationsToCurrentThread.patch
ifdef_out_FromStringInternal.patch ifdef_out_FromStringInternal.patch
add_option_to_not_use_restricting_sids.patch add_option_to_not_use_restricting_sids.patch

View file

@ -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;

View file

@ -1,93 +0,0 @@
// 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

View file

@ -1,41 +0,0 @@
// 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_

View file

@ -1,48 +0,0 @@
// 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"
#include "mozilla/sandboxing/sandboxLogging.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);
mozilla::sandboxing::LogBlocked("DuplicateHandle");
return SBOX_ERROR_GENERIC;
}
*target_handle = answer.handle;
mozilla::sandboxing::LogAllowed("DuplicateHandle");
return SBOX_ALL_OK;
}
} // namespace sandbox

View file

@ -1,24 +0,0 @@
// 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_

View file

@ -1,93 +0,0 @@
// 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

View file

@ -1,39 +0,0 @@
// 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_

View file

@ -1,114 +0,0 @@
// 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

View file

@ -28,7 +28,6 @@ enum class IpcTag {
OPENEVENT, OPENEVENT,
NTCREATEKEY, NTCREATEKEY,
NTOPENKEY, NTOPENKEY,
DUPLICATEHANDLEPROXY,
GDI_GDIDLLINITIALIZE, GDI_GDIDLLINITIALIZE,
GDI_GETSTOCKOBJECT, GDI_GETSTOCKOBJECT,
USER_REGISTERCLASSW, USER_REGISTERCLASSW,

View file

@ -172,20 +172,6 @@ class TargetServices {
// LowerToken has been called or not. // LowerToken has been called or not.
virtual ProcessState* GetState() = 0; 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;
virtual ResultCode GetComplexLineBreaks(const WCHAR* text, uint32_t length, virtual ResultCode GetComplexLineBreaks(const WCHAR* text, uint32_t length,
uint8_t* break_before) = 0; uint8_t* break_before) = 0;

View file

@ -30,7 +30,6 @@ class TargetPolicy {
SUBSYS_PROCESS, // Creation of child processes. SUBSYS_PROCESS, // Creation of child processes.
SUBSYS_REGISTRY, // Creation and opening of registry keys. SUBSYS_REGISTRY, // Creation and opening of registry keys.
SUBSYS_SYNC, // Creation of named sync objects. SUBSYS_SYNC, // Creation of named sync objects.
SUBSYS_HANDLES, // Duplication of handles to other processes.
SUBSYS_WIN32K_LOCKDOWN, // Win32K Lockdown related policy. SUBSYS_WIN32K_LOCKDOWN, // Win32K Lockdown related policy.
SUBSYS_SIGNED_BINARY, // Signed binary policy. SUBSYS_SIGNED_BINARY, // Signed binary policy.
SUBSYS_LINE_BREAK // Complex line break policy. SUBSYS_LINE_BREAK // Complex line break policy.
@ -44,9 +43,6 @@ class TargetPolicy {
FILES_ALLOW_QUERY, // Allows access to query the attributes of a file. FILES_ALLOW_QUERY, // Allows access to query the attributes of a file.
FILES_ALLOW_DIR_ANY, // Allows open or create with directory semantics FILES_ALLOW_DIR_ANY, // Allows open or create with directory semantics
// only. // 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. NAMEDPIPES_ALLOW_ANY, // Allows creation of a named pipe.
PROCESS_MIN_EXEC, // Allows to create a process with minimal rights PROCESS_MIN_EXEC, // Allows to create a process with minimal rights
// over the resulting process and thread handles. // over the resulting process and thread handles.

View file

@ -17,7 +17,6 @@
#include "base/win/windows_version.h" #include "base/win/windows_version.h"
#include "sandbox/win/src/acl.h" #include "sandbox/win/src/acl.h"
#include "sandbox/win/src/filesystem_policy.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/interception.h"
#include "sandbox/win/src/job.h" #include "sandbox/win/src/job.h"
#include "sandbox/win/src/line_break_policy.h" #include "sandbox/win/src/line_break_policy.h"
@ -775,14 +774,6 @@ ResultCode PolicyBase::AddRuleInternal(SubSystem subsystem,
} }
break; break;
} }
case SUBSYS_HANDLES: {
if (!HandlePolicy::GenerateRules(pattern, semantics, policy_maker_)) {
NOTREACHED();
return SBOX_ERROR_BAD_PARAMS;
}
break;
}
case SUBSYS_WIN32K_LOCKDOWN: { case SUBSYS_WIN32K_LOCKDOWN: {
// Win32k intercept rules only supported on Windows 8 and above. This must // Win32k intercept rules only supported on Windows 8 and above. This must
// match the version checks in process_mitigations.cc for consistency. // match the version checks in process_mitigations.cc for consistency.

View file

@ -12,7 +12,6 @@
#include "base/win/windows_version.h" #include "base/win/windows_version.h"
#include "sandbox/win/src/crosscall_client.h" #include "sandbox/win/src/crosscall_client.h"
#include "sandbox/win/src/handle_closer_agent.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/heap_helper.h"
#include "sandbox/win/src/line_break_interception.h" #include "sandbox/win/src/line_break_interception.h"
#include "sandbox/win/src/ipc_tags.h" #include "sandbox/win/src/ipc_tags.h"
@ -246,15 +245,6 @@ void ProcessState::SetCsrssConnected(bool csrss_connected) {
csrss_connected_ = 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);
}
ResultCode TargetServicesBase::GetComplexLineBreaks(const WCHAR* text, ResultCode TargetServicesBase::GetComplexLineBreaks(const WCHAR* text,
uint32_t length, uint32_t length,
uint8_t* break_before) { uint8_t* break_before) {

View file

@ -45,11 +45,6 @@ class TargetServicesBase : public TargetServices {
ResultCode Init() override; ResultCode Init() override;
void LowerToken() override; void LowerToken() override;
ProcessState* GetState() override; ProcessState* GetState() override;
ResultCode DuplicateHandle(HANDLE source_handle,
DWORD target_process_id,
HANDLE* target_handle,
DWORD desired_access,
DWORD options) override;
ResultCode GetComplexLineBreaks(const WCHAR* text, uint32_t length, ResultCode GetComplexLineBreaks(const WCHAR* text, uint32_t length,
uint8_t* break_before) final; uint8_t* break_before) final;

View file

@ -10,7 +10,6 @@
#include "base/logging.h" #include "base/logging.h"
#include "sandbox/win/src/crosscall_server.h" #include "sandbox/win/src/crosscall_server.h"
#include "sandbox/win/src/filesystem_dispatcher.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/interception.h"
#include "sandbox/win/src/internal_types.h" #include "sandbox/win/src/internal_types.h"
#include "sandbox/win/src/ipc_tags.h" #include "sandbox/win/src/ipc_tags.h"
@ -62,10 +61,6 @@ TopLevelDispatcher::TopLevelDispatcher(PolicyBase* policy) : policy_(policy) {
ipc_targets_[static_cast<size_t>(IpcTag::NTOPENKEY)] = dispatcher; ipc_targets_[static_cast<size_t>(IpcTag::NTOPENKEY)] = dispatcher;
registry_dispatcher_.reset(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_); dispatcher = new ProcessMitigationsWin32KDispatcher(policy_);
ipc_targets_[static_cast<size_t>(IpcTag::GDI_GDIDLLINITIALIZE)] = dispatcher; 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::GDI_GETSTOCKOBJECT)] = dispatcher;

View file

@ -113,9 +113,6 @@ elif CONFIG["OS_ARCH"] == "WINNT":
"chromium/sandbox/win/src/filesystem_policy.cc", "chromium/sandbox/win/src/filesystem_policy.cc",
"chromium/sandbox/win/src/handle_closer.cc", "chromium/sandbox/win/src/handle_closer.cc",
"chromium/sandbox/win/src/handle_closer_agent.cc", "chromium/sandbox/win/src/handle_closer_agent.cc",
"chromium/sandbox/win/src/handle_dispatcher.cc",
"chromium/sandbox/win/src/handle_interception.cc",
"chromium/sandbox/win/src/handle_policy.cc",
"chromium/sandbox/win/src/heap_helper.cc", "chromium/sandbox/win/src/heap_helper.cc",
"chromium/sandbox/win/src/interception.cc", "chromium/sandbox/win/src/interception.cc",
"chromium/sandbox/win/src/interception_agent.cc", "chromium/sandbox/win/src/interception_agent.cc",

View file

@ -1833,8 +1833,6 @@ void SandboxBroker::ApplyLoggingPolicy() {
L"HKEY_CURRENT_USER\\dummy"); L"HKEY_CURRENT_USER\\dummy");
mPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_SYNC, mPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_SYNC,
sandbox::TargetPolicy::EVENTS_ALLOW_READONLY, L"dummy"); sandbox::TargetPolicy::EVENTS_ALLOW_READONLY, L"dummy");
mPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES,
sandbox::TargetPolicy::HANDLES_DUP_BROKER, L"dummy");
} }
SandboxBroker::~SandboxBroker() { SandboxBroker::~SandboxBroker() {