security/sandbox/win/src/sharedmem_ipc_client.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 // Copyright (c) 2006-2008 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.
     5 #ifndef SANDBOX_SRC_SHAREDMEM_IPC_CLIENT_H__
     6 #define SANDBOX_SRC_SHAREDMEM_IPC_CLIENT_H__
     8 #include "sandbox/win/src/crosscall_params.h"
     9 #include "sandbox/win/src/sandbox.h"
    11 // IPC transport implementation that uses shared memory.
    12 // This is the client side
    13 //
    14 // The shared memory is divided on blocks called channels, and potentially
    15 // it can perform as many concurrent IPC calls as channels. The IPC over
    16 // each channel is strictly synchronous for the client.
    17 //
    18 // Each channel as a channel control section associated with. Each control
    19 // section has two kernel events (known as ping and pong) and a integer
    20 // variable that maintains a state
    21 //
    22 // this is the state diagram of a channel:
    23 //
    24 //                   locked                in service
    25 //     kFreeChannel---------->BusyChannel-------------->kAckChannel
    26 //          ^                                                 |
    27 //          |_________________________________________________|
    28 //                             answer ready
    29 //
    30 // The protocol is as follows:
    31 //   1) client finds a free channel: state = kFreeChannel
    32 //   2) does an atomic compare-and-swap, now state = BusyChannel
    33 //   3) client writes the data into the channel buffer
    34 //   4) client signals the ping event and waits (blocks) on the pong event
    35 //   5) eventually the server signals the pong event
    36 //   6) the client awakes and reads the answer from the same channel
    37 //   7) the client updates its InOut parameters with the new data from the
    38 //      shared memory section.
    39 //   8) the client atomically sets the state = kFreeChannel
    40 //
    41 //  In the shared memory the layout is as follows:
    42 //
    43 //    [ channel count    ]
    44 //    [ channel control 0]
    45 //    [ channel control 1]
    46 //    [ channel control N]
    47 //    [ channel buffer 0 ] 1024 bytes
    48 //    [ channel buffer 1 ] 1024 bytes
    49 //    [ channel buffer N ] 1024 bytes
    50 //
    51 // By default each channel buffer is 1024 bytes
    52 namespace sandbox {
    54 // the possible channel states as described above
    55 enum ChannelState {
    56   // channel is free
    57   kFreeChannel = 1,
    58   // IPC in progress client side
    59   kBusyChannel,
    60   // IPC in progress server side
    61   kAckChannel,
    62   // not used right now
    63   kReadyChannel,
    64   // IPC abandoned by client side
    65   kAbandonnedChannel
    66 };
    68 // The next two constants control the time outs for the IPC.
    69 const DWORD kIPCWaitTimeOut1 = 1000;   // Milliseconds.
    70 const DWORD kIPCWaitTimeOut2 =   50;   // Milliseconds.
    72 // the channel control structure
    73 struct ChannelControl {
    74   // points to be beginning of the channel buffer, where data goes
    75   size_t channel_base;
    76   // maintains the state from the ChannelState enumeration
    77   volatile LONG state;
    78   // the ping event is signaled by the client when the IPC data is ready on
    79   // the buffer
    80   HANDLE ping_event;
    81   // the client waits on the pong event for the IPC answer back
    82   HANDLE pong_event;
    83   // the IPC unique identifier
    84   uint32 ipc_tag;
    85 };
    87 struct IPCControl {
    88   // total number of channels available, some might be busy at a given time
    89   size_t channels_count;
    90   // handle to a shared mutex to detect when the server is dead
    91   HANDLE server_alive;
    92   // array of channel control structures
    93   ChannelControl channels[1];
    94 };
    96 // the actual shared memory IPC implementation class. This object is designed
    97 // to be lightweight so it can be constructed on-site (at the calling place)
    98 // wherever an IPC call is needed.
    99 class SharedMemIPCClient {
   100  public:
   101   // Creates the IPC client.
   102   // as parameter it takes the base address of the shared memory
   103   explicit SharedMemIPCClient(void* shared_mem);
   105   // locks a free channel and returns the channel buffer memory base. This call
   106   // blocks until there is a free channel
   107   void* GetBuffer();
   109   // releases the lock on the channel, for other to use. call this if you have
   110   // called GetBuffer and you want to abort but have not called yet DoCall()
   111   void FreeBuffer(void* buffer);
   113   // Performs the actual IPC call.
   114   // params: The blob of packed input parameters.
   115   // answer: upon IPC completion, it contains the server answer to the IPC.
   116   // If the return value is not SBOX_ERROR_CHANNEL_ERROR, the caller has to free
   117   // the channel.
   118   // returns ALL_OK if the IPC mechanism successfully delivered. You still need
   119   // to check on the answer structure to see the actual IPC result.
   120   ResultCode DoCall(CrossCallParams* params, CrossCallReturn* answer);
   122  private:
   123   // Returns the index of the first free channel. It sets 'severe_failure'
   124   // to true if there is an unrecoverable error that does not allow to
   125   // find a channel.
   126   size_t LockFreeChannel(bool* severe_failure);
   127   // Return the channel index given the address of the buffer.
   128   size_t ChannelIndexFromBuffer(const void* buffer);
   129   IPCControl* control_;
   130   // point to the first channel base
   131   char* first_base_;
   132 };
   134 }  // namespace sandbox
   136 #endif  // SANDBOX_SRC_SHAREDMEM_IPC_CLIENT_H__

mercurial