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