Skip to content

[HWASan] [compiler-rt] support non-4k pages on Android #95069

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion compiler-rt/lib/asan/asan_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ uptr FindDynamicShadowStart() {
# endif

return MapDynamicShadow(shadow_size_bytes, ASAN_SHADOW_SCALE,
/*min_shadow_base_alignment*/ 0, kHighMemEnd);
/*min_shadow_base_alignment*/ 0, kHighMemEnd,
GetMmapGranularity());
}

void AsanApplyToGlobals(globals_op_fptr op, const void *needle) {
Expand Down
3 changes: 2 additions & 1 deletion compiler-rt/lib/asan/asan_mac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ bool IsSystemHeapAddress (uptr addr) { return false; }

uptr FindDynamicShadowStart() {
return MapDynamicShadow(MemToShadowSize(kHighMemEnd), ASAN_SHADOW_SCALE,
/*min_shadow_base_alignment*/ 0, kHighMemEnd);
/*min_shadow_base_alignment*/ 0, kHighMemEnd,
GetMmapGranularity());
}

// No-op. Mac does not support static linkage anyway.
Expand Down
3 changes: 2 additions & 1 deletion compiler-rt/lib/asan/asan_premap_shadow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ uptr PremapShadowSize() {
// PremapShadowSize() bytes on the right of it are mapped r/o.
uptr PremapShadow() {
return MapDynamicShadow(PremapShadowSize(), /*mmap_alignment_scale*/ 3,
/*min_shadow_base_alignment*/ 0, kHighMemEnd);
/*min_shadow_base_alignment*/ 0, kHighMemEnd,
GetMmapGranularity());
}

bool PremapShadowFailed() {
Expand Down
17 changes: 11 additions & 6 deletions compiler-rt/lib/hwasan/hwasan_dynamic_shadow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,20 @@ decltype(__hwasan_shadow)* __hwasan_premap_shadow();

namespace __hwasan {

// We cannot call anything in libc here (see comment above), so we need to
// assume the biggest allowed page size.
// Android max page size is defined as 16k here:
// https://android.googlesource.com/platform/bionic/+/main/libc/platform/bionic/page.h#41
static constexpr uptr kMaxGranularity = 16384;

// Conservative upper limit.
static uptr PremapShadowSize() {
return RoundUpTo(GetMaxVirtualAddress() >> kShadowScale,
GetMmapGranularity());
return RoundUpTo(GetMaxVirtualAddress() >> kShadowScale, kMaxGranularity);
}

static uptr PremapShadow() {
return MapDynamicShadow(PremapShadowSize(), kShadowScale,
kShadowBaseAlignment, kHighMemEnd);
kShadowBaseAlignment, kHighMemEnd, kMaxGranularity);
}

static bool IsPremapShadowAvailable() {
Expand All @@ -56,7 +61,7 @@ static bool IsPremapShadowAvailable() {
}

static uptr FindPremappedShadowStart(uptr shadow_size_bytes) {
const uptr granularity = GetMmapGranularity();
const uptr granularity = kMaxGranularity;
const uptr shadow_start = reinterpret_cast<uptr>(&__hwasan_shadow);
const uptr premap_shadow_size = PremapShadowSize();
const uptr shadow_size = RoundUpTo(shadow_size_bytes, granularity);
Expand Down Expand Up @@ -109,7 +114,7 @@ uptr FindDynamicShadowStart(uptr shadow_size_bytes) {
if (IsPremapShadowAvailable())
return FindPremappedShadowStart(shadow_size_bytes);
return MapDynamicShadow(shadow_size_bytes, kShadowScale, kShadowBaseAlignment,
kHighMemEnd);
kHighMemEnd, kMaxGranularity);
}

} // namespace __hwasan
Expand All @@ -135,7 +140,7 @@ uptr FindDynamicShadowStart(uptr shadow_size_bytes) {
RingBufferSize());
# endif
return MapDynamicShadow(shadow_size_bytes, kShadowScale, kShadowBaseAlignment,
kHighMemEnd);
kHighMemEnd, GetMmapGranularity());
}

} // namespace __hwasan
Expand Down
3 changes: 2 additions & 1 deletion compiler-rt/lib/memprof/memprof_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ void InitializePlatformExceptionHandlers() {}
uptr FindDynamicShadowStart() {
uptr shadow_size_bytes = MemToShadowSize(kHighMemEnd);
return MapDynamicShadow(shadow_size_bytes, SHADOW_SCALE,
/*min_shadow_base_alignment*/ 0, kHighMemEnd);
/*min_shadow_base_alignment*/ 0, kHighMemEnd,
GetMmapGranularity());
}

