Index: sandbox/win/src/lpc_interception.cc |
diff --git a/sandbox/win/src/lpc_interception.cc b/sandbox/win/src/lpc_interception.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..c8399b48bb76770cf45499c89efef3b62f39830c |
--- /dev/null |
+++ b/sandbox/win/src/lpc_interception.cc |
@@ -0,0 +1,86 @@ |
+// Copyright (c) 2006-2008 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/lpc_interception.h" |
+ |
+#include "sandbox/win/src/crosscall_client.h" |
+#include "sandbox/win/src/ipc_tags.h" |
+#include "sandbox/win/src/policy_params.h" |
+#include "sandbox/win/src/policy_target.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 { |
+ |
+NTSTATUS WINAPI TargetNtAlpcConnectPort( |
+ NtAlpcConnectPortFunction orig_AlpcConnectPort, |
+ PHANDLE port_handle, |
+ PUNICODE_STRING port_name, |
+ POBJECT_ATTRIBUTES object_attributes, |
+ PALPC_PORT_ATTRIBUTES port_attributes, |
+ ULONG flags, |
+ void* sid, |
+ void* connection_message, |
+ ULONG* buffer_length, |
+ void* out_message_attributes, |
+ void* in_message_attributes, |
+ PLARGE_INTEGER timeout) { |
+ NTSTATUS status = orig_AlpcConnectPort(port_handle, port_name, |
+ object_attributes, port_attributes, flags, sid, connection_message, |
+ buffer_length, out_message_attributes, in_message_attributes, timeout); |
+ if (status != STATUS_ACCESS_DENIED || !port_name || object_attributes) |
+ return status; |
+ |
+ // We don't trust that the IPC can work this early. |
+ if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled()) |
+ return status; |
+ |
+ do { |
+ if (!ValidParameter(port_handle, sizeof(HANDLE), WRITE)) |
+ break; |
+ |
+ void* memory = GetGlobalIPCMemory(); |
+ if (memory == NULL) |
+ break; |
+ |
+ wchar_t* name = NULL; |
+ |
+ NTSTATUS ret = AllocAndCopyUnicodeString(port_name, &name); |
+ if (!NT_SUCCESS(ret) || name == NULL) |
+ break; |
+ |
+ ALPC_PORT_ATTRIBUTES copied_port_attributes = {0}; |
+ if (port_attributes) |
+ copied_port_attributes = *port_attributes; |
+ |
+ CrossCallReturn answer = {0}; |
+ answer.nt_status = status; |
+ CountedParameterSet<NameBased> params; |
+ params[NameBased::NAME] = ParamPickerMake(name); |
+ |
+ if (0 && !QueryBroker(IPC_NTCONNECTALPCPORT_TAG, params.GetBase())) |
+ return SBOX_ERROR_GENERIC; |
+ |
+ SharedMemIPCClient ipc(memory); |
+ ResultCode code = CrossCall(ipc, IPC_NTCONNECTALPCPORT_TAG, name, &answer); |
+ operator delete(name, NT_ALLOC); |
+ |
+ if (code != SBOX_ALL_OK) { |
+ status = answer.nt_status; |
+ break; |
+ } |
+ __try { |
+ *port_handle = answer.handle; |
+ status = STATUS_SUCCESS; |
+ } __except(EXCEPTION_EXECUTE_HANDLER) { |
+ break; |
+ } |
+ } while (false); |
+ |
+ return status; |
+} |
+ |
+} // namespace sandbox |