[asan] Re-exec without ASLR if needed on 64-bit Linux (#132682)

This generalizes https://github.com/llvm/llvm-project/pull/131975 to non-32-bit Linux (i.e., 64-bit Linux).

This works around an edge case in 64-bit Linux, whereby the memory layout is incompatible if the stack size is unlimited AND ASLR entropy is 31+ bits (see https://github.com/google/sanitizers/issues/856#issuecomment-2747076811).

More generally, this "re-exec without ASLR if layout is incompatible" is a hammer that can work around most shadow mapping issues, without incurring the overhead of using a dynamic shadow.
This commit is contained in:
Thurston Dang
2025-03-24 16:24:38 -07:00
committed by GitHub
parent 567b0f8923
commit 3ce3d889f6

View File

@@ -109,12 +109,14 @@ void InitializeShadowMemory() {
ProtectGap(kShadowGap2Beg, kShadowGap2End - kShadowGap2Beg + 1);
ProtectGap(kShadowGap3Beg, kShadowGap3End - kShadowGap3Beg + 1);
} else {
// The shadow mappings can shadow the entire user address space. However,
// on 32-bit systems, the maximum ASLR entropy (currently up to 16-bits
// == 256MB) is a significant chunk of the address space; reclaiming it by
// disabling ASLR might allow chonky binaries to run.
if (sizeof(uptr) == 32)
TryReExecWithoutASLR();
// ASan's mappings can usually shadow the entire address space, even with
// maximum ASLR entropy. However:
// - On 32-bit systems, the maximum ASLR entropy (currently up to 16-bits
// == 256MB) is a significant chunk of the address space; reclaiming it
// by disabling ASLR might allow chonky binaries to run.
// - On 64-bit systems, some settings (e.g., for Linux, unlimited stack
// size plus 31+ bits of entropy) can lead to an incompatible layout.
TryReExecWithoutASLR();
Report(
"Shadow memory range interleaves with an existing memory mapping. "