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