void *MemprofDlSymNext(const char *sym) { return dlsym(RTLD_NEXT, sym); }
Expand Down
17 changes: 8 additions & 9 deletions compiler-rt/lib/sanitizer_common/sanitizer_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,10 @@ inline int Verbosity() {
return atomic_load(&current_verbosity, memory_order_relaxed);
}

#if SANITIZER_ANDROID
inline uptr GetPageSize() {
// Android post-M sysconf(_SC_PAGESIZE) crashes if called from .preinit_array.
return 4096;
}
inline uptr GetPageSizeCached() {
return 4096;
}
#if SANITIZER_ANDROID && !defined(__aarch64__)
// 32-bit Android only has 4k pages.
inline uptr GetPageSize() { return 4096; }
inline uptr GetPageSizeCached() { return 4096; }
#else
uptr GetPageSize();
extern uptr PageSizeCached;
Expand All @@ -77,6 +73,7 @@ inline uptr GetPageSizeCached() {
return PageSizeCached;
}
#endif

uptr GetMmapGranularity();
uptr GetMaxVirtualAddress();
uptr GetMaxUserVirtualAddress();
Expand All @@ -91,6 +88,7 @@ void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,

// Memory management
void *MmapOrDie(uptr size, const char *mem_type, bool raw_report = false);

inline void *MmapOrDieQuietly(uptr size, const char *mem_type) {
return MmapOrDie(size, mem_type, /*raw_report*/ true);
}
Expand Down Expand Up @@ -139,7 +137,8 @@ void UnmapFromTo(uptr from, uptr to);
// shadow_size_bytes bytes on the right, which on linux is mapped no access.
// The high_mem_end may be updated if the original shadow size doesn't fit.
uptr MapDynamicShadow(uptr shadow_size_bytes, uptr shadow_scale,
uptr min_shadow_base_alignment, uptr &high_mem_end);
uptr min_shadow_base_alignment, uptr &high_mem_end,
uptr granularity);

// Let S = max(shadow_size, num_aliases * alias_size, ring_buffer_size).
// Reserves 2*S bytes of address space to the right of the returned address and
Expand Down
4 changes: 2 additions & 2 deletions compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1136,7 +1136,7 @@ uptr GetMaxUserVirtualAddress() {
return addr;
}

# if !SANITIZER_ANDROID
# if !SANITIZER_ANDROID || defined(__aarch64__)
uptr GetPageSize() {
# if SANITIZER_LINUX && (defined(__x86_64__) || defined(__i386__)) && \
defined(EXEC_PAGESIZE)
Expand All @@ -1155,7 +1155,7 @@ uptr GetPageSize() {
return sysconf(_SC_PAGESIZE); // EXEC_PAGESIZE may not be trustworthy.
# endif
}
# endif // !SANITIZER_ANDROID
# endif

uptr ReadBinaryName(/*out*/ char *buf, uptr buf_len) {
# if SANITIZER_SOLARIS
Expand Down
5 changes: 2 additions & 3 deletions compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -995,9 +995,8 @@ void UnmapFromTo(uptr from, uptr to) {
}

uptr MapDynamicShadow(uptr shadow_size_bytes, uptr shadow_scale,
uptr min_shadow_base_alignment,
UNUSED uptr &high_mem_end) {
const uptr granularity = GetMmapGranularity();
uptr min_shadow_base_alignment, UNUSED uptr &high_mem_end,
uptr granularity) {
const uptr alignment =
Max<uptr>(granularity << shadow_scale, 1ULL << min_shadow_base_alignment);
const uptr left_padding =
Expand Down
4 changes: 2 additions & 2 deletions compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1188,8 +1188,8 @@ uptr GetMaxVirtualAddress() {
}

uptr MapDynamicShadow(uptr shadow_size_bytes, uptr shadow_scale,
uptr min_shadow_base_alignment, uptr &high_mem_end) {
const uptr granularity = GetMmapGranularity();
uptr min_shadow_base_alignment, uptr &high_mem_end,
uptr granularity) {
const uptr alignment =
Max<uptr>(granularity << shadow_scale, 1ULL << min_shadow_base_alignment);
const uptr left_padding =
Expand Down
5 changes: 2 additions & 3 deletions compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -384,9 +384,8 @@ bool DontDumpShadowMemory(uptr addr, uptr length) {
}

uptr MapDynamicShadow(uptr shadow_size_bytes, uptr shadow_scale,
uptr min_shadow_base_alignment,
UNUSED uptr &high_mem_end) {
const uptr granularity = GetMmapGranularity();
uptr min_shadow_base_alignment, UNUSED uptr &high_mem_end,
uptr granularity) {
const uptr alignment =
Max<uptr>(granularity << shadow_scale, 1ULL << min_shadow_base_alignment);
const uptr left_padding =
Expand Down
Loading