From 9ae453628f50a5c23ac6ecf621edfc06344b5e21 Mon Sep 17 00:00:00 2001 From: Joshua Peraza Date: Thu, 20 Sep 2018 09:16:22 -0700 Subject: [PATCH] android: handle RELRO sharing by the Chromium linker Bug: crashpad:253 Change-Id: I7d6b1bfebe621d90a4b69dd44073abf471fa822c Reviewed-on: https://chromium-review.googlesource.com/1232293 Commit-Queue: Joshua Peraza Reviewed-by: Mark Mentovai --- util/linux/memory_map.cc | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/util/linux/memory_map.cc b/util/linux/memory_map.cc index 345f63ca..ea33f300 100644 --- a/util/linux/memory_map.cc +++ b/util/linux/memory_map.cc @@ -316,6 +316,37 @@ std::vector MemoryMap::FindFilePossibleMmapStarts( return std::vector(); } +#if defined(OS_ANDROID) + // The Android Chromium linker uses ashmem to share RELRO segments between + // processes. The original RELRO segment has been unmapped and replaced with a + // mapping named "/dev/ashmem/RELRO:" where is the base + // library name (e.g. libchrome.so) sans any preceding path that may be + // present in other mappings for the library. + // https://crashpad.chromium.org/bug/253 + static constexpr char kRelro[] = "/dev/ashmem/RELRO:"; + if (mapping.name.compare(0, strlen(kRelro), kRelro, 0, strlen(kRelro)) == 0) { + // The kernel appends "(deleted)" to ashmem mappings because there isn't + // any corresponding file on the filesystem. + static constexpr char kDeleted[] = " (deleted)"; + size_t libname_end = mapping.name.rfind(kDeleted); + DCHECK_NE(libname_end, std::string::npos); + if (libname_end == std::string::npos) { + libname_end = mapping.name.size(); + } + + std::string libname = + mapping.name.substr(strlen(kRelro), libname_end - strlen(kRelro)); + for (const auto& candidate : mappings_) { + if (candidate.name.rfind(libname) != std::string::npos) { + possible_starts.push_back(&candidate); + } + if (mapping.Equals(candidate)) { + return possible_starts; + } + } + } +#endif // OS_ANDROID + for (const auto& candidate : mappings_) { if (candidate.device == mapping.device && candidate.inode == mapping.inode &&