diff options
-rw-r--r-- | lib/asan/asan_allocator.cc | 1 | ||||
-rw-r--r-- | lib/asan/asan_internal.h | 5 | ||||
-rw-r--r-- | lib/asan/asan_linux.cc | 23 | ||||
-rw-r--r-- | lib/asan/asan_mac.cc | 26 | ||||
-rw-r--r-- | lib/asan/asan_rtl.cc | 48 | ||||
-rw-r--r-- | lib/asan/asan_thread.cc | 1 |
6 files changed, 59 insertions, 45 deletions
diff --git a/lib/asan/asan_allocator.cc b/lib/asan/asan_allocator.cc index aa0413c7a..f86dc0b02 100644 --- a/lib/asan/asan_allocator.cc +++ b/lib/asan/asan_allocator.cc @@ -35,7 +35,6 @@ #include "asan_thread.h" #include "asan_thread_registry.h" -#include <sys/mman.h> #include <stdint.h> #include <string.h> #include <unistd.h> diff --git a/lib/asan/asan_internal.h b/lib/asan/asan_internal.h index 041aa3f6c..d0790a7c8 100644 --- a/lib/asan/asan_internal.h +++ b/lib/asan/asan_internal.h @@ -88,9 +88,10 @@ void OutOfMemoryMessageAndDie(const char *mem_type, size_t size); // asan_linux.cc / asan_mac.cc void *AsanDoesNotSupportStaticLinkage(); int AsanOpenReadonly(const char* filename); -void *asan_mmap(void *addr, size_t length, int prot, int flags, - int fd, uint64_t offset); +void *AsanMmapFixedNoReserve(uintptr_t fixed_addr, size_t size); +void *AsanMmapFixedReserve(uintptr_t fixed_addr, size_t size); +void *AsanMprotect(uintptr_t fixed_addr, size_t size); void *AsanMmapSomewhereOrDie(size_t size, const char *where); void AsanUnmapOrDie(void *ptr, size_t size); diff --git a/lib/asan/asan_linux.cc b/lib/asan/asan_linux.cc index 45f94e9e0..26a08ae8f 100644 --- a/lib/asan/asan_linux.cc +++ b/lib/asan/asan_linux.cc @@ -30,7 +30,7 @@ void *AsanDoesNotSupportStaticLinkage() { return &_DYNAMIC; } -void *asan_mmap(void *addr, size_t length, int prot, int flags, +static void *asan_mmap(void *addr, size_t length, int prot, int flags, int fd, uint64_t offset) { # if __WORDSIZE == 64 return (void *)syscall(__NR_mmap, addr, length, prot, flags, fd, offset); @@ -50,6 +50,27 @@ void *AsanMmapSomewhereOrDie(size_t size, const char *mem_type) { return res; } +void *AsanMmapFixedNoReserve(uintptr_t fixed_addr, size_t size) { + return asan_mmap((void*)fixed_addr, size, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE, + 0, 0); +} + +void *AsanMmapFixedReserve(uintptr_t fixed_addr, size_t size) { + return asan_mmap((void*)fixed_addr, size, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON | MAP_FIXED, + 0, 0); +} + +void *AsanMprotect(uintptr_t fixed_addr, size_t size) { + return asan_mmap((void*)fixed_addr, size, + PROT_NONE, + MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE, + 0, 0); +} + void AsanUnmapOrDie(void *addr, size_t size) { if (!addr || !size) return; int res = syscall(__NR_munmap, addr, size); diff --git a/lib/asan/asan_mac.cc b/lib/asan/asan_mac.cc index 15d0987fa..b202e639b 100644 --- a/lib/asan/asan_mac.cc +++ b/lib/asan/asan_mac.cc @@ -22,6 +22,7 @@ #include "asan_thread_registry.h" #include <sys/mman.h> +#include <fcntl.h> #include <unistd.h> #include <new> @@ -40,12 +41,12 @@ void *AsanDoesNotSupportStaticLinkage() { return NULL; } -void *asan_mmap(void *addr, size_t length, int prot, int flags, +static void *asan_mmap(void *addr, size_t length, int prot, int flags, int fd, uint64_t offset) { return mmap(addr, length, prot, flags, fd, offset); } -ssize_t asan_write(int fd, const void *buf, size_t count) { +ssize_t AsanWrite(int fd, const void *buf, size_t count) { return write(fd, buf, count); } @@ -60,6 +61,27 @@ void *AsanMmapSomewhereOrDie(size_t size, const char *mem_type) { return res; } +void *AsanMmapFixedNoReserve(uintptr_t fixed_addr, size_t size) { + return asan_mmap((void*)fixed_addr, size, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE, + 0, 0); +} + +void *AsanMmapFixedReserve(uintptr_t fixed_addr, size_t size) { + return asan_mmap((void*)fixed_addr, size, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON | MAP_FIXED, + 0, 0); +} + +void *AsanMprotect(uintptr_t fixed_addr, size_t size) { + return asan_mmap((void*)fixed_addr, size, + PROT_NONE, + MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE, + 0, 0); +} + void AsanUnmapOrDie(void *addr, size_t size) { if (!addr || !size) return; int res = munmap(addr, size); diff --git a/lib/asan/asan_rtl.cc b/lib/asan/asan_rtl.cc index 299f647e1..50be6df6b 100644 --- a/lib/asan/asan_rtl.cc +++ b/lib/asan/asan_rtl.cc @@ -16,9 +16,7 @@ #include "asan_interface.h" #include "asan_internal.h" #include "asan_lock.h" -#ifdef __APPLE__ #include "asan_mac.h" -#endif #include "asan_mapping.h" #include "asan_stack.h" #include "asan_stats.h" @@ -36,7 +34,6 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <sys/mman.h> #include <sys/stat.h> #include <sys/types.h> #ifndef ANDROID @@ -188,37 +185,13 @@ void OutOfMemoryMessageAndDie(const char *mem_type, size_t size) { ShowStatsAndAbort(); } -static char *mmap_pages(size_t start_page, size_t n_pages, const char *mem_type, - bool abort_on_failure = true) { - void *res = asan_mmap((void*)start_page, kPageSize * n_pages, - PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE, 0, 0); - // Printf("%p => %p\n", (void*)start_page, res); - char *ch = (char*)res; - if (res == (void*)-1L && abort_on_failure) { - OutOfMemoryMessageAndDie(mem_type, n_pages * kPageSize); - } - CHECK(res == (void*)start_page || res == (void*)-1L); - return ch; -} - -// mmap range [beg, end] -static char *mmap_range(uintptr_t beg, uintptr_t end, const char *mem_type) { +// Reserve memory range [beg, end]. +static void ReserveShadowMemoryRange(uintptr_t beg, uintptr_t end) { CHECK((beg % kPageSize) == 0); CHECK(((end + 1) % kPageSize) == 0); - // Printf("mmap_range %p %p %ld\n", beg, end, (end - beg) / kPageSize); - return mmap_pages(beg, (end - beg + 1) / kPageSize, mem_type); -} - -// protect range [beg, end] -static void protect_range(uintptr_t beg, uintptr_t end) { - CHECK((beg % kPageSize) == 0); - CHECK(((end+1) % kPageSize) == 0); - // Printf("protect_range %p %p %ld\n", beg, end, (end - beg) / kPageSize); - void *res = asan_mmap((void*)beg, end - beg + 1, - PROT_NONE, - MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE, 0, 0); - CHECK(res == (void*)beg); + size_t size = end - beg + 1; + void *res = AsanMmapFixedNoReserve(beg, size); + CHECK(res == (void*)beg && "ReserveShadowMemoryRange failed"); } // ---------------------- LowLevelAllocator ------------- {{{1 @@ -349,9 +322,7 @@ static void ASAN_OnSIGSEGV(int, siginfo_t *siginfo, void *context) { // this address. const uintptr_t chunk_size = kPageSize << 10; // 4M uintptr_t chunk = addr & ~(chunk_size - 1); - asan_mmap((void*)chunk, chunk_size, - PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON | MAP_FIXED, 0, 0); + AsanMmapFixedReserve(chunk, chunk_size); return; } // Write the first message using the bullet-proof write. @@ -813,13 +784,14 @@ void __asan_init() { if (!FLAG_lazy_shadow) { if (kLowShadowBeg != kLowShadowEnd) { // mmap the low shadow plus one page. - mmap_range(kLowShadowBeg - kPageSize, kLowShadowEnd, "LowShadow"); + ReserveShadowMemoryRange(kLowShadowBeg - kPageSize, kLowShadowEnd); } // mmap the high shadow. - mmap_range(kHighShadowBeg, kHighShadowEnd, "HighShadow"); + ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd); } // protect the gap - protect_range(kShadowGapBeg, kShadowGapEnd); + void *prot = AsanMprotect(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1); + CHECK(prot == (void*)kShadowGapBeg); } // On Linux AsanThread::ThreadStart() calls malloc() that's why asan_inited diff --git a/lib/asan/asan_thread.cc b/lib/asan/asan_thread.cc index 214b21ae8..329197dd4 100644 --- a/lib/asan/asan_thread.cc +++ b/lib/asan/asan_thread.cc @@ -21,7 +21,6 @@ #include "sysinfo/sysinfo.h" #endif -#include <sys/mman.h> #include <sys/time.h> #include <sys/resource.h> #include <pthread.h> |