summaryrefslogtreecommitdiff
path: root/lib/asan/asan_poisoning.cc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/asan/asan_poisoning.cc')
-rw-r--r--lib/asan/asan_poisoning.cc63
1 files changed, 53 insertions, 10 deletions
diff --git a/lib/asan/asan_poisoning.cc b/lib/asan/asan_poisoning.cc
index 772b5e64b0277..280aaeb909a36 100644
--- a/lib/asan/asan_poisoning.cc
+++ b/lib/asan/asan_poisoning.cc
@@ -14,6 +14,7 @@
#include "asan_poisoning.h"
#include "sanitizer_common/sanitizer_libc.h"
+#include "sanitizer_common/sanitizer_flags.h"
namespace __asan {
@@ -68,7 +69,7 @@ void __asan_poison_memory_region(void const volatile *addr, uptr size) {
if (!flags()->allow_user_poisoning || size == 0) return;
uptr beg_addr = (uptr)addr;
uptr end_addr = beg_addr + size;
- if (flags()->verbosity >= 1) {
+ if (common_flags()->verbosity >= 1) {
Printf("Trying to poison memory region [%p, %p)\n",
(void*)beg_addr, (void*)end_addr);
}
@@ -110,7 +111,7 @@ void __asan_unpoison_memory_region(void const volatile *addr, uptr size) {
if (!flags()->allow_user_poisoning || size == 0) return;
uptr beg_addr = (uptr)addr;
uptr end_addr = beg_addr + size;
- if (flags()->verbosity >= 1) {
+ if (common_flags()->verbosity >= 1) {
Printf("Trying to unpoison memory region [%p, %p)\n",
(void*)beg_addr, (void*)end_addr);
}
@@ -183,37 +184,37 @@ uptr __asan_region_is_poisoned(uptr beg, uptr size) {
extern "C" SANITIZER_INTERFACE_ATTRIBUTE
-u16 __sanitizer_unaligned_load16(const u16 *p) {
+u16 __sanitizer_unaligned_load16(const uu16 *p) {
CHECK_SMALL_REGION(p, sizeof(*p), false);
return *p;
}
extern "C" SANITIZER_INTERFACE_ATTRIBUTE
-u32 __sanitizer_unaligned_load32(const u32 *p) {
+u32 __sanitizer_unaligned_load32(const uu32 *p) {
CHECK_SMALL_REGION(p, sizeof(*p), false);
return *p;
}
extern "C" SANITIZER_INTERFACE_ATTRIBUTE
-u64 __sanitizer_unaligned_load64(const u64 *p) {
+u64 __sanitizer_unaligned_load64(const uu64 *p) {
CHECK_SMALL_REGION(p, sizeof(*p), false);
return *p;
}
extern "C" SANITIZER_INTERFACE_ATTRIBUTE
-void __sanitizer_unaligned_store16(u16 *p, u16 x) {
+void __sanitizer_unaligned_store16(uu16 *p, u16 x) {
CHECK_SMALL_REGION(p, sizeof(*p), true);
*p = x;
}
extern "C" SANITIZER_INTERFACE_ATTRIBUTE
-void __sanitizer_unaligned_store32(u32 *p, u32 x) {
+void __sanitizer_unaligned_store32(uu32 *p, u32 x) {
CHECK_SMALL_REGION(p, sizeof(*p), true);
*p = x;
}
extern "C" SANITIZER_INTERFACE_ATTRIBUTE
-void __sanitizer_unaligned_store64(u64 *p, u64 x) {
+void __sanitizer_unaligned_store64(uu64 *p, u64 x) {
CHECK_SMALL_REGION(p, sizeof(*p), true);
*p = x;
}
@@ -244,13 +245,55 @@ static void PoisonAlignedStackMemory(uptr addr, uptr size, bool do_poison) {
}
void __asan_poison_stack_memory(uptr addr, uptr size) {
- if (flags()->verbosity > 0)
+ if (common_flags()->verbosity > 0)
Report("poisoning: %p %zx\n", (void*)addr, size);
PoisonAlignedStackMemory(addr, size, true);
}
void __asan_unpoison_stack_memory(uptr addr, uptr size) {
- if (flags()->verbosity > 0)
+ if (common_flags()->verbosity > 0)
Report("unpoisoning: %p %zx\n", (void*)addr, size);
PoisonAlignedStackMemory(addr, size, false);
}
+
+void __sanitizer_annotate_contiguous_container(void *beg_p, void *end_p,
+ void *old_mid_p,
+ void *new_mid_p) {
+ uptr beg = reinterpret_cast<uptr>(beg_p);
+ uptr end= reinterpret_cast<uptr>(end_p);
+ uptr old_mid = reinterpret_cast<uptr>(old_mid_p);
+ uptr new_mid = reinterpret_cast<uptr>(new_mid_p);
+ uptr granularity = SHADOW_GRANULARITY;
+ CHECK(beg <= end && beg <= old_mid && beg <= new_mid && old_mid <= end &&
+ new_mid <= end && IsAligned(beg, granularity));
+ CHECK_LE(end - beg,
+ FIRST_32_SECOND_64(1UL << 30, 1UL << 34)); // Sanity check.
+
+ uptr a = RoundDownTo(Min(old_mid, new_mid), granularity);
+ uptr c = RoundUpTo(Max(old_mid, new_mid), granularity);
+ uptr b = new_mid;
+ uptr b1 = RoundDownTo(b, granularity);
+ uptr b2 = RoundUpTo(b, granularity);
+ uptr d = old_mid;
+ uptr d1 = RoundDownTo(d, granularity);
+ uptr d2 = RoundUpTo(d, granularity);
+ // Currently we should be in this state:
+ // [a, d1) is good, [d2, c) is bad, [d1, d2) is partially good.
+ // Make a quick sanity check that we are indeed in this state.
+ if (d1 != d2)
+ CHECK_EQ(*(u8*)MemToShadow(d1), d - d1);
+ if (a + granularity <= d1)
+ CHECK_EQ(*(u8*)MemToShadow(a), 0);
+ if (d2 + granularity <= c && c <= end)
+ CHECK_EQ(*(u8 *)MemToShadow(c - granularity), kAsanUserPoisonedMemoryMagic);
+
+ // New state:
+ // [a, b1) is good, [b2, c) is bad, [b1, b2) is partially good.
+ // FIXME: we may want to have a separate poison magic value.
+ PoisonShadow(a, b1 - a, 0);
+ PoisonShadow(b2, c - b2, kAsanUserPoisonedMemoryMagic);
+ if (b1 != b2) {
+ CHECK_EQ(b2 - b1, granularity);
+ *(u8*)MemToShadow(b1) = static_cast<u8>(b - b1);
+ }
+}