security/sandbox/win/src/crosscall_server.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial