Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7c595b7a authored by Colin Cross's avatar Colin Cross Committed by android-build-merger
Browse files

Merge "Validate allocations against mappings" am: 9b528919

am: 5e079810

Change-Id: I8f2b51ea302039dfb2f8005baada9d336d9fc39c
parents bc4299d2 5e079810
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -35,6 +35,13 @@ bool HeapWalker::Allocation(uintptr_t begin, uintptr_t end) {
    end = begin + 1;
  }
  Range range{begin, end};
  if (valid_mappings_range_.end != 0 &&
      (begin < valid_mappings_range_.begin || end > valid_mappings_range_.end)) {
    MEM_LOG_ALWAYS_FATAL("allocation %p-%p is outside mapping range %p-%p",
                         reinterpret_cast<void*>(begin), reinterpret_cast<void*>(end),
                         reinterpret_cast<void*>(valid_mappings_range_.begin),
                         reinterpret_cast<void*>(valid_mappings_range_.end));
  }
  auto inserted = allocations_.insert(std::pair<Range, AllocationInfo>(range, AllocationInfo{}));
  if (inserted.second) {
    valid_allocations_range_.begin = std::min(valid_allocations_range_.begin, begin);
@@ -87,6 +94,11 @@ void HeapWalker::RecurseRoot(const Range& root) {
  }
}

void HeapWalker::Mapping(uintptr_t begin, uintptr_t end) {
  valid_mappings_range_.begin = std::min(valid_mappings_range_.begin, begin);
  valid_mappings_range_.end = std::max(valid_mappings_range_.end, end);
}

void HeapWalker::Root(uintptr_t begin, uintptr_t end) {
  roots_.push_back(Range{begin, end});
}
+4 −0
Original line number Diff line number Diff line
@@ -59,6 +59,8 @@ class HeapWalker {
        segv_page_count_(0) {
    valid_allocations_range_.end = 0;
    valid_allocations_range_.begin = ~valid_allocations_range_.end;
    valid_mappings_range_.end = 0;
    valid_mappings_range_.begin = ~valid_allocations_range_.end;

    segv_handler_.install(
        SIGSEGV, [=](ScopedSignalHandler& handler, int signal, siginfo_t* siginfo, void* uctx) {
@@ -68,6 +70,7 @@ class HeapWalker {

  ~HeapWalker() {}
  bool Allocation(uintptr_t begin, uintptr_t end);
  void Mapping(uintptr_t begin, uintptr_t end);
  void Root(uintptr_t begin, uintptr_t end);
  void Root(const allocator::vector<uintptr_t>& vals);

@@ -98,6 +101,7 @@ class HeapWalker {
  AllocationMap allocations_;
  size_t allocation_bytes_;
  Range valid_allocations_range_;
  Range valid_mappings_range_;

  allocator::vector<Range> roots_;
  allocator::vector<uintptr_t> root_vals_;
+5 −0
Original line number Diff line number Diff line
@@ -87,6 +87,11 @@ bool MemUnreachable::CollectAllocations(const allocator::vector<ThreadInfo>& thr
                                        const allocator::vector<Mapping>& mappings,
                                        const allocator::vector<uintptr_t>& refs) {
  MEM_ALOGI("searching process %d for allocations", pid_);

  for (auto it = mappings.begin(); it != mappings.end(); it++) {
    heap_walker_.Mapping(it->begin, it->end);
  }

  allocator::vector<Mapping> heap_mappings{mappings};
  allocator::vector<Mapping> anon_mappings{mappings};
  allocator::vector<Mapping> globals_mappings{mappings};
+18 −0
Original line number Diff line number Diff line
@@ -73,6 +73,24 @@ TEST_F(HeapWalkerTest, zero) {
  ASSERT_FALSE(heap_walker.Allocation(2, 3));
}

TEST_F(HeapWalkerTest, mapping) {
  HeapWalker heap_walker(heap_);
  heap_walker.Mapping(2, 3);
  heap_walker.Mapping(4, 5);
  ASSERT_TRUE(heap_walker.Allocation(2, 3));
  ASSERT_TRUE(heap_walker.Allocation(4, 5));
  // space between mappings is not checked, but could be in the future
  ASSERT_TRUE(heap_walker.Allocation(3, 4));

  // re-enable malloc, ASSERT_DEATH may allocate
  disable_malloc_.Enable();
  ASSERT_DEATH({ heap_walker.Allocation(1, 2); }, "0x1-0x2.*outside.*0x2-0x5");
  ASSERT_DEATH({ heap_walker.Allocation(1, 3); }, "0x1-0x3.*outside.*0x2-0x5");
  ASSERT_DEATH({ heap_walker.Allocation(4, 6); }, "0x4-0x6.*outside.*0x2-0x5");
  ASSERT_DEATH({ heap_walker.Allocation(5, 6); }, "0x5-0x6.*outside.*0x2-0x5");
  ASSERT_DEATH({ heap_walker.Allocation(1, 6); }, "0x1-0x6.*outside.*0x2-0x5");
}

#define buffer_begin(buffer) reinterpret_cast<uintptr_t>(buffer)
#define buffer_end(buffer) (reinterpret_cast<uintptr_t>(buffer) + sizeof(buffer))