Skip to content

Commit

Permalink
[compiler-rt][asan] decommit shadow memory for unmaps in fuchsia.
Browse files Browse the repository at this point in the history
This CL allows asan allocator in fuchsia to decommit shadow memory
for memory allocated using mmap.

Big allocations in asan end up being allocated via `mmap` and freed with
`munmap`. However, when that memory is freed, asan returns the
corresponding shadow memory back to the OS via a call to
`ReleaseMemoryPagesToOs`.

In fuchsia, `ReleaseMemoryPagesToOs` is a no-op: to be able to free
memory back to the OS, you have to hold a handle to the vmo you want to
modify, which is tricky at the ReleaseMemoryPagesToOs level as that
function is not exclusively used for shadow memory.

The function `__sanitizer_fill_shadow` fills a given shadow memory range
with a specific value, and if that value is 0 (unpoison) and the memory
range is bigger than a threshold parameter, it will decommit that memory
if it is all zeroes.

This CL modifies the `FlushUnneededASanShadowMemory` function in
`asan_poisoning.cpp` to add a call to `__sanitizer_fill_shadow` with
value and threshold = 0. This way, all the unneeded shadow memory gets
returned back to the OS.

A test for this behavior can be found in fxrev.dev/391974

Differential Revision: https://reviews.llvm.org/D80355

Change-Id: Id6dd85693e78a222f0329d5b2201e0da753e01c0
  • Loading branch information
mvanotti committed Jul 21, 2020
1 parent e5b3202 commit db00fac
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 6 deletions.
4 changes: 4 additions & 0 deletions compiler-rt/lib/asan/asan_fuchsia.cpp
Expand Up @@ -198,6 +198,10 @@ bool HandleDlopenInit() {
return false;
}

void FlushUnneededASanShadowMemory(uptr p, uptr size) {
__sanitizer_fill_shadow(p, size, 0, 0);
}

} // namespace __asan

// These are declared (in extern "C") by <zircon/sanitizer.h>.
Expand Down
6 changes: 6 additions & 0 deletions compiler-rt/lib/asan/asan_linux.cpp
Expand Up @@ -114,6 +114,12 @@ void AsanApplyToGlobals(globals_op_fptr op, const void *needle) {
UNIMPLEMENTED();
}

void FlushUnneededASanShadowMemory(uptr p, uptr size) {
// Since asan's mapping is compacting, the shadow chunk may be
// not page-aligned, so we only flush the page-aligned portion.
ReleaseMemoryPagesToOS(MemToShadow(p), MemToShadow(p + size));
}

#if SANITIZER_ANDROID
// FIXME: should we do anything for Android?
void AsanCheckDynamicRTPrereqs() {}
Expand Down
6 changes: 6 additions & 0 deletions compiler-rt/lib/asan/asan_mac.cpp
Expand Up @@ -89,6 +89,12 @@ void AsanApplyToGlobals(globals_op_fptr op, const void *needle) {
op(globals, size / sizeof(__asan_global));
}

void FlushUnneededASanShadowMemory(uptr p, uptr size) {
// Since asan's mapping is compacting, the shadow chunk may be
// not page-aligned, so we only flush the page-aligned portion.
ReleaseMemoryPagesToOS(MemToShadow(p), MemToShadow(p + size));
}

void ReadContextStack(void *context, uptr *stack, uptr *ssize) {
UNIMPLEMENTED();
}
Expand Down
6 changes: 0 additions & 6 deletions compiler-rt/lib/asan/asan_poisoning.cpp
Expand Up @@ -62,12 +62,6 @@ struct ShadowSegmentEndpoint {
}
};

void FlushUnneededASanShadowMemory(uptr p, uptr size) {
// Since asan's mapping is compacting, the shadow chunk may be
// not page-aligned, so we only flush the page-aligned portion.
ReleaseMemoryPagesToOS(MemToShadow(p), MemToShadow(p + size));
}

void AsanPoisonOrUnpoisonIntraObjectRedzone(uptr ptr, uptr size, bool poison) {
uptr end = ptr + size;
if (Verbosity()) {
Expand Down
6 changes: 6 additions & 0 deletions compiler-rt/lib/asan/asan_rtems.cpp
Expand Up @@ -50,6 +50,12 @@ void AsanApplyToGlobals(globals_op_fptr op, const void *needle) {
UNIMPLEMENTED();
}

void FlushUnneededASanShadowMemory(uptr p, uptr size) {
// Since asan's mapping is compacting, the shadow chunk may be
// not page-aligned, so we only flush the page-aligned portion.
ReleaseMemoryPagesToOS(MemToShadow(p), MemToShadow(p + size));
}

void AsanCheckDynamicRTPrereqs() {}
void AsanCheckIncompatibleRT() {}
void InitializeAsanInterceptors() {}
Expand Down
6 changes: 6 additions & 0 deletions compiler-rt/lib/asan/asan_win.cpp
Expand Up @@ -191,6 +191,12 @@ void AsanApplyToGlobals(globals_op_fptr op, const void *needle) {
UNIMPLEMENTED();
}

void FlushUnneededASanShadowMemory(uptr p, uptr size) {
// Since asan's mapping is compacting, the shadow chunk may be
// not page-aligned, so we only flush the page-aligned portion.
ReleaseMemoryPagesToOS(MemToShadow(p), MemToShadow(p + size));
}

// ---------------------- TSD ---------------- {{{
static bool tsd_key_inited = false;

Expand Down

0 comments on commit db00fac

Please sign in to comment.