forked from OSchip/llvm-project
[compiler-rt][asan] decommit shadow memory for unmaps in fuchsia.
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
This commit is contained in:
parent
e5b3202b6f
commit
db00fac2a2
|
@ -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>.
|
||||
|
|
|
@ -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() {}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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() {}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue