security/sandbox/win/src/crosscall_server.h

changeset 0
6474c204b198
     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_

mercurial