summaryrefslogtreecommitdiffstats
path: root/security/sandbox/chromium-shim/patches/with_update/mingw_offsetof.patch
blob: 89072da69b1a33a1c9a5b0bf3daf5c0b165ec5a5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# HG changeset patch
# User Tom Ritter <tom@mozilla.com>
# Date 1528394907 18000
#      Thu Jun 07 13:08:27 2018 -0500
# Node ID ffb6c5c06905538fb887464e9553e7b47cdf7575
# Parent  1987e062f1e5bf2998bb8e9d96353c5ccb0cc281
Bug 1461421 Use OffsetOf to calculate the location of parameters_ rather than making assumptions about the parent class r?bobowen

MozReview-Commit-ID: D7REZiAIMpN

diff --git a/security/sandbox/chromium/sandbox/win/src/crosscall_params.h b/security/sandbox/chromium/sandbox/win/src/crosscall_params.h
--- a/security/sandbox/chromium/sandbox/win/src/crosscall_params.h
+++ b/security/sandbox/chromium/sandbox/win/src/crosscall_params.h
@@ -78,16 +78,17 @@ union MultiType {
   ULONG_PTR ulong_ptr;
 };
 
 // Maximum number of IPC parameters currently supported.
 // To increase this value, we have to:
 //  - Add another Callback typedef to Dispatcher.
 //  - Add another case to the switch on SharedMemIPCServer::InvokeCallback.
 //  - Add another case to the switch in GetActualAndMaxBufferSize
+//  - Add another case to the switch in GetMinDeclaredActualCallParamsSize
 const int kMaxIpcParams = 9;
 
 // Contains the information about a parameter in the ipc buffer.
 struct ParamInfo {
   ArgType type_;
   uint32_t offset_;
   uint32_t size_;
 };
@@ -287,16 +288,18 @@ class ActualCallParams : public CrossCal
  protected:
   ActualCallParams() : CrossCallParams(IpcTag::UNUSED, NUMBER_PARAMS) {}
 
  private:
   ParamInfo param_info_[NUMBER_PARAMS + 1];
   char parameters_[BLOCK_SIZE - sizeof(CrossCallParams) -
                    sizeof(ParamInfo) * (NUMBER_PARAMS + 1)];
   DISALLOW_COPY_AND_ASSIGN(ActualCallParams);
+
+  friend uint32_t GetMinDeclaredActualCallParamsSize(uint32_t param_count);
 };
 
 static_assert(sizeof(ActualCallParams<1, 1024>) == 1024, "bad size buffer");
 static_assert(sizeof(ActualCallParams<2, 1024>) == 1024, "bad size buffer");
 static_assert(sizeof(ActualCallParams<3, 1024>) == 1024, "bad size buffer");
 
 }  // namespace sandbox
 
