summaryrefslogtreecommitdiffstats
path: root/security/sandbox/chromium-shim/patches/with_update/mingw_offsetof.patch
diff options
context:
space:
mode:
Diffstat (limited to 'security/sandbox/chromium-shim/patches/with_update/mingw_offsetof.patch')
-rw-r--r--security/sandbox/chromium-shim/patches/with_update/mingw_offsetof.patch182
1 files changed, 182 insertions, 0 deletions
diff --git a/security/sandbox/chromium-shim/patches/with_update/mingw_offsetof.patch b/security/sandbox/chromium-shim/patches/with_update/mingw_offsetof.patch
new file mode 100644
index 0000000000..89072da69b
--- /dev/null
+++ b/security/sandbox/chromium-shim/patches/with_update/mingw_offsetof.patch
@@ -0,0 +1,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;
+ }