blob: 2a395077db7d2fed75cde722dbd354c73af4ac17 [file] [log] [blame]
[email protected]eff7d9f2012-05-14 21:56:471// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commita814a8d52008-07-26 22:41:284
[email protected]df91e572008-10-08 21:29:435#ifndef SANDBOX_SRC_CROSSCALL_SERVER_H_
6#define SANDBOX_SRC_CROSSCALL_SERVER_H_
initial.commita814a8d52008-07-26 22:41:287
8#include <string>
9#include <vector>
[email protected]0d6cf242010-03-13 02:22:3210#include "base/basictypes.h"
[email protected]2041cf342010-02-19 03:15:5911#include "base/callback.h"
[email protected]181491782012-07-18 00:59:1512#include "sandbox/win/src/crosscall_params.h"
initial.commita814a8d52008-07-26 22:41:2813
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.
43namespace sandbox {
44
45class 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.
51typedef 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.
65class 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;
[email protected]df91e572008-10-08 21:29:4383 virtual ~ThreadProvider() {}
initial.commita814a8d52008-07-26 22:41:2884};
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.
89class 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,
[email protected]eff7d9f2012-05-14 21:56:4796 uint32 buffer_size,
97 uint32* output_size);
initial.commita814a8d52008-07-26 22:41:2898
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
[email protected]eff7d9f2012-05-14 21:56:47103 void* GetRawParameter(uint32 index, uint32* size, ArgType* type);
initial.commita814a8d52008-07-26 22:41:28104
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.
[email protected]eff7d9f2012-05-14 21:56:47107 bool GetParameter32(uint32 index, uint32* param);
[email protected]0d6cf242010-03-13 02:22:32108
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.
[email protected]eff7d9f2012-05-14 21:56:47111 bool GetParameterVoidPtr(uint32 index, void** param);
initial.commita814a8d52008-07-26 22:41:28112
113 // Gets a parameter that is a string. Returns false if the parameter does not
114 // exist.
[email protected]eff7d9f2012-05-14 21:56:47115 bool GetParameterStr(uint32 index, std::wstring* string);
initial.commita814a8d52008-07-26 22:41:28116
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.
[email protected]eff7d9f2012-05-14 21:56:47120 bool GetParameterPtr(uint32 index, uint32 expected_size, void** pointer);
initial.commita814a8d52008-07-26 22:41:28121
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];
[email protected]df91e572008-10-08 21:29:43130 DISALLOW_COPY_AND_ASSIGN(CrossCallParamsEx);
initial.commita814a8d52008-07-26 22:41:28131};
132
133// Simple helper function that sets the members of CrossCallReturn
134// to the proper state to signal a basic error.
135void SetCallError(ResultCode error, CrossCallReturn* call_return);
136
137// Sets the internal status of call_return to signify the that IPC call
138// completed successfully.
139void 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.
143struct 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.
150struct IPCInfo {
151 int ipc_tag;
152 const ClientInfo* client_info;
153 CrossCallReturn return_info;
154};
155
156// This structure identifies IPC signatures.
157struct 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.
174class 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
[email protected]df91e572008-10-08 21:29:43224#endif // SANDBOX_SRC_CROSSCALL_SERVER_H_