brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.6 KiB · a614f47 Raw
268 lines · c
1//===-- asan_descriptions.h -------------------------------------*- C++ -*-===//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 AddressSanitizer, an address sanity checker.10//11// ASan-private header for asan_descriptions.cpp.12// TODO(filcab): Most struct definitions should move to the interface headers.13//===----------------------------------------------------------------------===//14#ifndef ASAN_DESCRIPTIONS_H15#define ASAN_DESCRIPTIONS_H16 17#include "asan_allocator.h"18#include "asan_thread.h"19#include "sanitizer_common/sanitizer_common.h"20#include "sanitizer_common/sanitizer_report_decorator.h"21 22namespace __asan {23 24void DescribeThread(AsanThreadContext *context);25static inline void DescribeThread(AsanThread *t) {26  if (t) DescribeThread(t->context());27}28 29class AsanThreadIdAndName {30 public:31  explicit AsanThreadIdAndName(AsanThreadContext *t);32  explicit AsanThreadIdAndName(u32 tid);33 34  // Contains "T%tid (%name)" or "T%tid" if the name is empty.35  const char *c_str() const { return &name[0]; }36 37 private:38  char name[128];39};40 41class Decorator : public __sanitizer::SanitizerCommonDecorator {42 public:43  Decorator() : SanitizerCommonDecorator() {}44  const char *Access() { return Blue(); }45  const char *Location() { return Green(); }46  const char *Allocation() { return Magenta(); }47 48  const char *ShadowByte(u8 byte) {49    switch (byte) {50      case kAsanHeapLeftRedzoneMagic:51      case kAsanArrayCookieMagic:52        return Red();53      case kAsanHeapFreeMagic:54        return Magenta();55      case kAsanStackLeftRedzoneMagic:56      case kAsanStackMidRedzoneMagic:57      case kAsanStackRightRedzoneMagic:58        return Red();59      case kAsanStackAfterReturnMagic:60        return Magenta();61      case kAsanInitializationOrderMagic:62        return Cyan();63      case kAsanUserPoisonedMemoryMagic:64      case kAsanContiguousContainerOOBMagic:65      case kAsanAllocaLeftMagic:66      case kAsanAllocaRightMagic:67        return Blue();68      case kAsanStackUseAfterScopeMagic:69        return Magenta();70      case kAsanGlobalRedzoneMagic:71        return Red();72      case kAsanInternalHeapMagic:73        return Yellow();74      case kAsanIntraObjectRedzone:75        return Yellow();76      default:77        return Default();78    }79  }80};81 82enum ShadowKind : u8 {83  kShadowKindLow,84  kShadowKindGap,85  kShadowKindHigh,86};87static const char *const ShadowNames[] = {"low shadow", "shadow gap",88                                          "high shadow"};89 90struct ShadowAddressDescription {91  uptr addr;92  ShadowKind kind;93  u8 shadow_byte;94 95  void Print() const;96};97 98bool GetShadowAddressInformation(uptr addr, ShadowAddressDescription *descr);99bool DescribeAddressIfShadow(uptr addr);100 101enum AccessType {102  kAccessTypeLeft,103  kAccessTypeRight,104  kAccessTypeInside,105  kAccessTypeUnknown,  // This means we have an AddressSanitizer bug!106};107 108struct ChunkAccess {109  uptr bad_addr;110  sptr offset;111  uptr chunk_begin;112  uptr chunk_size;113  u32 user_requested_alignment : 12;114  u32 access_type : 2;115  u32 alloc_type : 2;116};117 118struct HeapAddressDescription {119  uptr addr;120  uptr alloc_tid;121  uptr free_tid;122  u32 alloc_stack_id;123  u32 free_stack_id;124  ChunkAccess chunk_access;125 126  void Print() const;127};128 129bool GetHeapAddressInformation(uptr addr, uptr access_size,130                               HeapAddressDescription *descr);131bool DescribeAddressIfHeap(uptr addr, uptr access_size = 1);132 133struct StackAddressDescription {134  uptr addr;135  uptr tid;136  uptr offset;137  uptr frame_pc;138  uptr access_size;139  const char *frame_descr;140 141  void Print() const;142};143 144bool GetStackAddressInformation(uptr addr, uptr access_size,145                                StackAddressDescription *descr);146 147struct WildAddressDescription {148  uptr addr;149  uptr access_size;150 151  void Print() const;152};153 154struct GlobalAddressDescription {155  uptr addr;156  // Assume address is close to at most four globals.157  static const int kMaxGlobals = 4;158  __asan_global globals[kMaxGlobals];159  u32 reg_sites[kMaxGlobals];160  uptr access_size;161  u8 size;162 163  void Print(const char *bug_type = "") const;164 165  // Returns true when this descriptions points inside the same global variable166  // as other. Descriptions can have different address within the variable167  bool PointsInsideTheSameVariable(const GlobalAddressDescription &other) const;168};169 170bool GetGlobalAddressInformation(uptr addr, uptr access_size,171                                 GlobalAddressDescription *descr);172bool DescribeAddressIfGlobal(uptr addr, uptr access_size, const char *bug_type);173 174// General function to describe an address. Will try to describe the address as175// a shadow, global (variable), stack, or heap address.176// bug_type is optional and is used for checking if we're reporting an177// initialization-order-fiasco178// The proper access_size should be passed for stack, global, and heap179// addresses. Defaults to 1.180// Each of the *AddressDescription functions has its own Print() member, which181// may take access_size and bug_type parameters if needed.182void PrintAddressDescription(uptr addr, uptr access_size = 1,183                             const char *bug_type = "");184 185enum AddressKind {186  kAddressKindWild,187  kAddressKindShadow,188  kAddressKindHeap,189  kAddressKindStack,190  kAddressKindGlobal,191};192 193class AddressDescription {194  struct AddressDescriptionData {195    AddressKind kind;196    union {197      ShadowAddressDescription shadow;198      HeapAddressDescription heap;199      StackAddressDescription stack;200      GlobalAddressDescription global;201      WildAddressDescription wild;202    };203  };204 205  AddressDescriptionData data;206 207 public:208  AddressDescription() = default;209  // shouldLockThreadRegistry allows us to skip locking if we're sure we already210  // have done it.211  explicit AddressDescription(uptr addr, bool shouldLockThreadRegistry = true)212      : AddressDescription(addr, 1, shouldLockThreadRegistry) {}213  AddressDescription(uptr addr, uptr access_size,214                     bool shouldLockThreadRegistry = true);215 216  uptr Address() const {217    switch (data.kind) {218      case kAddressKindWild:219        return data.wild.addr;220      case kAddressKindShadow:221        return data.shadow.addr;222      case kAddressKindHeap:223        return data.heap.addr;224      case kAddressKindStack:225        return data.stack.addr;226      case kAddressKindGlobal:227        return data.global.addr;228    }229    UNREACHABLE("AddressInformation kind is invalid");230  }231  void Print(const char *bug_descr = nullptr) const {232    switch (data.kind) {233      case kAddressKindWild:234        data.wild.Print();235        return;236      case kAddressKindShadow:237        return data.shadow.Print();238      case kAddressKindHeap:239        return data.heap.Print();240      case kAddressKindStack:241        return data.stack.Print();242      case kAddressKindGlobal:243        // initialization-order-fiasco has a special Print()244        return data.global.Print(bug_descr);245    }246    UNREACHABLE("AddressInformation kind is invalid");247  }248 249  void StoreTo(AddressDescriptionData *dst) const { *dst = data; }250 251  const ShadowAddressDescription *AsShadow() const {252    return data.kind == kAddressKindShadow ? &data.shadow : nullptr;253  }254  const HeapAddressDescription *AsHeap() const {255    return data.kind == kAddressKindHeap ? &data.heap : nullptr;256  }257  const StackAddressDescription *AsStack() const {258    return data.kind == kAddressKindStack ? &data.stack : nullptr;259  }260  const GlobalAddressDescription *AsGlobal() const {261    return data.kind == kAddressKindGlobal ? &data.global : nullptr;262  }263};264 265}  // namespace __asan266 267#endif  // ASAN_DESCRIPTIONS_H268