Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions compiler-rt/lib/asan/asan_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ void ReplaceSystemMalloc();
uptr FindDynamicShadowStart();
void AsanCheckDynamicRTPrereqs();
void AsanCheckIncompatibleRT();
void TryReExecWithoutASLR();

// Unpoisons platform-specific stacks.
// Returns true if all stacks have been unpoisoned.
Expand Down
28 changes: 28 additions & 0 deletions compiler-rt/lib/asan/asan_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
# include <pthread.h>
# include <stdio.h>
# include <sys/mman.h>
# include <sys/personality.h>
# include <sys/resource.h>
# include <sys/syscall.h>
# include <sys/time.h>
Expand Down Expand Up @@ -107,6 +108,33 @@ void FlushUnneededASanShadowMemory(uptr p, uptr size) {
ReleaseMemoryPagesToOS(MemToShadow(p), MemToShadow(p + size));
}

void ReExecWithoutASLR() {
// ASLR personality check.
// Caution: 'personality' is sometimes forbidden by sandboxes, so only call
// this function as a last resort (when the memory mapping is incompatible
// and ASan would fail anyway).
int old_personality = personality(0xffffffff);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would have

if (old_personality == -1) {
  [log error]
  return;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

bool aslr_on =
(old_personality != -1) && ((old_personality & ADDR_NO_RANDOMIZE) == 0);

if (aslr_on) {
// Disable ASLR if the memory layout was incompatible.
// Alternatively, we could just keep re-execing until we get lucky
// with a compatible randomized layout, but the risk is that if it's
// not an ASLR-related issue, we will be stuck in an infinite loop of
// re-execing (unless we change ReExec to pass a parameter of the
// number of retries allowed.)
VReport(1,
"WARNING: AddressSanitizer: memory layout is incompatible, "
"possibly due to high-entropy ASLR.\n"
"Re-execing with fixed virtual address space.\n"
"N.B. reducing ASLR entropy is preferable.\n");
CHECK_NE(personality(old_personality | ADDR_NO_RANDOMIZE), -1);

ReExec();
}
}

# if SANITIZER_ANDROID
// FIXME: should we do anything for Android?
void AsanCheckDynamicRTPrereqs() {}
Expand Down
3 changes: 3 additions & 0 deletions compiler-rt/lib/asan/asan_mac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ uptr FindDynamicShadowStart() {
GetMmapGranularity());
}

// Not used.
void TryReExecWithoutASLR() {}

// No-op. Mac does not support static linkage anyway.
void AsanCheckDynamicRTPrereqs() {}

Expand Down
9 changes: 9 additions & 0 deletions compiler-rt/lib/asan/asan_shadow_setup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,15 @@ void InitializeShadowMemory() {
ProtectGap(kShadowGap2Beg, kShadowGap2End - kShadowGap2Beg + 1);
ProtectGap(kShadowGap3Beg, kShadowGap3End - kShadowGap3Beg + 1);
} else {
# if SANITIZER_LINUX
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the call is within this guard, why do we need a dummy for macos and windows?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

// 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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this correct? From what I can see, uptr is an alias of uintptr_t, meaning sizeof is 4 on 32bit systems and this branch is never taken on any platform.

(Yes, I'm late.)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...oh, #132682 deleted that check. This question no longer matters.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I can see, uptr is an alias of uintptr_t, meaning sizeof is 4 on 32bit systems and this branch is never taken on any platform.

You're right, that was a bug. Nice catch :-)

TryReExecWithoutASLR();
# endif

Report(
"Shadow memory range interleaves with an existing memory mapping. "
"ASan cannot proceed correctly. ABORTING.\n");
Expand Down
4 changes: 4 additions & 0 deletions compiler-rt/lib/asan/asan_win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ uptr __asan_get_shadow_memory_dynamic_address() {
__asan_init();
return __asan_shadow_memory_dynamic_address;
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revert unrelated change

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

} // extern "C"

// ---------------------- Windows-specific interceptors ---------------- {{{
Expand Down Expand Up @@ -279,6 +280,9 @@ uptr FindDynamicShadowStart() {
GetMmapGranularity());
}

// Not used
void TryReExecWithoutASLR() {}

void AsanCheckDynamicRTPrereqs() {}

void AsanCheckIncompatibleRT() {}
Expand Down