|
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 #ifndef SANDBOX_SRC_CROSSCALL_SERVER_H_ |
|
6 #define SANDBOX_SRC_CROSSCALL_SERVER_H_ |
|
7 |
|
8 #include <string> |
|
9 #include <vector> |
|
10 #include "base/basictypes.h" |
|
11 #include "base/callback.h" |
|
12 #include "sandbox/win/src/crosscall_params.h" |
|
13 |
|
14 // This is the IPC server interface for CrossCall: The IPC for the Sandbox |
|
15 // On the server, CrossCall needs two things: |
|
16 // 1) threads: Or better said, someone to provide them, that is what the |
|
17 // ThreadProvider interface is defined for. These thread(s) are |
|
18 // the ones that will actually execute the IPC data retrieval. |
|
19 // |
|
20 // 2) a dispatcher: This interface represents the way to route and process |
|
21 // an IPC call given the IPC tag. |
|
22 // |
|
23 // The other class included here CrossCallParamsEx is the server side version |
|
24 // of the CrossCallParams class of /sandbox/crosscall_params.h The difference |
|
25 // is that the sever version is paranoid about the correctness of the IPC |
|
26 // message and will do all sorts of verifications. |
|
27 // |
|
28 // A general diagram of the interaction is as follows: |
|
29 // |
|
30 // ------------ |
|
31 // | | |
|
32 // ThreadProvider <--(1)Register--| IPC | |
|
33 // | | Implemen | |
|
34 // | | -tation | |
|
35 // (2) | | OnMessage |
|
36 // IPC fired --callback ------>| |--(3)---> Dispatcher |
|
37 // | | |
|
38 // ------------ |
|
39 // |
|
40 // The IPC implementation sits as a middleman between the handling of the |
|
41 // specifics of scheduling a thread to service the IPC and the multiple |
|
42 // entities that can potentially serve each particular IPC. |
|
43 namespace sandbox { |
|
44 |
|
45 class InterceptionManager; |
|
46 |
|
47 // This function signature is required as the callback when an IPC call fires. |
|
48 // context: a user-defined pointer that was set using ThreadProvider |
|
49 // reason: 0 if the callback was fired because of a timeout. |
|
50 // 1 if the callback was fired because of an event. |
|
51 typedef void (__stdcall * CrossCallIPCCallback)(void* context, |
|
52 unsigned char reason); |
|
53 |
|
54 // ThreadProvider models a thread factory. The idea is to decouple thread |
|
55 // creation and lifetime from the inner guts of the IPC. The contract is |
|
56 // simple: |
|
57 // - the IPC implementation calls RegisterWait with a waitable object that |
|
58 // becomes signaled when an IPC arrives and needs to be serviced. |
|
59 // - when the waitable object becomes signaled, the thread provider conjures |
|
60 // a thread that calls the callback (CrossCallIPCCallback) function |
|
61 // - the callback function tries its best not to block and return quickly |
|
62 // and should not assume that the next callback will use the same thread |
|
63 // - when the callback returns the ThreadProvider owns again the thread |
|
64 // and can destroy it or keep it around. |
|
65 class ThreadProvider { |
|
66 public: |
|
67 // Registers a waitable object with the thread provider. |
|
68 // client: A number to associate with all the RegisterWait calls, typically |
|
69 // this is the address of the caller object. This parameter cannot |
|
70 // be zero. |
|
71 // waitable_object : a kernel object that can be waited on |
|
72 // callback: a function pointer which is the function that will be called |
|
73 // when the waitable object fires |
|
74 // context: a user-provider pointer that is passed back to the callback |
|
75 // when its called |
|
76 virtual bool RegisterWait(const void* client, HANDLE waitable_object, |
|
77 CrossCallIPCCallback callback, |
|
78 void* context) = 0; |
|
79 |
|
80 // Removes all the registrations done with the same cookie parameter. |
|
81 // This frees internal thread pool resources. |
|
82 virtual bool UnRegisterWaits(void* cookie) = 0; |
|
83 virtual ~ThreadProvider() {} |
|
84 }; |
|
85 |
|
86 // Models the server-side of the original input parameters. |
|
87 // Provides IPC buffer validation and it is capable of reading the parameters |
|
88 // out of the IPC buffer. |
|
89 class CrossCallParamsEx : public CrossCallParams { |
|
90 public: |
|
91 // Factory constructor. Pass an IPCbuffer (and buffer size) that contains a |
|
92 // pending IPCcall. This constructor will: |
|
93 // 1) validate the IPC buffer. returns NULL is the IPCbuffer is malformed. |
|
94 // 2) make a copy of the IPCbuffer (parameter capture) |
|
95 static CrossCallParamsEx* CreateFromBuffer(void* buffer_base, |
|
96 uint32 buffer_size, |
|
97 uint32* output_size); |
|
98 |
|
99 // Provides IPCinput parameter raw access: |
|
100 // index : the parameter to read; 0 is the first parameter |
|
101 // returns NULL if the parameter is non-existent. If it exists it also |
|
102 // returns the size in *size |
|
103 void* GetRawParameter(uint32 index, uint32* size, ArgType* type); |
|
104 |
|
105 // Gets a parameter that is four bytes in size. |
|
106 // Returns false if the parameter does not exist or is not 32 bits wide. |
|
107 bool GetParameter32(uint32 index, uint32* param); |
|
108 |
|
109 // Gets a parameter that is void pointer in size. |
|
110 // Returns false if the parameter does not exist or is not void pointer sized. |
|
111 bool GetParameterVoidPtr(uint32 index, void** param); |
|
112 |
|
113 // Gets a parameter that is a string. Returns false if the parameter does not |
|
114 // exist. |
|
115 bool GetParameterStr(uint32 index, std::wstring* string); |
|
116 |
|
117 // Gets a parameter that is an in/out buffer. Returns false is the parameter |
|
118 // does not exist or if the size of the actual parameter is not equal to the |
|
119 // expected size. |
|
120 bool GetParameterPtr(uint32 index, uint32 expected_size, void** pointer); |
|
121 |
|
122 // Frees the memory associated with the IPC parameters. |
|
123 static void operator delete(void* raw_memory) throw(); |
|
124 |
|
125 private: |
|
126 // Only the factory method CreateFromBuffer can construct these objects. |
|
127 CrossCallParamsEx(); |
|
128 |
|
129 ParamInfo param_info_[1]; |
|
130 DISALLOW_COPY_AND_ASSIGN(CrossCallParamsEx); |
|
131 }; |
|
132 |
|
133 // Simple helper function that sets the members of CrossCallReturn |
|
134 // to the proper state to signal a basic error. |
|
135 void SetCallError(ResultCode error, CrossCallReturn* call_return); |
|
136 |
|
137 // Sets the internal status of call_return to signify the that IPC call |
|
138 // completed successfully. |
|
139 void SetCallSuccess(CrossCallReturn* call_return); |
|
140 |
|
141 // Represents the client process that initiated the IPC which boils down to the |
|
142 // process handle and the job object handle that contains the client process. |
|
143 struct ClientInfo { |
|
144 HANDLE process; |
|
145 HANDLE job_object; |
|
146 DWORD process_id; |
|
147 }; |
|
148 |
|
149 // All IPC-related information to be passed to the IPC handler. |
|
150 struct IPCInfo { |
|
151 int ipc_tag; |
|
152 const ClientInfo* client_info; |
|
153 CrossCallReturn return_info; |
|
154 }; |
|
155 |
|
156 // This structure identifies IPC signatures. |
|
157 struct IPCParams { |
|
158 int ipc_tag; |
|
159 ArgType args[kMaxIpcParams]; |
|
160 |
|
161 bool Matches(IPCParams* other) const { |
|
162 return !memcmp(this, other, sizeof(*other)); |
|
163 } |
|
164 }; |
|
165 |
|
166 // Models an entity that can process an IPC message or it can route to another |
|
167 // one that could handle it. When an IPC arrives the IPC implementation will: |
|
168 // 1) call OnMessageReady() with the tag of the pending IPC. If the dispatcher |
|
169 // returns NULL it means that it cannot handle this IPC but if it returns |
|
170 // non-null, it must be the pointer to a dispatcher that can handle it. |
|
171 // 2) When the IPC finally obtains a valid Dispatcher the IPC |
|
172 // implementation creates a CrossCallParamsEx from the raw IPC buffer. |
|
173 // 3) It calls the returned callback, with the IPC info and arguments. |
|
174 class Dispatcher { |
|
175 public: |
|
176 // Called from the IPC implementation to handle a specific IPC message. |
|
177 typedef bool (Dispatcher::*CallbackGeneric)(); |
|
178 typedef bool (Dispatcher::*Callback0)(IPCInfo* ipc); |
|
179 typedef bool (Dispatcher::*Callback1)(IPCInfo* ipc, void* p1); |
|
180 typedef bool (Dispatcher::*Callback2)(IPCInfo* ipc, void* p1, void* p2); |
|
181 typedef bool (Dispatcher::*Callback3)(IPCInfo* ipc, void* p1, void* p2, |
|
182 void* p3); |
|
183 typedef bool (Dispatcher::*Callback4)(IPCInfo* ipc, void* p1, void* p2, |
|
184 void* p3, void* p4); |
|
185 typedef bool (Dispatcher::*Callback5)(IPCInfo* ipc, void* p1, void* p2, |
|
186 void* p3, void* p4, void* p5); |
|
187 typedef bool (Dispatcher::*Callback6)(IPCInfo* ipc, void* p1, void* p2, |
|
188 void* p3, void* p4, void* p5, void* p6); |
|
189 typedef bool (Dispatcher::*Callback7)(IPCInfo* ipc, void* p1, void* p2, |
|
190 void* p3, void* p4, void* p5, void* p6, |
|
191 void* p7); |
|
192 typedef bool (Dispatcher::*Callback8)(IPCInfo* ipc, void* p1, void* p2, |
|
193 void* p3, void* p4, void* p5, void* p6, |
|
194 void* p7, void* p8); |
|
195 typedef bool (Dispatcher::*Callback9)(IPCInfo* ipc, void* p1, void* p2, |
|
196 void* p3, void* p4, void* p5, void* p6, |
|
197 void* p7, void* p8, void* p9); |
|
198 |
|
199 // Called from the IPC implementation when an IPC message is ready override |
|
200 // on a derived class to handle a set of IPC messages. Return NULL if your |
|
201 // subclass does not handle the message or return the pointer to the subclass |
|
202 // that can handle it. |
|
203 virtual Dispatcher* OnMessageReady(IPCParams* ipc, CallbackGeneric* callback); |
|
204 |
|
205 // Called when a target proces is created, to setup the interceptions related |
|
206 // with the given service (IPC). |
|
207 virtual bool SetupService(InterceptionManager* manager, int service) = 0; |
|
208 |
|
209 virtual ~Dispatcher() {} |
|
210 |
|
211 protected: |
|
212 // Structure that defines an IPC Call with all the parameters and the handler. |
|
213 struct IPCCall { |
|
214 IPCParams params; |
|
215 CallbackGeneric callback; |
|
216 }; |
|
217 |
|
218 // List of IPC Calls supported by the class. |
|
219 std::vector<IPCCall> ipc_calls_; |
|
220 }; |
|
221 |
|
222 } // namespace sandbox |
|
223 |
|
224 #endif // SANDBOX_SRC_CROSSCALL_SERVER_H_ |