Home | History | Annotate | Download | only in asan
      1 //===-- asan_poisoning.h ----------------------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file is a part of AddressSanitizer, an address sanity checker.
     11 //
     12 // Shadow memory poisoning by ASan RTL and by user application.
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "asan_interceptors.h"
     16 #include "asan_internal.h"
     17 #include "asan_mapping.h"
     18 
     19 namespace __asan {
     20 
     21 // Poisons the shadow memory for "size" bytes starting from "addr".
     22 void PoisonShadow(uptr addr, uptr size, u8 value);
     23 
     24 // Poisons the shadow memory for "redzone_size" bytes starting from
     25 // "addr + size".
     26 void PoisonShadowPartialRightRedzone(uptr addr,
     27                                      uptr size,
     28                                      uptr redzone_size,
     29                                      u8 value);
     30 
     31 // Fast versions of PoisonShadow and PoisonShadowPartialRightRedzone that
     32 // assume that memory addresses are properly aligned. Use in
     33 // performance-critical code with care.
     34 ALWAYS_INLINE void FastPoisonShadow(uptr aligned_beg, uptr aligned_size,
     35                                     u8 value) {
     36   DCHECK(flags()->poison_heap);
     37   uptr shadow_beg = MEM_TO_SHADOW(aligned_beg);
     38   uptr shadow_end = MEM_TO_SHADOW(
     39       aligned_beg + aligned_size - SHADOW_GRANULARITY) + 1;
     40   REAL(memset)((void*)shadow_beg, value, shadow_end - shadow_beg);
     41 }
     42 
     43 ALWAYS_INLINE void FastPoisonShadowPartialRightRedzone(
     44     uptr aligned_addr, uptr size, uptr redzone_size, u8 value) {
     45   DCHECK(flags()->poison_heap);
     46   u8 *shadow = (u8*)MEM_TO_SHADOW(aligned_addr);
     47   for (uptr i = 0; i < redzone_size; i += SHADOW_GRANULARITY, shadow++) {
     48     if (i + SHADOW_GRANULARITY <= size) {
     49       *shadow = 0;  // fully addressable
     50     } else if (i >= size) {
     51       *shadow = (SHADOW_GRANULARITY == 128) ? 0xff : value;  // unaddressable
     52     } else {
     53       // first size-i bytes are addressable
     54       *shadow = static_cast<u8>(size - i);
     55     }
     56   }
     57 }
     58 
     59 }  // namespace __asan
     60