forked from OSchip/llvm-project
Refactor shadow poisoning done by asan-rt, no funtionality changes; patch by samsonov@google.com
llvm-svn: 145505
This commit is contained in:
parent
3ecf976ca9
commit
15dd3f2500
|
@ -119,25 +119,15 @@ static inline uint8_t SizeToSizeClass(size_t size) {
|
|||
return res;
|
||||
}
|
||||
|
||||
static void PoisonShadow(uintptr_t mem, size_t size, uint8_t poison) {
|
||||
CHECK(IsAligned(mem, SHADOW_GRANULARITY));
|
||||
CHECK(IsAligned(mem + size, SHADOW_GRANULARITY));
|
||||
uintptr_t shadow_beg = MemToShadow(mem);
|
||||
uintptr_t shadow_end = MemToShadow(mem + size);
|
||||
real_memset((void*)shadow_beg, poison, shadow_end - shadow_beg);
|
||||
}
|
||||
|
||||
// Given REDZONE bytes, we need to mark first size bytes
|
||||
// as addressable and the rest REDZONE-size bytes as unaddressable.
|
||||
static void PoisonMemoryPartialRightRedzone(uintptr_t mem, size_t size) {
|
||||
static void PoisonHeapPartialRightRedzone(uintptr_t mem, size_t size) {
|
||||
CHECK(size <= REDZONE);
|
||||
CHECK(IsAligned(mem, REDZONE));
|
||||
CHECK(IsPowerOfTwo(SHADOW_GRANULARITY));
|
||||
CHECK(IsPowerOfTwo(REDZONE));
|
||||
CHECK(REDZONE >= SHADOW_GRANULARITY);
|
||||
uint8_t *shadow = (uint8_t*)MemToShadow(mem);
|
||||
PoisonShadowPartialRightRedzone(shadow, size,
|
||||
REDZONE, SHADOW_GRANULARITY,
|
||||
PoisonShadowPartialRightRedzone(mem, size, REDZONE,
|
||||
kAsanHeapRightRedzoneMagic);
|
||||
}
|
||||
|
||||
|
@ -687,8 +677,8 @@ static uint8_t *Allocate(size_t alignment, size_t size, AsanStackTrace *stack) {
|
|||
m->compressed_alloc_stack_size());
|
||||
PoisonShadow(addr, rounded_size, 0);
|
||||
if (size < rounded_size) {
|
||||
PoisonMemoryPartialRightRedzone(addr + rounded_size - REDZONE,
|
||||
size & (REDZONE - 1));
|
||||
PoisonHeapPartialRightRedzone(addr + rounded_size - REDZONE,
|
||||
size & (REDZONE - 1));
|
||||
}
|
||||
if (size <= FLAG_max_malloc_fill_size) {
|
||||
real_memset((void*)addr, 0, rounded_size);
|
||||
|
|
|
@ -32,23 +32,21 @@ typedef std::map<uintptr_t, Global> MapOfGlobals;
|
|||
static MapOfGlobals *g_all_globals = NULL;
|
||||
|
||||
void PoisonRedZones(const Global &g) {
|
||||
uintptr_t shadow = MemToShadow(g.beg);
|
||||
size_t ShadowRZSize = kGlobalAndStackRedzone >> SHADOW_SCALE;
|
||||
CHECK(ShadowRZSize == 1 || ShadowRZSize == 2 || ShadowRZSize == 4);
|
||||
size_t shadow_rz_size = kGlobalAndStackRedzone >> SHADOW_SCALE;
|
||||
CHECK(shadow_rz_size == 1 || shadow_rz_size == 2 || shadow_rz_size == 4);
|
||||
// full right redzone
|
||||
uintptr_t right_rz2_offset = ShadowRZSize *
|
||||
size_t g_aligned_size = kGlobalAndStackRedzone *
|
||||
((g.size + kGlobalAndStackRedzone - 1) / kGlobalAndStackRedzone);
|
||||
real_memset((uint8_t*)shadow + right_rz2_offset,
|
||||
kAsanGlobalRedzoneMagic, ShadowRZSize);
|
||||
PoisonShadow(g.beg + g_aligned_size,
|
||||
kGlobalAndStackRedzone, kAsanGlobalRedzoneMagic);
|
||||
if ((g.size % kGlobalAndStackRedzone) != 0) {
|
||||
// partial right redzone
|
||||
uint64_t right_rz1_offset =
|
||||
ShadowRZSize * (g.size / kGlobalAndStackRedzone);
|
||||
CHECK(right_rz1_offset == right_rz2_offset - ShadowRZSize);
|
||||
PoisonShadowPartialRightRedzone((uint8_t*)(shadow + right_rz1_offset),
|
||||
uint64_t g_aligned_down_size = kGlobalAndStackRedzone *
|
||||
(g.size / kGlobalAndStackRedzone);
|
||||
CHECK(g_aligned_down_size == g_aligned_size - kGlobalAndStackRedzone);
|
||||
PoisonShadowPartialRightRedzone(g.beg + g_aligned_down_size,
|
||||
g.size % kGlobalAndStackRedzone,
|
||||
kGlobalAndStackRedzone,
|
||||
SHADOW_GRANULARITY,
|
||||
kAsanGlobalRedzoneMagic);
|
||||
}
|
||||
}
|
||||
|
@ -116,6 +114,7 @@ static void RegisterGlobal(const Global *g) {
|
|||
if (FLAG_report_globals >= 2)
|
||||
Printf("Added Global: beg=%p size=%ld name=%s\n",
|
||||
g->beg, g->size, g->name);
|
||||
CHECK(AddrIsAlignedByGranularity(g->beg));
|
||||
PoisonRedZones(*g);
|
||||
(*g_all_globals)[g->beg] = *g;
|
||||
}
|
||||
|
|
|
@ -36,28 +36,39 @@ namespace __asan {
|
|||
class AsanThread;
|
||||
struct AsanStackTrace;
|
||||
|
||||
// asan_rtl.cc
|
||||
// asan_rtl.cc
|
||||
void CheckFailed(const char *cond, const char *file, int line);
|
||||
void ShowStatsAndAbort();
|
||||
|
||||
// asan_globals.cc
|
||||
// asan_globals.cc
|
||||
bool DescribeAddrIfGlobal(uintptr_t addr);
|
||||
|
||||
// asan_malloc_linux.cc / asan_malloc_mac.cc
|
||||
// asan_malloc_linux.cc / asan_malloc_mac.cc
|
||||
void ReplaceSystemMalloc();
|
||||
|
||||
// asan_linux.cc / asan_mac.cc
|
||||
// asan_linux.cc / asan_mac.cc
|
||||
void *AsanDoesNotSupportStaticLinkage();
|
||||
void *asan_mmap(void *addr, size_t length, int prot, int flags,
|
||||
int fd, uint64_t offset);
|
||||
ssize_t asan_write(int fd, const void *buf, size_t count);
|
||||
|
||||
// asan_printf.cc
|
||||
// asan_printf.cc
|
||||
void RawWrite(const char *buffer);
|
||||
int SNPrint(char *buffer, size_t length, const char *format, ...);
|
||||
void Printf(const char *format, ...);
|
||||
void Report(const char *format, ...);
|
||||
|
||||
// asan_poisoning.cc
|
||||
// Poisons the shadow memory for "size" bytes starting from "addr".
|
||||
void PoisonShadow(uintptr_t addr, size_t size, uint8_t value);
|
||||
// Poisons the shadow memory for "redzone_size" bytes starting from
|
||||
// "addr + size".
|
||||
void PoisonShadowPartialRightRedzone(uintptr_t addr,
|
||||
uintptr_t size,
|
||||
uintptr_t redzone_size,
|
||||
uint8_t value);
|
||||
|
||||
|
||||
extern size_t FLAG_quarantine_size;
|
||||
extern int FLAG_demangle;
|
||||
extern bool FLAG_symbolize;
|
||||
|
@ -134,26 +145,6 @@ const int kAsanGlobalRedzoneMagic = 0xf9;
|
|||
static const uintptr_t kCurrentStackFrameMagic = 0x41B58AB3;
|
||||
static const uintptr_t kRetiredStackFrameMagic = 0x45E0360E;
|
||||
|
||||
// Poison the shadow memory which corresponds to 'redzone_size' bytes
|
||||
// of the original memory, where first 'size' bytes are addressable.
|
||||
static inline void
|
||||
PoisonShadowPartialRightRedzone(unsigned char *shadow,
|
||||
uintptr_t size,
|
||||
uintptr_t redzone_size,
|
||||
uintptr_t shadow_granularity,
|
||||
unsigned char magic) {
|
||||
for (uintptr_t i = 0; i < redzone_size;
|
||||
i+= shadow_granularity, shadow++) {
|
||||
if (i + shadow_granularity <= size) {
|
||||
*shadow = 0; // fully addressable
|
||||
} else if (i >= size) {
|
||||
*shadow = (shadow_granularity == 128) ? 0xff : magic; // unaddressable
|
||||
} else {
|
||||
*shadow = size - i; // first size-i bytes are addressable
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------- Atomic ---------------- {{{1
|
||||
static inline int AtomicInc(int *a) {
|
||||
if (!FLAG_mt) return ++(*a);
|
||||
|
|
|
@ -91,6 +91,10 @@ static inline bool AddrIsInShadow(uintptr_t a) {
|
|||
return AddrIsInLowShadow(a) || AddrIsInHighShadow(a);
|
||||
}
|
||||
|
||||
static inline bool AddrIsAlignedByGranularity(uintptr_t a) {
|
||||
return (a & (SHADOW_GRANULARITY - 1)) == 0;
|
||||
}
|
||||
|
||||
} // namespace __asan
|
||||
|
||||
#endif // ASAN_MAPPING_H
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
//
|
||||
// This file is a part of AddressSanitizer, an address sanity checker.
|
||||
//
|
||||
// Memory poisoning that can be made by user application.
|
||||
// Shadow memory poisoning by ASan RTL and by user application.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "asan_interceptors.h"
|
||||
|
@ -21,6 +21,33 @@
|
|||
|
||||
namespace __asan {
|
||||
|
||||
void PoisonShadow(uintptr_t addr, size_t size, uint8_t value) {
|
||||
CHECK(AddrIsAlignedByGranularity(addr));
|
||||
CHECK(AddrIsAlignedByGranularity(addr + size));
|
||||
uintptr_t shadow_beg = MemToShadow(addr);
|
||||
uintptr_t shadow_end = MemToShadow(addr + size);
|
||||
real_memset((void*)shadow_beg, value, shadow_end - shadow_beg);
|
||||
}
|
||||
|
||||
void PoisonShadowPartialRightRedzone(uintptr_t addr,
|
||||
uintptr_t size,
|
||||
uintptr_t redzone_size,
|
||||
uint8_t value) {
|
||||
CHECK(AddrIsAlignedByGranularity(addr));
|
||||
uint8_t *shadow = (uint8_t*)MemToShadow(addr);
|
||||
for (uintptr_t i = 0; i < redzone_size;
|
||||
i += SHADOW_GRANULARITY, shadow++) {
|
||||
if (i + SHADOW_GRANULARITY <= size) {
|
||||
*shadow = 0; // fully addressable
|
||||
} else if (i >= size) {
|
||||
*shadow = (SHADOW_GRANULARITY == 128) ? 0xff : value; // unaddressable
|
||||
} else {
|
||||
*shadow = size - i; // first size-i bytes are addressable
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct ShadowSegmentEndpoint {
|
||||
uint8_t *chunk;
|
||||
int8_t offset; // in [0, SHADOW_GRANULARITY)
|
||||
|
|
|
@ -469,9 +469,7 @@ static void UnpoisonStackFromHereToTop() {
|
|||
CHECK(curr_thread);
|
||||
uintptr_t top = curr_thread->stack_top();
|
||||
uintptr_t bottom = ((uintptr_t)&local_stack - kPageSize) & ~(kPageSize-1);
|
||||
uintptr_t top_shadow = MemToShadow(top);
|
||||
uintptr_t bot_shadow = MemToShadow(bottom);
|
||||
real_memset((void*)bot_shadow, 0, top_shadow - bot_shadow);
|
||||
PoisonShadow(bottom, top - bottom, 0);
|
||||
}
|
||||
|
||||
extern "C" void WRAP(longjmp)(void *env, int val) {
|
||||
|
|
Loading…
Reference in New Issue