159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// Copyright (c) 2012 The Chromium Authors. All rights reserved. 259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// Use of this source code is governed by a BSD-style license that can be 359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// found in the LICENSE file. 459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#ifndef SANDBOX_SRC_CROSSCALL_PARAMS_H__ 659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#define SANDBOX_SRC_CROSSCALL_PARAMS_H__ 759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#include <windows.h> 959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#include <lmaccess.h> 10cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include <stddef.h> 11cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include <stdint.h> 1259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 1359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#include <memory> 1459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 15cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include "base/macros.h" 1659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#include "sandbox/win/src/internal_types.h" 1759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#include "sandbox/win/src/sandbox_types.h" 1859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 19cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// Increases |value| until there is no need for padding given an int64_t 2059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// alignment. Returns the increased value. 21cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoinline uint32_t Align(uint32_t value) { 22cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko uint32_t alignment = sizeof(int64_t); 2359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat return ((value + alignment - 1) / alignment) * alignment; 2459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat} 2559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 2659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// This header is part of CrossCall: the sandbox inter-process communication. 2759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// This header defines the basic types used both in the client IPC and in the 2859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// server IPC code. CrossCallParams and ActualCallParams model the input 2959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// parameters of an IPC call and CrossCallReturn models the output params and 3059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// the return value. 3159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// 32cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// An IPC call is defined by its 'tag' which is a (uint32_t) unique identifier 3359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// that is used to route the IPC call to the proper server. Every tag implies 3459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// a complete call signature including the order and type of each parameter. 3559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// 3659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// Like most IPC systems. CrossCall is designed to take as inputs 'simple' 3759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// types such as integers and strings. Classes, generic arrays or pointers to 3859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// them are not supported. 3959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// 4059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// Another limitation of CrossCall is that the return value and output 41cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// parameters can only be uint32_t integers. Returning complex structures or 4259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// strings is not supported. 4359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 4459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratnamespace sandbox { 4559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 4659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// max number of extended return parameters. See CrossCallReturn 4759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratconst size_t kExtendedReturnCount = 8; 4859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 4959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// Union of multiple types to be used as extended results 5059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// in the CrossCallReturn. 5159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratunion MultiType { 52cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko uint32_t unsigned_int; 5359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat void* pointer; 5459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat HANDLE handle; 5559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat ULONG_PTR ulong_ptr; 5659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat}; 5759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 5859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// Maximum number of IPC parameters currently supported. 5959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// To increase this value, we have to: 6059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// - Add another Callback typedef to Dispatcher. 6159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// - Add another case to the switch on SharedMemIPCServer::InvokeCallback. 6259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// - Add another case to the switch in GetActualAndMaxBufferSize 6359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratconst int kMaxIpcParams = 9; 6459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 6559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// Contains the information about a parameter in the ipc buffer. 6659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratstruct ParamInfo { 6759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat ArgType type_; 68cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko uint32_t offset_; 69cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko uint32_t size_; 7059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat}; 7159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 7259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// Models the return value and the return parameters of an IPC call 7359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// currently limited to one status code and eight generic return values 7459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// which cannot be pointers to other data. For x64 ports this structure 7559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// might have to use other integer types. 7659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratstruct CrossCallReturn { 7759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // the IPC tag. It should match the original IPC tag. 78cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko uint32_t tag; 7959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // The result of the IPC operation itself. 8059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat ResultCode call_outcome; 8159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // the result of the IPC call as executed in the server. The interpretation 8259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // of this value depends on the specific service. 8359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat union { 8459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat NTSTATUS nt_status; 8559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat DWORD win32_result; 8659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat }; 8759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // Number of extended return values. 88cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko uint32_t extended_count; 8959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // for calls that should return a windows handle. It is found here. 9059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat HANDLE handle; 9159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // The array of extended values. 9259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat MultiType extended[kExtendedReturnCount]; 9359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat}; 9459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 9559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// CrossCallParams base class that models the input params all packed in a 9659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// single compact memory blob. The representation can vary but in general a 9759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// given child of this class is meant to represent all input parameters 9859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// necessary to make a IPC call. 9959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// 10059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// This class cannot have virtual members because its assumed the IPC 10159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// parameters start from the 'this' pointer to the end, which is defined by 10259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// one of the subclasses 10359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// 10459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// Objects of this class cannot be constructed directly. Only derived 10559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// classes have the proper knowledge to construct it. 10659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratclass CrossCallParams { 10759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat public: 10859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // Returns the tag (ipc unique id) associated with this IPC. 109cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko uint32_t GetTag() const { return tag_; } 11059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 11159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // Returns the beggining of the buffer where the IPC params can be stored. 11259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // prior to an IPC call 11359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat const void* GetBuffer() const { 11459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat return this; 11559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat } 11659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 11759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // Returns how many parameter this IPC call should have. 118cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko uint32_t GetParamsCount() const { return params_count_; } 11959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 12059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // Returns a pointer to the CrossCallReturn structure. 12159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat CrossCallReturn* GetCallReturn() { 12259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat return &call_return; 12359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat } 12459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 12559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // Returns TRUE if this call contains InOut parameters. 126cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko bool IsInOut() const { return (1 == is_in_out_); } 12759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 12859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // Tells the CrossCall object if it contains InOut parameters. 12959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat void SetIsInOut(bool value) { 13059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat if (value) 13159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat is_in_out_ = 1; 13259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat else 13359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat is_in_out_ = 0; 13459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat } 13559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 13659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat protected: 13759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // constructs the IPC call params. Called only from the derived classes 138cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko CrossCallParams(uint32_t tag, uint32_t params_count) 139cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko : tag_(tag), is_in_out_(0), params_count_(params_count) {} 14059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 14159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat private: 142cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko uint32_t tag_; 143cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko uint32_t is_in_out_; 14459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat CrossCallReturn call_return; 145cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko const uint32_t params_count_; 14659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat DISALLOW_COPY_AND_ASSIGN(CrossCallParams); 14759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat}; 14859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 14959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// ActualCallParams models an specific IPC call parameters with respect to the 15059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// storage allocation that the packed parameters should need. 15159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// NUMBER_PARAMS: the number of parameters, valid from 1 to N 15259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// BLOCK_SIZE: the total storage that the NUMBER_PARAMS parameters can take, 15359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// typically the block size is defined by the channel size of the underlying 15459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// ipc mechanism. 15559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// In practice this class is used to levergage C++ capacity to properly 15659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// calculate sizes and displacements given the possibility of the packed params 15759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// blob to be complex. 15859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// 15959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// As is, this class assumes that the layout of the blob is as follows. Assume 16059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// that NUMBER_PARAMS = 2 and a 32-bit build: 16159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// 16259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// [ tag 4 bytes] 16359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// [ IsOnOut 4 bytes] 16459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// [ call return 52 bytes] 16559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// [ params count 4 bytes] 16659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// [ parameter 0 type 4 bytes] 16759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// [ parameter 0 offset 4 bytes] ---delta to ---\ 16859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// [ parameter 0 size 4 bytes] | 16959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// [ parameter 1 type 4 bytes] | 17059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// [ parameter 1 offset 4 bytes] ---------------|--\ 17159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// [ parameter 1 size 4 bytes] | | 17259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// [ parameter 2 type 4 bytes] | | 17359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// [ parameter 2 offset 4 bytes] ----------------------\ 17459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// [ parameter 2 size 4 bytes] | | | 17559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// |---------------------------| | | | 17659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// | value 0 (x bytes) | <--------------/ | | 17759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// | value 1 (y bytes) | <-----------------/ | 17859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// | | | 17959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// | end of buffer | <---------------------/ 18059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// |---------------------------| 18159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// 18259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// Note that the actual number of params is NUMBER_PARAMS + 1 18359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// so that the size of each actual param can be computed from the difference 18459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// between one parameter and the next down. The offset of the last param 18559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// points to the end of the buffer and the type and size are undefined. 18659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// 18759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erattemplate <size_t NUMBER_PARAMS, size_t BLOCK_SIZE> 18859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratclass ActualCallParams : public CrossCallParams { 18959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat public: 19059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // constructor. Pass the ipc unique tag as input 191cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko explicit ActualCallParams(uint32_t tag) 19259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat : CrossCallParams(tag, NUMBER_PARAMS) { 19359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat param_info_[0].offset_ = 194cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko static_cast<uint32_t>(parameters_ - reinterpret_cast<char*>(this)); 19559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat } 19659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 19759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // Testing-only constructor. Allows setting the |number_params| to a 19859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // wrong value. 199cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko ActualCallParams(uint32_t tag, uint32_t number_params) 20059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat : CrossCallParams(tag, number_params) { 20159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat param_info_[0].offset_ = 202cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko static_cast<uint32_t>(parameters_ - reinterpret_cast<char*>(this)); 20359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat } 20459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 20559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // Testing-only method. Allows setting the apparent size to a wrong value. 20659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // returns the previous size. 207cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko uint32_t OverrideSize(uint32_t new_size) { 208cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko uint32_t previous_size = param_info_[NUMBER_PARAMS].offset_; 20959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat param_info_[NUMBER_PARAMS].offset_ = new_size; 21059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat return previous_size; 21159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat } 21259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 21359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // Copies each paramter into the internal buffer. For each you must supply: 21459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // index: 0 for the first param, 1 for the next an so on 215cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko bool CopyParamIn(uint32_t index, 216cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko const void* parameter_address, 217cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko uint32_t size, 218cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko bool is_in_out, 219cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko ArgType type) { 22059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat if (index >= NUMBER_PARAMS) { 22159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat return false; 22259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat } 22359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 224cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko if (UINT32_MAX == size) { 22559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // Memory error while getting the size. 22659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat return false; 22759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat } 22859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 22959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat if (size && !parameter_address) { 23059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat return false; 23159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat } 23259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 23359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat if ((size > sizeof(*this)) || 23459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat (param_info_[index].offset_ > (sizeof(*this) - size))) { 23559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // It does not fit, abort copy. 23659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat return false; 23759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat } 23859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 23959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat char* dest = reinterpret_cast<char*>(this) + param_info_[index].offset_; 24059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 24159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // We might be touching user memory, this has to be done from inside a try 24259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // except. 24359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat __try { 24459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat memcpy(dest, parameter_address, size); 24559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat } 24659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat __except(EXCEPTION_EXECUTE_HANDLER) { 24759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat return false; 24859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat } 24959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 25059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // Set the flag to tell the broker to update the buffer once the call is 25159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // made. 25259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat if (is_in_out) 25359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat SetIsInOut(true); 25459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 25559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat param_info_[index + 1].offset_ = Align(param_info_[index].offset_ + 25659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat size); 25759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat param_info_[index].size_ = size; 25859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat param_info_[index].type_ = type; 25959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat return true; 26059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat } 26159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 26259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // Returns a pointer to a parameter in the memory section. 26359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat void* GetParamPtr(size_t index) { 26459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat return reinterpret_cast<char*>(this) + param_info_[index].offset_; 26559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat } 26659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 26759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // Returns the total size of the buffer. Only valid once all the paramters 26859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // have been copied in with CopyParamIn. 269cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko uint32_t GetSize() const { return param_info_[NUMBER_PARAMS].offset_; } 27059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 27159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat protected: 27259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat ActualCallParams() : CrossCallParams(0, NUMBER_PARAMS) { } 27359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 27459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat private: 27559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat ParamInfo param_info_[NUMBER_PARAMS + 1]; 27659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat char parameters_[BLOCK_SIZE - sizeof(CrossCallParams) 27759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat - sizeof(ParamInfo) * (NUMBER_PARAMS + 1)]; 27859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat DISALLOW_COPY_AND_ASSIGN(ActualCallParams); 27959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat}; 28059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 28159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratstatic_assert(sizeof(ActualCallParams<1, 1024>) == 1024, "bad size buffer"); 28259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratstatic_assert(sizeof(ActualCallParams<2, 1024>) == 1024, "bad size buffer"); 28359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratstatic_assert(sizeof(ActualCallParams<3, 1024>) == 1024, "bad size buffer"); 28459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 28559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat} // namespace sandbox 28659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 28759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#endif // SANDBOX_SRC_CROSSCALL_PARAMS_H__ 288