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

Commit 9b528919 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Validate allocations against mappings"

parents 7472cf6c 3ca1976f
Loading
Loading
Loading
Loading
+12 −0
Original line number Original line Diff line number Diff line
@@ -35,6 +35,13 @@ bool HeapWalker::Allocation(uintptr_t begin, uintptr_t end) {
    end = begin + 1;
    end = begin + 1;
  }
  }
  Range range{begin, end};
  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{}));
  auto inserted = allocations_.insert(std::pair<Range, AllocationInfo>(range, AllocationInfo{}));
  if (inserted.second) {
  if (inserted.second) {
    valid_allocations_range_.begin = std::min(valid_allocations_range_.begin, begin);
    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) {
void HeapWalker::Root(uintptr_t begin, uintptr_t end) {
  roots_.push_back(Range{begin, end});
  roots_.push_back(Range{begin, end});
}
}
+4 −0
Original line number Original line Diff line number Diff line
@@ -59,6 +59,8 @@ class HeapWalker {
        segv_page_count_(0) {
        segv_page_count_(0) {
    valid_allocations_range_.end = 0;
    valid_allocations_range_.end = 0;
    valid_allocations_range_.begin = ~valid_allocations_range_.end;
    valid_allocations_range_.begin = ~valid_allocations_range_.end;
    valid_mappings_range_.end = 0;
    valid_mappings_range_.begin = ~valid_allocations_range_.end;


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


  ~HeapWalker() {}
  ~HeapWalker() {}
  bool Allocation(uintptr_t begin, uintptr_t end);
  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(uintptr_t begin, uintptr_t end);
  void Root(const allocator::vector<uintptr_t>& vals);
  void Root(const allocator::vector<uintptr_t>& vals);


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


  allocator::vector<Range> roots_;
  allocator::vector<Range> roots_;
  allocator::vector<uintptr_t> root_vals_;
  allocator::vector<uintptr_t> root_vals_;
+5 −0
Original line number Original line 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<Mapping>& mappings,
                                        const allocator::vector<uintptr_t>& refs) {
                                        const allocator::vector<uintptr_t>& refs) {
  MEM_ALOGI("searching process %d for allocations", pid_);
  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> heap_mappings{mappings};
  allocator::vector<Mapping> anon_mappings{mappings};
  allocator::vector<Mapping> anon_mappings{mappings};
  allocator::vector<Mapping> globals_mappings{mappings};
  allocator::vector<Mapping> globals_mappings{mappings};
+18 −0
Original line number Original line Diff line number Diff line
@@ -73,6 +73,24 @@ TEST_F(HeapWalkerTest, zero) {
  ASSERT_FALSE(heap_walker.Allocation(2, 3));
  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_begin(buffer) reinterpret_cast<uintptr_t>(buffer)
#define buffer_end(buffer) (reinterpret_cast<uintptr_t>(buffer) + sizeof(buffer))
#define buffer_end(buffer) (reinterpret_cast<uintptr_t>(buffer) + sizeof(buffer))