1 // Copyright (c) 2006-2008 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/sync_interception.h"
6
7 #include "sandbox/win/src/crosscall_client.h"
8 #include "sandbox/win/src/ipc_tags.h"
9 #include "sandbox/win/src/policy_params.h"
10 #include "sandbox/win/src/policy_target.h"
11 #include "sandbox/win/src/sandbox_factory.h"
12 #include "sandbox/win/src/sandbox_nt_util.h"
13 #include "sandbox/win/src/sharedmem_ipc_client.h"
14 #include "sandbox/win/src/target_services.h"
15
16 namespace sandbox {
17
ProxyCreateEvent(LPCWSTR name,BOOL initial_state,EVENT_TYPE event_type,void * ipc_memory,CrossCallReturn * answer)18 ResultCode ProxyCreateEvent(LPCWSTR name,
19 BOOL initial_state,
20 EVENT_TYPE event_type,
21 void* ipc_memory,
22 CrossCallReturn* answer) {
23 CountedParameterSet<NameBased> params;
24 params[NameBased::NAME] = ParamPickerMake(name);
25
26 if (!QueryBroker(IPC_CREATEEVENT_TAG, params.GetBase()))
27 return SBOX_ERROR_GENERIC;
28
29 SharedMemIPCClient ipc(ipc_memory);
30 ResultCode code = CrossCall(ipc, IPC_CREATEEVENT_TAG, name, event_type,
31 initial_state, answer);
32 return code;
33 }
34
ProxyOpenEvent(LPCWSTR name,ACCESS_MASK desired_access,void * ipc_memory,CrossCallReturn * answer)35 ResultCode ProxyOpenEvent(LPCWSTR name,
36 ACCESS_MASK desired_access,
37 void* ipc_memory,
38 CrossCallReturn* answer) {
39 CountedParameterSet<OpenEventParams> params;
40 params[OpenEventParams::NAME] = ParamPickerMake(name);
41 params[OpenEventParams::ACCESS] = ParamPickerMake(desired_access);
42
43 if (!QueryBroker(IPC_OPENEVENT_TAG, params.GetBase()))
44 return SBOX_ERROR_GENERIC;
45
46 SharedMemIPCClient ipc(ipc_memory);
47 ResultCode code = CrossCall(ipc, IPC_OPENEVENT_TAG, name, desired_access,
48 answer);
49
50 return code;
51 }
52
TargetNtCreateEvent(NtCreateEventFunction orig_CreateEvent,PHANDLE event_handle,ACCESS_MASK desired_access,POBJECT_ATTRIBUTES object_attributes,EVENT_TYPE event_type,BOOLEAN initial_state)53 NTSTATUS WINAPI TargetNtCreateEvent(NtCreateEventFunction orig_CreateEvent,
54 PHANDLE event_handle,
55 ACCESS_MASK desired_access,
56 POBJECT_ATTRIBUTES object_attributes,
57 EVENT_TYPE event_type,
58 BOOLEAN initial_state) {
59 NTSTATUS status = orig_CreateEvent(event_handle, desired_access,
60 object_attributes, event_type,
61 initial_state);
62 if (status != STATUS_ACCESS_DENIED || !object_attributes)
63 return status;
64
65 // We don't trust that the IPC can work this early.
66 if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
67 return status;
68
69 do {
70 if (!ValidParameter(event_handle, sizeof(HANDLE), WRITE))
71 break;
72
73 void* memory = GetGlobalIPCMemory();
74 if (memory == NULL)
75 break;
76
77 OBJECT_ATTRIBUTES object_attribs_copy = *object_attributes;
78 // The RootDirectory points to BaseNamedObjects. We can ignore it.
79 object_attribs_copy.RootDirectory = NULL;
80
81 wchar_t* name = NULL;
82 uint32 attributes = 0;
83 NTSTATUS ret = AllocAndCopyName(&object_attribs_copy, &name, &attributes,
84 NULL);
85 if (!NT_SUCCESS(ret) || name == NULL)
86 break;
87
88 CrossCallReturn answer = {0};
89 answer.nt_status = status;
90 ResultCode code = ProxyCreateEvent(name, initial_state, event_type, memory,
91 &answer);
92 operator delete(name, NT_ALLOC);
93
94 if (code != SBOX_ALL_OK) {
95 status = answer.nt_status;
96 break;
97 }
98 __try {
99 *event_handle = answer.handle;
100 status = STATUS_SUCCESS;
101 } __except(EXCEPTION_EXECUTE_HANDLER) {
102 break;
103 }
104 } while (false);
105
106 return status;
107 }
108
TargetNtOpenEvent(NtOpenEventFunction orig_OpenEvent,PHANDLE event_handle,ACCESS_MASK desired_access,POBJECT_ATTRIBUTES object_attributes)109 NTSTATUS WINAPI TargetNtOpenEvent(NtOpenEventFunction orig_OpenEvent,
110 PHANDLE event_handle,
111 ACCESS_MASK desired_access,
112 POBJECT_ATTRIBUTES object_attributes) {
113 NTSTATUS status = orig_OpenEvent(event_handle, desired_access,
114 object_attributes);
115 if (status != STATUS_ACCESS_DENIED || !object_attributes)
116 return status;
117
118 // We don't trust that the IPC can work this early.
119 if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
120 return status;
121
122 do {
123 if (!ValidParameter(event_handle, sizeof(HANDLE), WRITE))
124 break;
125
126 void* memory = GetGlobalIPCMemory();
127 if (memory == NULL)
128 break;
129
130 OBJECT_ATTRIBUTES object_attribs_copy = *object_attributes;
131 // The RootDirectory points to BaseNamedObjects. We can ignore it.
132 object_attribs_copy.RootDirectory = NULL;
133
134 wchar_t* name = NULL;
135 uint32 attributes = 0;
136 NTSTATUS ret = AllocAndCopyName(&object_attribs_copy, &name, &attributes,
137 NULL);
138 if (!NT_SUCCESS(ret) || name == NULL)
139 break;
140
141 CrossCallReturn answer = {0};
142 answer.nt_status = status;
143 ResultCode code = ProxyOpenEvent(name, desired_access, memory, &answer);
144 operator delete(name, NT_ALLOC);
145
146 if (code != SBOX_ALL_OK) {
147 status = answer.nt_status;
148 break;
149 }
150 __try {
151 *event_handle = answer.handle;
152 status = STATUS_SUCCESS;
153 } __except(EXCEPTION_EXECUTE_HANDLER) {
154 break;
155 }
156 } while (false);
157
158 return status;
159 }
160
161 } // namespace sandbox
162