summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/asan/asan_allocator.cc1
-rw-r--r--lib/asan/asan_internal.h5
-rw-r--r--lib/asan/asan_linux.cc23
-rw-r--r--lib/asan/asan_mac.cc26
-rw-r--r--lib/asan/asan_rtl.cc48
-rw-r--r--lib/asan/asan_thread.cc1
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>