Bug 1750168 - Align the size of buffers given to WriteBytesZeroCopy. r=nika
authorMike Hommey <mh+mozilla@glandium.org>
Fri, 14 Jan 2022 22:54:26 +0000
changeset 604615 d09e050e686b9419a5d70917dc9a77332c7ebdd8
parent 604614 a1652ef01a12b15abdbab0696c4906c7b7612f70
child 604616 22212426ae629188a63a2a689a7056fa97650e5f
push id39152
push userabutkovits@mozilla.com
push dateSat, 15 Jan 2022 09:45:36 +0000
treeherdermozilla-central@60998033086a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnika
bugs1750168
milestone98.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1750168 - Align the size of buffers given to WriteBytesZeroCopy. r=nika Also ensure Copier::Copy receives aligned pointers (in debug builds). Differential Revision: https://phabricator.services.mozilla.com/D135985
ipc/chromium/src/base/pickle.cc
--- a/ipc/chromium/src/base/pickle.cc
+++ b/ipc/chromium/src/base/pickle.cc
@@ -74,16 +74,18 @@ struct Copier<T, sizeof(uint64_t), false
     uint32dest[hiIndex] = src[hiIndex];
   }
 };
 #endif
 
 template <typename T, size_t size>
 struct Copier<T, size, true> {
   static void Copy(T* dest, const char* iter) {
+    // The pointer ought to be properly aligned.
+    DCHECK_EQ((((uintptr_t)iter) & (MOZ_ALIGNOF(T) - 1)), 0);
     *dest = *reinterpret_cast<const T*>(iter);
   }
 };
 
 }  // anonymous namespace
 
 PickleIterator::PickleIterator(const Pickle& pickle)
     : iter_(pickle.buffers_.Iter()) {
@@ -604,18 +606,32 @@ bool Pickle::WriteUnsignedChar(unsigned 
 #endif
   return WriteBytes(&value, sizeof(value));
 }
 
 bool Pickle::WriteBytesZeroCopy(void* data, uint32_t data_len,
                                 uint32_t capacity) {
   BeginWrite(data_len, sizeof(memberAlignmentType));
 
+  uint32_t new_capacity = AlignInt(capacity);
+#ifndef MOZ_MEMORY
+  if (new_capacity > capacity) {
+    // If the buffer we were given is not large enough to contain padding
+    // after the data, reallocate it to make it so. When using jemalloc,
+    // we're guaranteed the buffer size is going to be at least 4-bytes
+    // aligned, so we skip realloc altogether. Even with other allocators,
+    // the realloc is likely not necessary, but we don't take chances.
+    // At least with ASan, it does matter to realloc to inform ASan we're
+    // going to use more data from the buffer (and let it actually realloc
+    // if it needs to).
+    data = realloc(data, new_capacity);
+  }
+#endif
   buffers_.WriteBytesZeroCopy(reinterpret_cast<char*>(data), data_len,
-                              capacity);
+                              new_capacity);
 
   EndWrite(data_len);
   return true;
 }
 
 bool Pickle::WriteBytes(const void* data, uint32_t data_len,
                         uint32_t alignment) {
   DCHECK(alignment == 4 || alignment == 8);