Commit 706117a7 authored by Brad Werth's avatar Brad Werth
Browse files

Bug 1792146: Make replace_malloc_usable_size succeed with pointers within...

Bug 1792146: Make replace_malloc_usable_size succeed with pointers within allocation pages. r=glandium

This changes replace_malloc_usable_size to allow measuring the size of
ptrs that appear anywhere within an allocation page, not just ptrs to the
start of the allocation pages.

This also modifies a gtest to explicitly check the usable size of some
modified pointers, not just the usable size of the pages where those
pointers are located.

Differential Revision: https://phabricator.services.mozilla.com/D170963
parent c738d5a2
Loading
Loading
Loading
Loading
+14 −3
Original line number Diff line number Diff line
@@ -699,6 +699,12 @@ class GMut {
    return page.mState != AllocPageState::InUse && aNow >= page.mReuseTime;
  }

  // Get the address of the allocation page referred to via an index. Used
  // when checking pointers against page boundaries.
  uint8_t* AllocPageBaseAddr(GMutLock, uintptr_t aIndex) {
    return mAllocPages[aIndex].mBaseAddr;
  }

  Maybe<arena_id_t> PageArena(GMutLock aLock, uintptr_t aIndex) {
    const AllocPageInfo& page = mAllocPages[aIndex];
    AssertAllocPageInUse(aLock, page);
@@ -1367,13 +1373,18 @@ static size_t replace_malloc_usable_size(usable_ptr_t aPtr) {
    GMut::CrashOnGuardPage(const_cast<void*>(aPtr));
  }

  // At this point we know we have an allocation page.
  // At this point we know aPtr lands within an allocation page, due to the
  // math done in the PtrKind constructor. But if aPtr points to memory
  // before the base address of the allocation, we return 0.
  uintptr_t index = pk.AllocPageIndex();

  MutexAutoLock lock(GMut::sMutex);

  // Check for malloc_usable_size() of a freed block.
  gMut->EnsureValidAndInUse(lock, const_cast<void*>(aPtr), index);
  void* pageBaseAddr = gMut->AllocPageBaseAddr(lock, index);

  if (MOZ_UNLIKELY(aPtr < pageBaseAddr)) {
    return 0;
  }

  return gMut->PageUsableSize(lock, index);
}
+3 −1
Original line number Diff line number Diff line
@@ -147,12 +147,13 @@ TEST(PHC, TestPHCInfo)
      PHCInfoEq(phcInfo, phc::AddrInfo::Kind::InUsePage, p, 32ul, true, false));
  ASSERT_EQ(moz_malloc_usable_size(p), 32ul);
  jemalloc_ptr_info(p, &jeInfo);
  ASSERT_TRUE(JeInfoEq(jeInfo, TagLiveAlloc, p, 32, 0));

  // Test an in-use PHC allocation: last byte within it.
  ASSERT_TRUE(ReplaceMalloc::IsPHCAllocation(p + 31, &phcInfo));
  ASSERT_TRUE(
      PHCInfoEq(phcInfo, phc::AddrInfo::Kind::InUsePage, p, 32ul, true, false));
  ASSERT_TRUE(JeInfoEq(jeInfo, TagLiveAlloc, p, 32, 0));
  ASSERT_EQ(moz_malloc_usable_size(p + 31), 32ul);
  jemalloc_ptr_info(p + 31, &jeInfo);
  ASSERT_TRUE(JeInfoEq(jeInfo, TagLiveAlloc, p, 32, 0));

@@ -160,6 +161,7 @@ TEST(PHC, TestPHCInfo)
  ASSERT_TRUE(ReplaceMalloc::IsPHCAllocation(p - 1, &phcInfo));
  ASSERT_TRUE(
      PHCInfoEq(phcInfo, phc::AddrInfo::Kind::InUsePage, p, 32ul, true, false));
  ASSERT_EQ(moz_malloc_usable_size(p - 1), 0ul);
  jemalloc_ptr_info(p - 1, &jeInfo);
  ASSERT_TRUE(JeInfoEq(jeInfo, TagUnknown, nullptr, 0, 0));