|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
|
2 // Use of this source code is governed by a BSD-style license that can be |
|
3 // found in the LICENSE file. |
|
4 |
|
5 #include "sandbox/win/src/handle_dispatcher.h" |
|
6 |
|
7 #include "base/win/scoped_handle.h" |
|
8 #include "sandbox/win/src/handle_interception.h" |
|
9 #include "sandbox/win/src/handle_policy.h" |
|
10 #include "sandbox/win/src/ipc_tags.h" |
|
11 #include "sandbox/win/src/policy_broker.h" |
|
12 #include "sandbox/win/src/policy_params.h" |
|
13 #include "sandbox/win/src/sandbox.h" |
|
14 #include "sandbox/win/src/sandbox_nt_util.h" |
|
15 #include "sandbox/win/src/sandbox_types.h" |
|
16 #include "sandbox/win/src/sandbox_utils.h" |
|
17 |
|
18 namespace sandbox { |
|
19 |
|
20 HandleDispatcher::HandleDispatcher(PolicyBase* policy_base) |
|
21 : policy_base_(policy_base) { |
|
22 static const IPCCall duplicate_handle_proxy = { |
|
23 {IPC_DUPLICATEHANDLEPROXY_TAG, VOIDPTR_TYPE, ULONG_TYPE, ULONG_TYPE, |
|
24 ULONG_TYPE}, |
|
25 reinterpret_cast<CallbackGeneric>(&HandleDispatcher::DuplicateHandleProxy) |
|
26 }; |
|
27 |
|
28 ipc_calls_.push_back(duplicate_handle_proxy); |
|
29 } |
|
30 |
|
31 bool HandleDispatcher::SetupService(InterceptionManager* manager, |
|
32 int service) { |
|
33 // We perform no interceptions for handles right now. |
|
34 switch (service) { |
|
35 case IPC_DUPLICATEHANDLEPROXY_TAG: |
|
36 return true; |
|
37 } |
|
38 |
|
39 return false; |
|
40 } |
|
41 |
|
42 bool HandleDispatcher::DuplicateHandleProxy(IPCInfo* ipc, |
|
43 HANDLE source_handle, |
|
44 DWORD target_process_id, |
|
45 DWORD desired_access, |
|
46 DWORD options) { |
|
47 NTSTATUS error; |
|
48 static NtQueryObject QueryObject = NULL; |
|
49 if (!QueryObject) |
|
50 ResolveNTFunctionPtr("NtQueryObject", &QueryObject); |
|
51 |
|
52 // Get a copy of the handle for use in the broker process. |
|
53 HANDLE handle_temp; |
|
54 if (!::DuplicateHandle(ipc->client_info->process, source_handle, |
|
55 ::GetCurrentProcess(), &handle_temp, |
|
56 0, FALSE, DUPLICATE_SAME_ACCESS)) { |
|
57 ipc->return_info.win32_result = ::GetLastError(); |
|
58 return false; |
|
59 } |
|
60 base::win::ScopedHandle handle(handle_temp); |
|
61 |
|
62 // Get the object type (32 characters is safe; current max is 14). |
|
63 BYTE buffer[sizeof(OBJECT_TYPE_INFORMATION) + 32 * sizeof(wchar_t)]; |
|
64 OBJECT_TYPE_INFORMATION* type_info = |
|
65 reinterpret_cast<OBJECT_TYPE_INFORMATION*>(buffer); |
|
66 ULONG size = sizeof(buffer) - sizeof(wchar_t); |
|
67 error = QueryObject(handle, ObjectTypeInformation, type_info, size, &size); |
|
68 if (!NT_SUCCESS(error)) { |
|
69 ipc->return_info.win32_result = error; |
|
70 return false; |
|
71 } |
|
72 type_info->Name.Buffer[type_info->Name.Length / sizeof(wchar_t)] = L'\0'; |
|
73 |
|
74 CountedParameterSet<HandleTarget> params; |
|
75 params[HandleTarget::NAME] = ParamPickerMake(type_info->Name.Buffer); |
|
76 params[HandleTarget::TARGET] = ParamPickerMake(target_process_id); |
|
77 |
|
78 EvalResult eval = policy_base_->EvalPolicy(IPC_DUPLICATEHANDLEPROXY_TAG, |
|
79 params.GetBase()); |
|
80 ipc->return_info.win32_result = |
|
81 HandlePolicy::DuplicateHandleProxyAction(eval, *ipc->client_info, |
|
82 source_handle, |
|
83 target_process_id, |
|
84 &ipc->return_info.handle, |
|
85 desired_access, options); |
|
86 return true; |
|
87 } |
|
88 |
|
89 } // namespace sandbox |
|
90 |