brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.3 KiB · 9e059ce Raw
99 lines · cpp
1//===-- hwasan_globals.cpp ------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file is a part of HWAddressSanitizer.10//11// HWAddressSanitizer globals-specific runtime.12//===----------------------------------------------------------------------===//13 14#include "hwasan_globals.h"15 16#include "sanitizer_common/sanitizer_array_ref.h"17 18namespace __hwasan {19 20enum { NT_LLVM_HWASAN_GLOBALS = 3 };21struct hwasan_global_note {22  s32 begin_relptr;23  s32 end_relptr;24};25 26// Check that the given library meets the code model requirements for tagged27// globals. These properties are not checked at link time so they need to be28// checked at runtime.29static void CheckCodeModel(ElfW(Addr) base, const ElfW(Phdr) * phdr,30                           ElfW(Half) phnum) {31  ElfW(Addr) min_addr = -1ull, max_addr = 0;32  for (unsigned i = 0; i != phnum; ++i) {33    if (phdr[i].p_type != PT_LOAD)34      continue;35    ElfW(Addr) lo = base + phdr[i].p_vaddr, hi = lo + phdr[i].p_memsz;36    if (min_addr > lo)37      min_addr = lo;38    if (max_addr < hi)39      max_addr = hi;40  }41 42  if (max_addr - min_addr > 1ull << 32) {43    Report("FATAL: HWAddressSanitizer: library size exceeds 2^32\n");44    Die();45  }46  if (max_addr > 1ull << 48) {47    Report("FATAL: HWAddressSanitizer: library loaded above address 2^48\n");48    Die();49  }50}51 52ArrayRef<const hwasan_global> HwasanGlobalsFor(ElfW(Addr) base,53                                               const ElfW(Phdr) * phdr,54                                               ElfW(Half) phnum) {55  // Read the phdrs from this DSO.56  for (unsigned i = 0; i != phnum; ++i) {57    if (phdr[i].p_type != PT_NOTE)58      continue;59 60    const char *note = reinterpret_cast<const char *>(base + phdr[i].p_vaddr);61    const char *nend = note + phdr[i].p_memsz;62 63    // Traverse all the notes until we find a HWASan note.64    while (note < nend) {65      auto *nhdr = reinterpret_cast<const ElfW(Nhdr) *>(note);66      const char *name = note + sizeof(ElfW(Nhdr));67      const char *desc = name + RoundUpTo(nhdr->n_namesz, 4);68 69      // Discard non-HWASan-Globals notes.70      if (nhdr->n_type != NT_LLVM_HWASAN_GLOBALS ||71          internal_strcmp(name, "LLVM") != 0) {72        note = desc + RoundUpTo(nhdr->n_descsz, 4);73        continue;74      }75 76      auto *global_note = reinterpret_cast<const hwasan_global_note *>(desc);77      auto *globals_begin = reinterpret_cast<const hwasan_global *>(78          note + global_note->begin_relptr);79      auto *globals_end = reinterpret_cast<const hwasan_global *>(80          note + global_note->end_relptr);81 82      // Only libraries with instrumented globals need to be checked against the83      // code model since they use relocations that aren't checked at link time.84      //85      // There is always a HWASan globals note ("Create the note even if we86      // aren't instrumenting globals." - HWAddressSanitizer.cpp), but we can87      // elide the code model check if there are no globals.88      if (globals_begin != globals_end)89        CheckCodeModel(base, phdr, phnum);90 91      return {globals_begin, globals_end};92    }93  }94 95  return {};96}97 98}  // namespace __hwasan99