diff --git a/security/sandbox/chromium/sandbox/win/src/crosscall_server.cc b/security/sandbox/chromium/sandbox/win/src/crosscall_server.cc
--- a/security/sandbox/chromium/sandbox/win/src/crosscall_server.cc
+++ b/security/sandbox/chromium/sandbox/win/src/crosscall_server.cc
@@ -28,30 +28,31 @@ namespace {
 
 // The buffer for a message must match the max channel size.
 const size_t kMaxBufferSize = sandbox::kIPCChannelSize;
 
 }  // namespace
 
 namespace sandbox {
 
+// The template types are used to calculate the maximum expected size.
+typedef ActualCallParams<0, kMaxBufferSize> ActualCP0;
+typedef ActualCallParams<1, kMaxBufferSize> ActualCP1;
+typedef ActualCallParams<2, kMaxBufferSize> ActualCP2;
+typedef ActualCallParams<3, kMaxBufferSize> ActualCP3;
+typedef ActualCallParams<4, kMaxBufferSize> ActualCP4;
+typedef ActualCallParams<5, kMaxBufferSize> ActualCP5;
+typedef ActualCallParams<6, kMaxBufferSize> ActualCP6;
+typedef ActualCallParams<7, kMaxBufferSize> ActualCP7;
+typedef ActualCallParams<8, kMaxBufferSize> ActualCP8;
+typedef ActualCallParams<9, kMaxBufferSize> ActualCP9;
+
 // Returns the actual size for the parameters in an IPC buffer. Returns
 // zero if the |param_count| is zero or too big.
 uint32_t GetActualBufferSize(uint32_t param_count, void* buffer_base) {
-  // The template types are used to calculate the maximum expected size.
-  typedef ActualCallParams<1, kMaxBufferSize> ActualCP1;
-  typedef ActualCallParams<2, kMaxBufferSize> ActualCP2;
-  typedef ActualCallParams<3, kMaxBufferSize> ActualCP3;
-  typedef ActualCallParams<4, kMaxBufferSize> ActualCP4;
-  typedef ActualCallParams<5, kMaxBufferSize> ActualCP5;
-  typedef ActualCallParams<6, kMaxBufferSize> ActualCP6;
-  typedef ActualCallParams<7, kMaxBufferSize> ActualCP7;
-  typedef ActualCallParams<8, kMaxBufferSize> ActualCP8;
-  typedef ActualCallParams<9, kMaxBufferSize> ActualCP9;
-
   // Retrieve the actual size and the maximum size of the params buffer.
   switch (param_count) {
     case 0:
       return 0;
     case 1:
       return reinterpret_cast<ActualCP1*>(buffer_base)->GetSize();
     case 2:
       return reinterpret_cast<ActualCP2*>(buffer_base)->GetSize();
@@ -69,16 +70,45 @@ uint32_t GetActualBufferSize(uint32_t pa
       return reinterpret_cast<ActualCP8*>(buffer_base)->GetSize();
     case 9:
       return reinterpret_cast<ActualCP9*>(buffer_base)->GetSize();
     default:
       return 0;
   }
 }
 
+// Returns the minimum size for the parameters in an IPC buffer. Returns
+// zero if the |param_count| is less than zero or too big.
+uint32_t GetMinDeclaredActualCallParamsSize(uint32_t param_count) {
+  switch (param_count) {
+    case 0:
+      return offsetof(ActualCP0, parameters_);
+    case 1:
+      return offsetof(ActualCP1, parameters_);
+    case 2:
+      return offsetof(ActualCP2, parameters_);
+    case 3:
+      return offsetof(ActualCP3, parameters_);
+    case 4:
+      return offsetof(ActualCP4, parameters_);
+    case 5:
+      return offsetof(ActualCP5, parameters_);
+    case 6:
+      return offsetof(ActualCP6, parameters_);
+    case 7:
+      return offsetof(ActualCP7, parameters_);
+    case 8:
+      return offsetof(ActualCP8, parameters_);
+    case 9:
+      return offsetof(ActualCP9, parameters_);
+    default:
+      return 0;
+  }
+}
+
 // Verifies that the declared sizes of an IPC buffer are within range.
 bool IsSizeWithinRange(uint32_t buffer_size,
                        uint32_t min_declared_size,
                        uint32_t declared_size) {
   if ((buffer_size < min_declared_size) ||
       (sizeof(CrossCallParamsEx) > min_declared_size)) {
     // Minimal computed size bigger than existing buffer or param_count
     // integer overflow.
@@ -133,18 +163,17 @@ CrossCallParamsEx* CrossCallParamsEx::Cr
   // will catch memory access violations so we don't crash.
   __try {
     CrossCallParams* call_params =
         reinterpret_cast<CrossCallParams*>(buffer_base);
 
     // Check against the minimum size given the number of stated params
     // if too small we bail out.
     param_count = call_params->GetParamsCount();
-    min_declared_size =
-        sizeof(CrossCallParams) + ((param_count + 1) * sizeof(ParamInfo));
+    min_declared_size = GetMinDeclaredActualCallParamsSize(param_count);
 
     // Initial check for the buffer being big enough to determine the actual
     // buffer size.
     if (buffer_size < min_declared_size)
       return nullptr;
 
     // Retrieve the declared size which if it fails returns 0.
     declared_size = GetActualBufferSize(param_count, buffer_base);
@@ -158,18 +187,17 @@ CrossCallParamsEx* CrossCallParamsEx::Cr
     copied_params = reinterpret_cast<CrossCallParamsEx*>(backing_mem);
     memcpy(backing_mem, call_params, declared_size);
 
     // Avoid compiler optimizations across this point. Any value stored in
     // memory should be stored for real, and values previously read from memory
     // should be actually read.
     std::atomic_thread_fence(std::memory_order_seq_cst);
 
-    min_declared_size =
-        sizeof(CrossCallParams) + ((param_count + 1) * sizeof(ParamInfo));
+    min_declared_size = GetMinDeclaredActualCallParamsSize(param_count);
 
     // Check that the copied buffer is still valid.
     if (copied_params->GetParamsCount() != param_count ||
         GetActualBufferSize(param_count, backing_mem) != declared_size ||
         !IsSizeWithinRange(buffer_size, min_declared_size, declared_size)) {
       delete[] backing_mem;
       return nullptr;
     }