1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/sandbox/win/src/crosscall_server.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,224 @@ 1.4 +// Copyright (c) 2012 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#ifndef SANDBOX_SRC_CROSSCALL_SERVER_H_ 1.9 +#define SANDBOX_SRC_CROSSCALL_SERVER_H_ 1.10 + 1.11 +#include <string> 1.12 +#include <vector> 1.13 +#include "base/basictypes.h" 1.14 +#include "base/callback.h" 1.15 +#include "sandbox/win/src/crosscall_params.h" 1.16 + 1.17 +// This is the IPC server interface for CrossCall: The IPC for the Sandbox 1.18 +// On the server, CrossCall needs two things: 1.19 +// 1) threads: Or better said, someone to provide them, that is what the 1.20 +// ThreadProvider interface is defined for. These thread(s) are 1.21 +// the ones that will actually execute the IPC data retrieval. 1.22 +// 1.23 +// 2) a dispatcher: This interface represents the way to route and process 1.24 +// an IPC call given the IPC tag. 1.25 +// 1.26 +// The other class included here CrossCallParamsEx is the server side version 1.27 +// of the CrossCallParams class of /sandbox/crosscall_params.h The difference 1.28 +// is that the sever version is paranoid about the correctness of the IPC 1.29 +// message and will do all sorts of verifications. 1.30 +// 1.31 +// A general diagram of the interaction is as follows: 1.32 +// 1.33 +// ------------ 1.34 +// | | 1.35 +// ThreadProvider <--(1)Register--| IPC | 1.36 +// | | Implemen | 1.37 +// | | -tation | 1.38 +// (2) | | OnMessage 1.39 +// IPC fired --callback ------>| |--(3)---> Dispatcher 1.40 +// | | 1.41 +// ------------ 1.42 +// 1.43 +// The IPC implementation sits as a middleman between the handling of the 1.44 +// specifics of scheduling a thread to service the IPC and the multiple 1.45 +// entities that can potentially serve each particular IPC. 1.46 +namespace sandbox { 1.47 + 1.48 +class InterceptionManager; 1.49 + 1.50 +// This function signature is required as the callback when an IPC call fires. 1.51 +// context: a user-defined pointer that was set using ThreadProvider 1.52 +// reason: 0 if the callback was fired because of a timeout. 1.53 +// 1 if the callback was fired because of an event. 1.54 +typedef void (__stdcall * CrossCallIPCCallback)(void* context, 1.55 + unsigned char reason); 1.56 + 1.57 +// ThreadProvider models a thread factory. The idea is to decouple thread 1.58 +// creation and lifetime from the inner guts of the IPC. The contract is 1.59 +// simple: 1.60 +// - the IPC implementation calls RegisterWait with a waitable object that 1.61 +// becomes signaled when an IPC arrives and needs to be serviced. 1.62 +// - when the waitable object becomes signaled, the thread provider conjures 1.63 +// a thread that calls the callback (CrossCallIPCCallback) function 1.64 +// - the callback function tries its best not to block and return quickly 1.65 +// and should not assume that the next callback will use the same thread 1.66 +// - when the callback returns the ThreadProvider owns again the thread 1.67 +// and can destroy it or keep it around. 1.68 +class ThreadProvider { 1.69 + public: 1.70 + // Registers a waitable object with the thread provider. 1.71 + // client: A number to associate with all the RegisterWait calls, typically 1.72 + // this is the address of the caller object. This parameter cannot 1.73 + // be zero. 1.74 + // waitable_object : a kernel object that can be waited on 1.75 + // callback: a function pointer which is the function that will be called 1.76 + // when the waitable object fires 1.77 + // context: a user-provider pointer that is passed back to the callback 1.78 + // when its called 1.79 + virtual bool RegisterWait(const void* client, HANDLE waitable_object, 1.80 + CrossCallIPCCallback callback, 1.81 + void* context) = 0; 1.82 + 1.83 + // Removes all the registrations done with the same cookie parameter. 1.84 + // This frees internal thread pool resources. 1.85 + virtual bool UnRegisterWaits(void* cookie) = 0; 1.86 + virtual ~ThreadProvider() {} 1.87 +}; 1.88 + 1.89 +// Models the server-side of the original input parameters. 1.90 +// Provides IPC buffer validation and it is capable of reading the parameters 1.91 +// out of the IPC buffer. 1.92 +class CrossCallParamsEx : public CrossCallParams { 1.93 + public: 1.94 + // Factory constructor. Pass an IPCbuffer (and buffer size) that contains a 1.95 + // pending IPCcall. This constructor will: 1.96 + // 1) validate the IPC buffer. returns NULL is the IPCbuffer is malformed. 1.97 + // 2) make a copy of the IPCbuffer (parameter capture) 1.98 + static CrossCallParamsEx* CreateFromBuffer(void* buffer_base, 1.99 + uint32 buffer_size, 1.100 + uint32* output_size); 1.101 + 1.102 + // Provides IPCinput parameter raw access: 1.103 + // index : the parameter to read; 0 is the first parameter 1.104 + // returns NULL if the parameter is non-existent. If it exists it also 1.105 + // returns the size in *size 1.106 + void* GetRawParameter(uint32 index, uint32* size, ArgType* type); 1.107 + 1.108 + // Gets a parameter that is four bytes in size. 1.109 + // Returns false if the parameter does not exist or is not 32 bits wide. 1.110 + bool GetParameter32(uint32 index, uint32* param); 1.111 + 1.112 + // Gets a parameter that is void pointer in size. 1.113 + // Returns false if the parameter does not exist or is not void pointer sized. 1.114 + bool GetParameterVoidPtr(uint32 index, void** param); 1.115 + 1.116 + // Gets a parameter that is a string. Returns false if the parameter does not 1.117 + // exist. 1.118 + bool GetParameterStr(uint32 index, std::wstring* string); 1.119 + 1.120 + // Gets a parameter that is an in/out buffer. Returns false is the parameter 1.121 + // does not exist or if the size of the actual parameter is not equal to the 1.122 + // expected size. 1.123 + bool GetParameterPtr(uint32 index, uint32 expected_size, void** pointer); 1.124 + 1.125 + // Frees the memory associated with the IPC parameters. 1.126 + static void operator delete(void* raw_memory) throw(); 1.127 + 1.128 + private: 1.129 + // Only the factory method CreateFromBuffer can construct these objects. 1.130 + CrossCallParamsEx(); 1.131 + 1.132 + ParamInfo param_info_[1]; 1.133 + DISALLOW_COPY_AND_ASSIGN(CrossCallParamsEx); 1.134 +}; 1.135 + 1.136 +// Simple helper function that sets the members of CrossCallReturn 1.137 +// to the proper state to signal a basic error. 1.138 +void SetCallError(ResultCode error, CrossCallReturn* call_return); 1.139 + 1.140 +// Sets the internal status of call_return to signify the that IPC call 1.141 +// completed successfully. 1.142 +void SetCallSuccess(CrossCallReturn* call_return); 1.143 + 1.144 +// Represents the client process that initiated the IPC which boils down to the 1.145 +// process handle and the job object handle that contains the client process. 1.146 +struct ClientInfo { 1.147 + HANDLE process; 1.148 + HANDLE job_object; 1.149 + DWORD process_id; 1.150 +}; 1.151 + 1.152 +// All IPC-related information to be passed to the IPC handler. 1.153 +struct IPCInfo { 1.154 + int ipc_tag; 1.155 + const ClientInfo* client_info; 1.156 + CrossCallReturn return_info; 1.157 +}; 1.158 + 1.159 +// This structure identifies IPC signatures. 1.160 +struct IPCParams { 1.161 + int ipc_tag; 1.162 + ArgType args[kMaxIpcParams]; 1.163 + 1.164 + bool Matches(IPCParams* other) const { 1.165 + return !memcmp(this, other, sizeof(*other)); 1.166 + } 1.167 +}; 1.168 + 1.169 +// Models an entity that can process an IPC message or it can route to another 1.170 +// one that could handle it. When an IPC arrives the IPC implementation will: 1.171 +// 1) call OnMessageReady() with the tag of the pending IPC. If the dispatcher 1.172 +// returns NULL it means that it cannot handle this IPC but if it returns 1.173 +// non-null, it must be the pointer to a dispatcher that can handle it. 1.174 +// 2) When the IPC finally obtains a valid Dispatcher the IPC 1.175 +// implementation creates a CrossCallParamsEx from the raw IPC buffer. 1.176 +// 3) It calls the returned callback, with the IPC info and arguments. 1.177 +class Dispatcher { 1.178 + public: 1.179 + // Called from the IPC implementation to handle a specific IPC message. 1.180 + typedef bool (Dispatcher::*CallbackGeneric)(); 1.181 + typedef bool (Dispatcher::*Callback0)(IPCInfo* ipc); 1.182 + typedef bool (Dispatcher::*Callback1)(IPCInfo* ipc, void* p1); 1.183 + typedef bool (Dispatcher::*Callback2)(IPCInfo* ipc, void* p1, void* p2); 1.184 + typedef bool (Dispatcher::*Callback3)(IPCInfo* ipc, void* p1, void* p2, 1.185 + void* p3); 1.186 + typedef bool (Dispatcher::*Callback4)(IPCInfo* ipc, void* p1, void* p2, 1.187 + void* p3, void* p4); 1.188 + typedef bool (Dispatcher::*Callback5)(IPCInfo* ipc, void* p1, void* p2, 1.189 + void* p3, void* p4, void* p5); 1.190 + typedef bool (Dispatcher::*Callback6)(IPCInfo* ipc, void* p1, void* p2, 1.191 + void* p3, void* p4, void* p5, void* p6); 1.192 + typedef bool (Dispatcher::*Callback7)(IPCInfo* ipc, void* p1, void* p2, 1.193 + void* p3, void* p4, void* p5, void* p6, 1.194 + void* p7); 1.195 + typedef bool (Dispatcher::*Callback8)(IPCInfo* ipc, void* p1, void* p2, 1.196 + void* p3, void* p4, void* p5, void* p6, 1.197 + void* p7, void* p8); 1.198 + typedef bool (Dispatcher::*Callback9)(IPCInfo* ipc, void* p1, void* p2, 1.199 + void* p3, void* p4, void* p5, void* p6, 1.200 + void* p7, void* p8, void* p9); 1.201 + 1.202 + // Called from the IPC implementation when an IPC message is ready override 1.203 + // on a derived class to handle a set of IPC messages. Return NULL if your 1.204 + // subclass does not handle the message or return the pointer to the subclass 1.205 + // that can handle it. 1.206 + virtual Dispatcher* OnMessageReady(IPCParams* ipc, CallbackGeneric* callback); 1.207 + 1.208 + // Called when a target proces is created, to setup the interceptions related 1.209 + // with the given service (IPC). 1.210 + virtual bool SetupService(InterceptionManager* manager, int service) = 0; 1.211 + 1.212 + virtual ~Dispatcher() {} 1.213 + 1.214 + protected: 1.215 + // Structure that defines an IPC Call with all the parameters and the handler. 1.216 + struct IPCCall { 1.217 + IPCParams params; 1.218 + CallbackGeneric callback; 1.219 + }; 1.220 + 1.221 + // List of IPC Calls supported by the class. 1.222 + std::vector<IPCCall> ipc_calls_; 1.223 +}; 1.224 + 1.225 +} // namespace sandbox 1.226 + 1.227 +#endif // SANDBOX_SRC_CROSSCALL_SERVER_H_