| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef SANDBOX_SRC_CROSSCALL_PARAMS_H__ | 5 #ifndef SANDBOX_SRC_CROSSCALL_PARAMS_H__ |
| 6 #define SANDBOX_SRC_CROSSCALL_PARAMS_H__ | 6 #define SANDBOX_SRC_CROSSCALL_PARAMS_H__ |
| 7 | 7 |
| 8 #include <windows.h> | 8 #include <windows.h> |
| 9 #include <lmaccess.h> | 9 #include <lmaccess.h> |
| 10 #include <stdint.h> |
| 10 | 11 |
| 11 #include <memory> | 12 #include <memory> |
| 12 | 13 |
| 13 #include "base/basictypes.h" | 14 #include "base/basictypes.h" |
| 14 #include "sandbox/win/src/internal_types.h" | 15 #include "sandbox/win/src/internal_types.h" |
| 15 #include "sandbox/win/src/sandbox_types.h" | 16 #include "sandbox/win/src/sandbox_types.h" |
| 16 | 17 |
| 17 // Increases |value| until there is no need for padding given an int64 | 18 // Increases |value| until there is no need for padding given an int64_t |
| 18 // alignment. Returns the increased value. | 19 // alignment. Returns the increased value. |
| 19 inline uint32 Align(uint32 value) { | 20 inline uint32_t Align(uint32_t value) { |
| 20 uint32 alignment = sizeof(int64); | 21 uint32_t alignment = sizeof(int64_t); |
| 21 return ((value + alignment - 1) / alignment) * alignment; | 22 return ((value + alignment - 1) / alignment) * alignment; |
| 22 } | 23 } |
| 23 | 24 |
| 24 // This header is part of CrossCall: the sandbox inter-process communication. | 25 // This header is part of CrossCall: the sandbox inter-process communication. |
| 25 // This header defines the basic types used both in the client IPC and in the | 26 // This header defines the basic types used both in the client IPC and in the |
| 26 // server IPC code. CrossCallParams and ActualCallParams model the input | 27 // server IPC code. CrossCallParams and ActualCallParams model the input |
| 27 // parameters of an IPC call and CrossCallReturn models the output params and | 28 // parameters of an IPC call and CrossCallReturn models the output params and |
| 28 // the return value. | 29 // the return value. |
| 29 // | 30 // |
| 30 // An IPC call is defined by its 'tag' which is a (uint32) unique identifier | 31 // An IPC call is defined by its 'tag' which is a (uint32_t) unique identifier |
| 31 // that is used to route the IPC call to the proper server. Every tag implies | 32 // that is used to route the IPC call to the proper server. Every tag implies |
| 32 // a complete call signature including the order and type of each parameter. | 33 // a complete call signature including the order and type of each parameter. |
| 33 // | 34 // |
| 34 // Like most IPC systems. CrossCall is designed to take as inputs 'simple' | 35 // Like most IPC systems. CrossCall is designed to take as inputs 'simple' |
| 35 // types such as integers and strings. Classes, generic arrays or pointers to | 36 // types such as integers and strings. Classes, generic arrays or pointers to |
| 36 // them are not supported. | 37 // them are not supported. |
| 37 // | 38 // |
| 38 // Another limitation of CrossCall is that the return value and output | 39 // Another limitation of CrossCall is that the return value and output |
| 39 // parameters can only be uint32 integers. Returning complex structures or | 40 // parameters can only be uint32_t integers. Returning complex structures or |
| 40 // strings is not supported. | 41 // strings is not supported. |
| 41 | 42 |
| 42 namespace sandbox { | 43 namespace sandbox { |
| 43 | 44 |
| 44 // max number of extended return parameters. See CrossCallReturn | 45 // max number of extended return parameters. See CrossCallReturn |
| 45 const size_t kExtendedReturnCount = 8; | 46 const size_t kExtendedReturnCount = 8; |
| 46 | 47 |
| 47 // Union of multiple types to be used as extended results | 48 // Union of multiple types to be used as extended results |
| 48 // in the CrossCallReturn. | 49 // in the CrossCallReturn. |
| 49 union MultiType { | 50 union MultiType { |
| 50 uint32 unsigned_int; | 51 uint32_t unsigned_int; |
| 51 void* pointer; | 52 void* pointer; |
| 52 HANDLE handle; | 53 HANDLE handle; |
| 53 ULONG_PTR ulong_ptr; | 54 ULONG_PTR ulong_ptr; |
| 54 }; | 55 }; |
| 55 | 56 |
| 56 // Maximum number of IPC parameters currently supported. | 57 // Maximum number of IPC parameters currently supported. |
| 57 // To increase this value, we have to: | 58 // To increase this value, we have to: |
| 58 // - Add another Callback typedef to Dispatcher. | 59 // - Add another Callback typedef to Dispatcher. |
| 59 // - Add another case to the switch on SharedMemIPCServer::InvokeCallback. | 60 // - Add another case to the switch on SharedMemIPCServer::InvokeCallback. |
| 60 // - Add another case to the switch in GetActualAndMaxBufferSize | 61 // - Add another case to the switch in GetActualAndMaxBufferSize |
| 61 const int kMaxIpcParams = 9; | 62 const int kMaxIpcParams = 9; |
| 62 | 63 |
| 63 // Contains the information about a parameter in the ipc buffer. | 64 // Contains the information about a parameter in the ipc buffer. |
| 64 struct ParamInfo { | 65 struct ParamInfo { |
| 65 ArgType type_; | 66 ArgType type_; |
| 66 uint32 offset_; | 67 uint32_t offset_; |
| 67 uint32 size_; | 68 uint32_t size_; |
| 68 }; | 69 }; |
| 69 | 70 |
| 70 // Models the return value and the return parameters of an IPC call | 71 // Models the return value and the return parameters of an IPC call |
| 71 // currently limited to one status code and eight generic return values | 72 // currently limited to one status code and eight generic return values |
| 72 // which cannot be pointers to other data. For x64 ports this structure | 73 // which cannot be pointers to other data. For x64 ports this structure |
| 73 // might have to use other integer types. | 74 // might have to use other integer types. |
| 74 struct CrossCallReturn { | 75 struct CrossCallReturn { |
| 75 // the IPC tag. It should match the original IPC tag. | 76 // the IPC tag. It should match the original IPC tag. |
| 76 uint32 tag; | 77 uint32_t tag; |
| 77 // The result of the IPC operation itself. | 78 // The result of the IPC operation itself. |
| 78 ResultCode call_outcome; | 79 ResultCode call_outcome; |
| 79 // the result of the IPC call as executed in the server. The interpretation | 80 // the result of the IPC call as executed in the server. The interpretation |
| 80 // of this value depends on the specific service. | 81 // of this value depends on the specific service. |
| 81 union { | 82 union { |
| 82 NTSTATUS nt_status; | 83 NTSTATUS nt_status; |
| 83 DWORD win32_result; | 84 DWORD win32_result; |
| 84 }; | 85 }; |
| 85 // Number of extended return values. | 86 // Number of extended return values. |
| 86 uint32 extended_count; | 87 uint32_t extended_count; |
| 87 // for calls that should return a windows handle. It is found here. | 88 // for calls that should return a windows handle. It is found here. |
| 88 HANDLE handle; | 89 HANDLE handle; |
| 89 // The array of extended values. | 90 // The array of extended values. |
| 90 MultiType extended[kExtendedReturnCount]; | 91 MultiType extended[kExtendedReturnCount]; |
| 91 }; | 92 }; |
| 92 | 93 |
| 93 // CrossCallParams base class that models the input params all packed in a | 94 // CrossCallParams base class that models the input params all packed in a |
| 94 // single compact memory blob. The representation can vary but in general a | 95 // single compact memory blob. The representation can vary but in general a |
| 95 // given child of this class is meant to represent all input parameters | 96 // given child of this class is meant to represent all input parameters |
| 96 // necessary to make a IPC call. | 97 // necessary to make a IPC call. |
| 97 // | 98 // |
| 98 // This class cannot have virtual members because its assumed the IPC | 99 // This class cannot have virtual members because its assumed the IPC |
| 99 // parameters start from the 'this' pointer to the end, which is defined by | 100 // parameters start from the 'this' pointer to the end, which is defined by |
| 100 // one of the subclasses | 101 // one of the subclasses |
| 101 // | 102 // |
| 102 // Objects of this class cannot be constructed directly. Only derived | 103 // Objects of this class cannot be constructed directly. Only derived |
| 103 // classes have the proper knowledge to construct it. | 104 // classes have the proper knowledge to construct it. |
| 104 class CrossCallParams { | 105 class CrossCallParams { |
| 105 public: | 106 public: |
| 106 // Returns the tag (ipc unique id) associated with this IPC. | 107 // Returns the tag (ipc unique id) associated with this IPC. |
| 107 uint32 GetTag() const { | 108 uint32_t GetTag() const { return tag_; } |
| 108 return tag_; | |
| 109 } | |
| 110 | 109 |
| 111 // Returns the beggining of the buffer where the IPC params can be stored. | 110 // Returns the beggining of the buffer where the IPC params can be stored. |
| 112 // prior to an IPC call | 111 // prior to an IPC call |
| 113 const void* GetBuffer() const { | 112 const void* GetBuffer() const { |
| 114 return this; | 113 return this; |
| 115 } | 114 } |
| 116 | 115 |
| 117 // Returns how many parameter this IPC call should have. | 116 // Returns how many parameter this IPC call should have. |
| 118 const uint32 GetParamsCount() const { | 117 const uint32_t GetParamsCount() const { return params_count_; } |
| 119 return params_count_; | |
| 120 } | |
| 121 | 118 |
| 122 // Returns a pointer to the CrossCallReturn structure. | 119 // Returns a pointer to the CrossCallReturn structure. |
| 123 CrossCallReturn* GetCallReturn() { | 120 CrossCallReturn* GetCallReturn() { |
| 124 return &call_return; | 121 return &call_return; |
| 125 } | 122 } |
| 126 | 123 |
| 127 // Returns TRUE if this call contains InOut parameters. | 124 // Returns TRUE if this call contains InOut parameters. |
| 128 const bool IsInOut() const { | 125 const bool IsInOut() const { |
| 129 return (1 == is_in_out_); | 126 return (1 == is_in_out_); |
| 130 } | 127 } |
| 131 | 128 |
| 132 // Tells the CrossCall object if it contains InOut parameters. | 129 // Tells the CrossCall object if it contains InOut parameters. |
| 133 void SetIsInOut(bool value) { | 130 void SetIsInOut(bool value) { |
| 134 if (value) | 131 if (value) |
| 135 is_in_out_ = 1; | 132 is_in_out_ = 1; |
| 136 else | 133 else |
| 137 is_in_out_ = 0; | 134 is_in_out_ = 0; |
| 138 } | 135 } |
| 139 | 136 |
| 140 protected: | 137 protected: |
| 141 // constructs the IPC call params. Called only from the derived classes | 138 // constructs the IPC call params. Called only from the derived classes |
| 142 CrossCallParams(uint32 tag, uint32 params_count) | 139 CrossCallParams(uint32_t tag, uint32_t params_count) |
| 143 : tag_(tag), is_in_out_(0), params_count_(params_count) {} | 140 : tag_(tag), is_in_out_(0), params_count_(params_count) {} |
| 144 | 141 |
| 145 private: | 142 private: |
| 146 uint32 tag_; | 143 uint32_t tag_; |
| 147 uint32 is_in_out_; | 144 uint32_t is_in_out_; |
| 148 CrossCallReturn call_return; | 145 CrossCallReturn call_return; |
| 149 const uint32 params_count_; | 146 const uint32_t params_count_; |
| 150 DISALLOW_COPY_AND_ASSIGN(CrossCallParams); | 147 DISALLOW_COPY_AND_ASSIGN(CrossCallParams); |
| 151 }; | 148 }; |
| 152 | 149 |
| 153 // ActualCallParams models an specific IPC call parameters with respect to the | 150 // ActualCallParams models an specific IPC call parameters with respect to the |
| 154 // storage allocation that the packed parameters should need. | 151 // storage allocation that the packed parameters should need. |
| 155 // NUMBER_PARAMS: the number of parameters, valid from 1 to N | 152 // NUMBER_PARAMS: the number of parameters, valid from 1 to N |
| 156 // BLOCK_SIZE: the total storage that the NUMBER_PARAMS parameters can take, | 153 // BLOCK_SIZE: the total storage that the NUMBER_PARAMS parameters can take, |
| 157 // typically the block size is defined by the channel size of the underlying | 154 // typically the block size is defined by the channel size of the underlying |
| 158 // ipc mechanism. | 155 // ipc mechanism. |
| 159 // In practice this class is used to levergage C++ capacity to properly | 156 // In practice this class is used to levergage C++ capacity to properly |
| (...skipping 25 matching lines...) Expand all Loading... |
| 185 // | 182 // |
| 186 // Note that the actual number of params is NUMBER_PARAMS + 1 | 183 // Note that the actual number of params is NUMBER_PARAMS + 1 |
| 187 // so that the size of each actual param can be computed from the difference | 184 // so that the size of each actual param can be computed from the difference |
| 188 // between one parameter and the next down. The offset of the last param | 185 // between one parameter and the next down. The offset of the last param |
| 189 // points to the end of the buffer and the type and size are undefined. | 186 // points to the end of the buffer and the type and size are undefined. |
| 190 // | 187 // |
| 191 template <size_t NUMBER_PARAMS, size_t BLOCK_SIZE> | 188 template <size_t NUMBER_PARAMS, size_t BLOCK_SIZE> |
| 192 class ActualCallParams : public CrossCallParams { | 189 class ActualCallParams : public CrossCallParams { |
| 193 public: | 190 public: |
| 194 // constructor. Pass the ipc unique tag as input | 191 // constructor. Pass the ipc unique tag as input |
| 195 explicit ActualCallParams(uint32 tag) | 192 explicit ActualCallParams(uint32_t tag) |
| 196 : CrossCallParams(tag, NUMBER_PARAMS) { | 193 : CrossCallParams(tag, NUMBER_PARAMS) { |
| 197 param_info_[0].offset_ = | 194 param_info_[0].offset_ = |
| 198 static_cast<uint32>(parameters_ - reinterpret_cast<char*>(this)); | 195 static_cast<uint32_t>(parameters_ - reinterpret_cast<char*>(this)); |
| 199 } | 196 } |
| 200 | 197 |
| 201 // Testing-only constructor. Allows setting the |number_params| to a | 198 // Testing-only constructor. Allows setting the |number_params| to a |
| 202 // wrong value. | 199 // wrong value. |
| 203 ActualCallParams(uint32 tag, uint32 number_params) | 200 ActualCallParams(uint32_t tag, uint32_t number_params) |
| 204 : CrossCallParams(tag, number_params) { | 201 : CrossCallParams(tag, number_params) { |
| 205 param_info_[0].offset_ = | 202 param_info_[0].offset_ = |
| 206 static_cast<uint32>(parameters_ - reinterpret_cast<char*>(this)); | 203 static_cast<uint32_t>(parameters_ - reinterpret_cast<char*>(this)); |
| 207 } | 204 } |
| 208 | 205 |
| 209 // Testing-only method. Allows setting the apparent size to a wrong value. | 206 // Testing-only method. Allows setting the apparent size to a wrong value. |
| 210 // returns the previous size. | 207 // returns the previous size. |
| 211 uint32 OverrideSize(uint32 new_size) { | 208 uint32_t OverrideSize(uint32_t new_size) { |
| 212 uint32 previous_size = param_info_[NUMBER_PARAMS].offset_; | 209 uint32_t previous_size = param_info_[NUMBER_PARAMS].offset_; |
| 213 param_info_[NUMBER_PARAMS].offset_ = new_size; | 210 param_info_[NUMBER_PARAMS].offset_ = new_size; |
| 214 return previous_size; | 211 return previous_size; |
| 215 } | 212 } |
| 216 | 213 |
| 217 // Copies each paramter into the internal buffer. For each you must supply: | 214 // Copies each paramter into the internal buffer. For each you must supply: |
| 218 // index: 0 for the first param, 1 for the next an so on | 215 // index: 0 for the first param, 1 for the next an so on |
| 219 bool CopyParamIn(uint32 index, const void* parameter_address, uint32 size, | 216 bool CopyParamIn(uint32_t index, |
| 220 bool is_in_out, ArgType type) { | 217 const void* parameter_address, |
| 218 uint32_t size, |
| 219 bool is_in_out, |
| 220 ArgType type) { |
| 221 if (index >= NUMBER_PARAMS) { | 221 if (index >= NUMBER_PARAMS) { |
| 222 return false; | 222 return false; |
| 223 } | 223 } |
| 224 | 224 |
| 225 if (kuint32max == size) { | 225 if (UINT32_MAX == size) { |
| 226 // Memory error while getting the size. | 226 // Memory error while getting the size. |
| 227 return false; | 227 return false; |
| 228 } | 228 } |
| 229 | 229 |
| 230 if (size && !parameter_address) { | 230 if (size && !parameter_address) { |
| 231 return false; | 231 return false; |
| 232 } | 232 } |
| 233 | 233 |
| 234 if ((size > sizeof(*this)) || | 234 if ((size > sizeof(*this)) || |
| 235 (param_info_[index].offset_ > (sizeof(*this) - size))) { | 235 (param_info_[index].offset_ > (sizeof(*this) - size))) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 260 return true; | 260 return true; |
| 261 } | 261 } |
| 262 | 262 |
| 263 // Returns a pointer to a parameter in the memory section. | 263 // Returns a pointer to a parameter in the memory section. |
| 264 void* GetParamPtr(size_t index) { | 264 void* GetParamPtr(size_t index) { |
| 265 return reinterpret_cast<char*>(this) + param_info_[index].offset_; | 265 return reinterpret_cast<char*>(this) + param_info_[index].offset_; |
| 266 } | 266 } |
| 267 | 267 |
| 268 // Returns the total size of the buffer. Only valid once all the paramters | 268 // Returns the total size of the buffer. Only valid once all the paramters |
| 269 // have been copied in with CopyParamIn. | 269 // have been copied in with CopyParamIn. |
| 270 uint32 GetSize() const { | 270 uint32_t GetSize() const { return param_info_[NUMBER_PARAMS].offset_; } |
| 271 return param_info_[NUMBER_PARAMS].offset_; | |
| 272 } | |
| 273 | 271 |
| 274 protected: | 272 protected: |
| 275 ActualCallParams() : CrossCallParams(0, NUMBER_PARAMS) { } | 273 ActualCallParams() : CrossCallParams(0, NUMBER_PARAMS) { } |
| 276 | 274 |
| 277 private: | 275 private: |
| 278 ParamInfo param_info_[NUMBER_PARAMS + 1]; | 276 ParamInfo param_info_[NUMBER_PARAMS + 1]; |
| 279 char parameters_[BLOCK_SIZE - sizeof(CrossCallParams) | 277 char parameters_[BLOCK_SIZE - sizeof(CrossCallParams) |
| 280 - sizeof(ParamInfo) * (NUMBER_PARAMS + 1)]; | 278 - sizeof(ParamInfo) * (NUMBER_PARAMS + 1)]; |
| 281 DISALLOW_COPY_AND_ASSIGN(ActualCallParams); | 279 DISALLOW_COPY_AND_ASSIGN(ActualCallParams); |
| 282 }; | 280 }; |
| 283 | 281 |
| 284 static_assert(sizeof(ActualCallParams<1, 1024>) == 1024, "bad size buffer"); | 282 static_assert(sizeof(ActualCallParams<1, 1024>) == 1024, "bad size buffer"); |
| 285 static_assert(sizeof(ActualCallParams<2, 1024>) == 1024, "bad size buffer"); | 283 static_assert(sizeof(ActualCallParams<2, 1024>) == 1024, "bad size buffer"); |
| 286 static_assert(sizeof(ActualCallParams<3, 1024>) == 1024, "bad size buffer"); | 284 static_assert(sizeof(ActualCallParams<3, 1024>) == 1024, "bad size buffer"); |
| 287 | 285 |
| 288 } // namespace sandbox | 286 } // namespace sandbox |
| 289 | 287 |
| 290 #endif // SANDBOX_SRC_CROSSCALL_PARAMS_H__ | 288 #endif // SANDBOX_SRC_CROSSCALL_PARAMS_H__ |
| OLD | NEW |