| Index: runtime/szrt_asan.c
|
| diff --git a/runtime/szrt_asan.c b/runtime/szrt_asan.c
|
| index 797f1b99b2a7a03c01085770c6b3b466ad50f9e7..a406b9323a9f0395e3d9ef0df4b51563d1aa8c28 100644
|
| --- a/runtime/szrt_asan.c
|
| +++ b/runtime/szrt_asan.c
|
| @@ -32,7 +32,8 @@
|
| // Assuming 48 bit address space on 64 bit systems
|
| #define SHADOW_LENGTH_64 (1u << (48 - SHADOW_SCALE_LOG2))
|
| #define SHADOW_LENGTH_32 (1u << (32 - SHADOW_SCALE_LOG2))
|
| -#define IS_32_BIT (sizeof(void *) == 4)
|
| +#define WORD_SIZE (sizeof(uint32_t))
|
| +#define IS_32_BIT (sizeof(void *) == WORD_SIZE)
|
|
|
| #define SHADOW_OFFSET(p) ((uintptr_t)(p) % SHADOW_SCALE)
|
| #define IS_SHADOW_ALIGNED(p) (SHADOW_OFFSET(p) == 0)
|
| @@ -45,13 +46,51 @@
|
|
|
| static char *shadow_offset = NULL;
|
|
|
| +static void __asan_error(char *, int);
|
| +static void __asan_check(char *, int, bool);
|
| +
|
| void __asan_init(int, void **, int *);
|
| -void __asan_check(char *, int);
|
| +void __asan_check_load(char *, int);
|
| +void __asan_check_store(char *, int);
|
| void *__asan_malloc(size_t);
|
| void __asan_free(char *);
|
| void __asan_poison(char *, int);
|
| void __asan_unpoison(char *, int);
|
|
|
| +static void __asan_error(char *ptr, int size) {
|
| + fprintf(stderr, "Illegal access of %d bytes at %p\n", size, ptr);
|
| + abort();
|
| +}
|
| +
|
| +// check only the first byte of each word unless strict
|
| +static void __asan_check(char *ptr, int size, bool strict) {
|
| + assert(strict || (uintptr_t)ptr % WORD_SIZE == 0);
|
| + printf("%s check %d bytes at %p\n", (strict) ? "strict" : "loose", size, ptr);
|
| + char *end = ptr + size;
|
| + int step = (strict) ? 1 : WORD_SIZE;
|
| + for (char *cur = ptr; cur < end; cur += step) {
|
| + char shadow = *(char *)MEM2SHADOW(cur);
|
| + printf("checking %p against %p with shadow %d\n", cur, MEM2SHADOW(cur),
|
| + shadow);
|
| + if (shadow != 0 && (shadow < 0 || SHADOW_OFFSET(cur) >= shadow)) {
|
| + __asan_error(ptr, size);
|
| + }
|
| + }
|
| +}
|
| +
|
| +void __asan_check_load(char *ptr, int size) {
|
| + // aligned single word accesses may be widened single byte accesses, but for
|
| + // all else use strict check
|
| + bool strict = !((uintptr_t)ptr % WORD_SIZE == 0 && size == WORD_SIZE);
|
| + __asan_check(ptr, size, strict);
|
| +}
|
| +
|
| +void __asan_check_store(char *ptr, int size) {
|
| + // stores may never be partially out of bounds so use strict check
|
| + bool strict = true;
|
| + __asan_check(ptr, size, strict);
|
| +}
|
| +
|
| void __asan_init(int n_rzs, void **rzs, int *rz_sizes) {
|
| // ensure the redzones are large enough to hold metadata
|
| assert(RZ_SIZE >= sizeof(void *) && RZ_SIZE >= sizeof(size_t));
|
| @@ -80,19 +119,6 @@ void __asan_init(int n_rzs, void **rzs, int *rz_sizes) {
|
| }
|
| }
|
|
|
| -void __asan_check(char *ptr, int size) {
|
| - printf("check %d bytes at %p\n", size, ptr);
|
| - char *end = ptr + size;
|
| - for (; ptr < end; ++ptr) {
|
| - char shadow = *(char *)MEM2SHADOW(ptr);
|
| - printf("checking %p with shadow %d\n", ptr, shadow);
|
| - if (shadow != 0 && (shadow < 0 || SHADOW_OFFSET(ptr) > shadow)) {
|
| - fprintf(stderr, "Illegal access of %d bytes at %p\n", size, ptr);
|
| - abort();
|
| - }
|
| - }
|
| -}
|
| -
|
| void *__asan_malloc(size_t size) {
|
| printf("malloc() called with size %d\n", size);
|
| size_t padding =
|
|
|