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 &&