tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

11_mingw_offsetof.patch (7294B)


      1 # HG changeset patch
      2 # User Tom Ritter <tom@mozilla.com>
      3 # Date 1528394907 18000
      4 #      Thu Jun 07 13:08:27 2018 -0500
      5 # Node ID ffb6c5c06905538fb887464e9553e7b47cdf7575
      6 # Parent  1987e062f1e5bf2998bb8e9d96353c5ccb0cc281
      7 Bug 1461421 Use OffsetOf to calculate the location of parameters_ rather than making assumptions about the parent class r?bobowen
      8 
      9 MozReview-Commit-ID: D7REZiAIMpN
     10 
     11 diff --git a/sandbox/win/src/crosscall_params.h b/sandbox/win/src/crosscall_params.h
     12 --- a/sandbox/win/src/crosscall_params.h
     13 +++ b/sandbox/win/src/crosscall_params.h
     14 @@ -78,16 +78,17 @@ union MultiType {
     15   ULONG_PTR ulong_ptr;
     16 };
     17 
     18 // Maximum number of IPC parameters currently supported.
     19 // To increase this value, we have to:
     20 //  - Add another Callback typedef to Dispatcher.
     21 //  - Add another case to the switch on SharedMemIPCServer::InvokeCallback.
     22 //  - Add another case to the switch in GetActualAndMaxBufferSize
     23 +//  - Add another case to the switch in GetMinDeclaredActualCallParamsSize
     24 const int kMaxIpcParams = 9;
     25 
     26 // Contains the information about a parameter in the ipc buffer.
     27 struct ParamInfo {
     28   ArgType type_;
     29   uint32_t offset_;
     30   uint32_t size_;
     31 };
     32 @@ -287,16 +288,18 @@ class ActualCallParams : public CrossCal
     33 
     34  protected:
     35   ActualCallParams() : CrossCallParams(IpcTag::UNUSED, NUMBER_PARAMS) {}
     36 
     37  private:
     38   ParamInfo param_info_[NUMBER_PARAMS + 1];
     39   char parameters_[BLOCK_SIZE - sizeof(CrossCallParams) -
     40                    sizeof(ParamInfo) * (NUMBER_PARAMS + 1)];
     41 +
     42 +  friend uint32_t GetMinDeclaredActualCallParamsSize(uint32_t param_count);
     43 };
     44 
     45 static_assert(sizeof(ActualCallParams<1, 1024>) == 1024, "bad size buffer");
     46 static_assert(sizeof(ActualCallParams<2, 1024>) == 1024, "bad size buffer");
     47 static_assert(sizeof(ActualCallParams<3, 1024>) == 1024, "bad size buffer");
     48 
     49 }  // namespace sandbox
     50 
     51 diff --git a/sandbox/win/src/crosscall_server.cc b/sandbox/win/src/crosscall_server.cc
     52 --- a/sandbox/win/src/crosscall_server.cc
     53 +++ b/sandbox/win/src/crosscall_server.cc
     54 @@ -28,30 +28,31 @@ namespace {
     55 
     56 // The buffer for a message must match the max channel size.
     57 const size_t kMaxBufferSize = sandbox::kIPCChannelSize;
     58 
     59 }  // namespace
     60 
     61 namespace sandbox {
     62 
     63 +// The template types are used to calculate the maximum expected size.
     64 +typedef ActualCallParams<0, kMaxBufferSize> ActualCP0;
     65 +typedef ActualCallParams<1, kMaxBufferSize> ActualCP1;
     66 +typedef ActualCallParams<2, kMaxBufferSize> ActualCP2;
     67 +typedef ActualCallParams<3, kMaxBufferSize> ActualCP3;
     68 +typedef ActualCallParams<4, kMaxBufferSize> ActualCP4;
     69 +typedef ActualCallParams<5, kMaxBufferSize> ActualCP5;
     70 +typedef ActualCallParams<6, kMaxBufferSize> ActualCP6;
     71 +typedef ActualCallParams<7, kMaxBufferSize> ActualCP7;
     72 +typedef ActualCallParams<8, kMaxBufferSize> ActualCP8;
     73 +typedef ActualCallParams<9, kMaxBufferSize> ActualCP9;
     74 +
     75 // Returns the actual size for the parameters in an IPC buffer. Returns
     76 // zero if the |param_count| is zero or too big.
     77 uint32_t GetActualBufferSize(uint32_t param_count, void* buffer_base) {
     78 -  // The template types are used to calculate the maximum expected size.
     79 -  typedef ActualCallParams<1, kMaxBufferSize> ActualCP1;
     80 -  typedef ActualCallParams<2, kMaxBufferSize> ActualCP2;
     81 -  typedef ActualCallParams<3, kMaxBufferSize> ActualCP3;
     82 -  typedef ActualCallParams<4, kMaxBufferSize> ActualCP4;
     83 -  typedef ActualCallParams<5, kMaxBufferSize> ActualCP5;
     84 -  typedef ActualCallParams<6, kMaxBufferSize> ActualCP6;
     85 -  typedef ActualCallParams<7, kMaxBufferSize> ActualCP7;
     86 -  typedef ActualCallParams<8, kMaxBufferSize> ActualCP8;
     87 -  typedef ActualCallParams<9, kMaxBufferSize> ActualCP9;
     88 -
     89   // Retrieve the actual size and the maximum size of the params buffer.
     90   switch (param_count) {
     91     case 0:
     92       return 0;
     93     case 1:
     94       return reinterpret_cast<ActualCP1*>(buffer_base)->GetSize();
     95     case 2:
     96       return reinterpret_cast<ActualCP2*>(buffer_base)->GetSize();
     97 @@ -69,16 +70,45 @@ uint32_t GetActualBufferSize(uint32_t pa
     98       return reinterpret_cast<ActualCP8*>(buffer_base)->GetSize();
     99     case 9:
    100       return reinterpret_cast<ActualCP9*>(buffer_base)->GetSize();
    101     default:
    102       return 0;
    103   }
    104 }
    105 
    106 +// Returns the minimum size for the parameters in an IPC buffer. Returns
    107 +// zero if the |param_count| is less than zero or too big.
    108 +uint32_t GetMinDeclaredActualCallParamsSize(uint32_t param_count) {
    109 +  switch (param_count) {
    110 +    case 0:
    111 +      return offsetof(ActualCP0, parameters_);
    112 +    case 1:
    113 +      return offsetof(ActualCP1, parameters_);
    114 +    case 2:
    115 +      return offsetof(ActualCP2, parameters_);
    116 +    case 3:
    117 +      return offsetof(ActualCP3, parameters_);
    118 +    case 4:
    119 +      return offsetof(ActualCP4, parameters_);
    120 +    case 5:
    121 +      return offsetof(ActualCP5, parameters_);
    122 +    case 6:
    123 +      return offsetof(ActualCP6, parameters_);
    124 +    case 7:
    125 +      return offsetof(ActualCP7, parameters_);
    126 +    case 8:
    127 +      return offsetof(ActualCP8, parameters_);
    128 +    case 9:
    129 +      return offsetof(ActualCP9, parameters_);
    130 +    default:
    131 +      return 0;
    132 +  }
    133 +}
    134 +
    135 // Verifies that the declared sizes of an IPC buffer are within range.
    136 bool IsSizeWithinRange(uint32_t buffer_size,
    137                        uint32_t min_declared_size,
    138                        uint32_t declared_size) {
    139   if ((buffer_size < min_declared_size) ||
    140       (sizeof(CrossCallParamsEx) > min_declared_size)) {
    141     // Minimal computed size bigger than existing buffer or param_count
    142     // integer overflow.
    143 @@ -133,18 +163,17 @@ CrossCallParamsEx* CrossCallParamsEx::Cr
    144   // will catch memory access violations so we don't crash.
    145   __try {
    146     CrossCallParams* call_params =
    147         reinterpret_cast<CrossCallParams*>(buffer_base);
    148 
    149     // Check against the minimum size given the number of stated params
    150     // if too small we bail out.
    151     param_count = call_params->GetParamsCount();
    152 -    min_declared_size =
    153 -        sizeof(CrossCallParams) + ((param_count + 1) * sizeof(ParamInfo));
    154 +    min_declared_size = GetMinDeclaredActualCallParamsSize(param_count);
    155 
    156     // Initial check for the buffer being big enough to determine the actual
    157     // buffer size.
    158     if (buffer_size < min_declared_size)
    159       return nullptr;
    160 
    161     // Retrieve the declared size which if it fails returns 0.
    162     declared_size = GetActualBufferSize(param_count, buffer_base);
    163 @@ -158,18 +187,17 @@ CrossCallParamsEx* CrossCallParamsEx::Cr
    164     copied_params = reinterpret_cast<CrossCallParamsEx*>(backing_mem);
    165     memcpy(backing_mem, call_params, declared_size);
    166 
    167     // Avoid compiler optimizations across this point. Any value stored in
    168     // memory should be stored for real, and values previously read from memory
    169     // should be actually read.
    170     std::atomic_thread_fence(std::memory_order_seq_cst);
    171 
    172 -    min_declared_size =
    173 -        sizeof(CrossCallParams) + ((param_count + 1) * sizeof(ParamInfo));
    174 +    min_declared_size = GetMinDeclaredActualCallParamsSize(param_count);
    175 
    176     // Check that the copied buffer is still valid.
    177     if (copied_params->GetParamsCount() != param_count ||
    178         GetActualBufferSize(param_count, backing_mem) != declared_size ||
    179         !IsSizeWithinRange(buffer_size, min_declared_size, declared_size)) {
    180       delete[] backing_mem;
    181       return nullptr;
    182     }