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