Skip to content
Open
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
1 change: 1 addition & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ See docs/process.md for more on how version tagging works.

4.0.23 (in development)
-----------------------
- compiler-rt was updated to LLVM 21.1.8. (#26405)
- The inconsistency of incrementing / decrementing refcounts between Wasm EH and
Emscripten EH has been fixed. See `test_EXPORT_EXCEPTION_HANDLING_HELPERS` in
`test_core.py` to see the usage. (#25988)
Expand Down
2 changes: 1 addition & 1 deletion system/lib/compiler-rt/lib/asan/asan_activation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ static struct AsanDeactivatedFlags {
cf.verbosity = Verbosity();
cf.help = false; // this is activation-specific help

// Check if activation flags need to be overriden.
// Check if activation flags need to be overridden.
if (const char *env = GetEnv("ASAN_ACTIVATION_OPTIONS")) {
parser.ParseString(env);
}
Expand Down
12 changes: 11 additions & 1 deletion system/lib/compiler-rt/lib/asan/asan_allocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -424,10 +424,15 @@ struct Allocator {
PoisonShadow(chunk, allocated_size, kAsanHeapLeftRedzoneMagic);
}

void ReInitialize(const AllocatorOptions &options) {
// Apply provided AllocatorOptions to an Allocator
void ApplyOptions(const AllocatorOptions &options) {
SetAllocatorMayReturnNull(options.may_return_null);
allocator.SetReleaseToOSIntervalMs(options.release_to_os_interval_ms);
SharedInitCode(options);
}

void ReInitialize(const AllocatorOptions &options) {
ApplyOptions(options);

// Poison all existing allocation's redzones.
if (CanPoisonMemory()) {
Expand Down Expand Up @@ -977,6 +982,11 @@ void ReInitializeAllocator(const AllocatorOptions &options) {
instance.ReInitialize(options);
}

// Apply provided AllocatorOptions to an Allocator
void ApplyAllocatorOptions(const AllocatorOptions &options) {
instance.ApplyOptions(options);
}

void GetAllocatorOptions(AllocatorOptions *options) {
instance.GetOptions(options);
}
Expand Down
3 changes: 2 additions & 1 deletion system/lib/compiler-rt/lib/asan/asan_allocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ struct AllocatorOptions {
void InitializeAllocator(const AllocatorOptions &options);
void ReInitializeAllocator(const AllocatorOptions &options);
void GetAllocatorOptions(AllocatorOptions *options);
void ApplyAllocatorOptions(const AllocatorOptions &options);

class AsanChunkView {
public:
Expand Down Expand Up @@ -238,7 +239,7 @@ using PrimaryAllocator = PrimaryAllocatorASVT<LocalAddressSpaceView>;
typedef CompactSizeClassMap SizeClassMap;
template <typename AddressSpaceViewTy>
struct AP32 {
static const uptr kSpaceBeg = 0;
static const uptr kSpaceBeg = SANITIZER_MMAP_BEGIN;
static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE;
static const uptr kMetadataSize = 0;
typedef __asan::SizeClassMap SizeClassMap;
Expand Down
22 changes: 14 additions & 8 deletions system/lib/compiler-rt/lib/asan/asan_descriptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,10 +211,10 @@ bool GetStackAddressInformation(uptr addr, uptr access_size,
descr->frame_pc = access.frame_pc;
descr->frame_descr = access.frame_descr;

#if SANITIZER_PPC64V1
// On PowerPC64 ELFv1, the address of a function actually points to a
// three-doubleword data structure with the first field containing
// the address of the function's code.
#if SANITIZER_PPC64V1 || SANITIZER_AIX
// On PowerPC64 ELFv1 or AIX, the address of a function actually points to a
// three-doubleword (or three-word for 32-bit AIX) data structure with
// the first field containing the address of the function's code.
descr->frame_pc = *reinterpret_cast<uptr *>(descr->frame_pc);
#endif
descr->frame_pc += 16;
Expand Down Expand Up @@ -444,6 +444,16 @@ AddressDescription::AddressDescription(uptr addr, uptr access_size,
data.kind = kAddressKindShadow;
return;
}

// Check global first. On AIX, some global data defined in shared libraries
// are put to the STACK region for unknown reasons. Check global first can
// workaround this issue.
// TODO: Look into whether there's a different solution to this problem.
if (GetGlobalAddressInformation(addr, access_size, &data.global)) {
data.kind = kAddressKindGlobal;
return;
}

if (GetHeapAddressInformation(addr, access_size, &data.heap)) {
data.kind = kAddressKindHeap;
return;
Expand All @@ -461,10 +471,6 @@ AddressDescription::AddressDescription(uptr addr, uptr access_size,
return;
}

if (GetGlobalAddressInformation(addr, access_size, &data.global)) {
data.kind = kAddressKindGlobal;
return;
}
data.kind = kAddressKindWild;
data.wild.addr = addr;
data.wild.access_size = access_size;
Expand Down
43 changes: 43 additions & 0 deletions system/lib/compiler-rt/lib/asan/asan_errors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
//===----------------------------------------------------------------------===//

#include "asan_errors.h"

#include "asan_descriptions.h"
#include "asan_mapping.h"
#include "asan_poisoning.h"
#include "asan_report.h"
#include "asan_stack.h"
#include "sanitizer_common/sanitizer_stackdepot.h"
Expand Down Expand Up @@ -611,6 +613,44 @@ static void PrintShadowMemoryForAddress(uptr addr) {
Printf("%s", str.data());
}

static void CheckPoisonRecords(uptr addr) {
if (!AddrIsInMem(addr))
return;

u8 *shadow_addr = (u8 *)MemToShadow(addr);
// If we are in the partial right redzone, look at the next shadow byte.
if (*shadow_addr > 0 && *shadow_addr < 128)
shadow_addr++;
u8 shadow_val = *shadow_addr;

if (shadow_val != kAsanUserPoisonedMemoryMagic)
return;

Printf("\n");

if (flags()->poison_history_size <= 0) {
Printf(
"NOTE: the stack trace above identifies the code that *accessed* "
"the poisoned memory.\n");
Printf(
"To identify the code that *poisoned* the memory, try the "
"experimental setting ASAN_OPTIONS=poison_history_size=<size>.\n");
return;
}

PoisonRecord record;
if (FindPoisonRecord(addr, record)) {
StackTrace poison_stack = StackDepotGet(record.stack_id);
if (poison_stack.size > 0) {
Printf("Memory was manually poisoned by thread T%u:\n", record.thread_id);
poison_stack.Print();
}
} else {
Printf("ERROR: no matching poison tracking record found.\n");
Printf("Try a larger value for ASAN_OPTIONS=poison_history_size=<size>.\n");
}
}

void ErrorGeneric::Print() {
Decorator d;
Printf("%s", d.Error());
Expand All @@ -634,6 +674,9 @@ void ErrorGeneric::Print() {
PrintContainerOverflowHint();
ReportErrorSummary(bug_descr, &stack);
PrintShadowMemoryForAddress(addr);

// This is an experimental flag, hence we don't make a special handler.
CheckPoisonRecords(addr);
}

} // namespace __asan
6 changes: 6 additions & 0 deletions system/lib/compiler-rt/lib/asan/asan_fake_stack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ static const u64 kAllocaRedzoneMask = 31UL;

// For small size classes inline PoisonShadow for better performance.
ALWAYS_INLINE void SetShadow(uptr ptr, uptr size, uptr class_id, u64 magic) {
CHECK(AddrIsAlignedByGranularity(ptr + size));
u64 *shadow = reinterpret_cast<u64*>(MemToShadow(ptr));
if (ASAN_SHADOW_SCALE == 3 && class_id <= 6) {
// This code expects ASAN_SHADOW_SCALE=3.
Expand All @@ -39,6 +40,11 @@ ALWAYS_INLINE void SetShadow(uptr ptr, uptr size, uptr class_id, u64 magic) {
// The size class is too big, it's cheaper to poison only size bytes.
PoisonShadow(ptr, size, static_cast<u8>(magic));
}

if (magic == 0) {
uptr redzone_size = FakeStack::BytesInSizeClass(class_id) - size;
PoisonShadow(ptr + size, redzone_size, kAsanStackRightRedzoneMagic);
}
}

FakeStack *FakeStack::Create(uptr stack_size_log) {
Expand Down
32 changes: 13 additions & 19 deletions system/lib/compiler-rt/lib/asan/asan_flags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ static void InitializeDefaultFlags() {
DisplayHelpMessages(&asan_parser);
}

// Validate flags and report incompatible configurations
static void ProcessFlags() {
Flags *f = flags();

Expand Down Expand Up @@ -250,11 +251,12 @@ void InitializeFlags() {
ProcessFlags();

#if SANITIZER_WINDOWS
// On Windows, weak symbols are emulated by having the user program
// register which weak functions are defined.
// The ASAN DLL will initialize flags prior to user module initialization,
// so __asan_default_options will not point to the user definition yet.
// We still want to ensure we capture when options are passed via
// On Windows, weak symbols (such as the `__asan_default_options` function)
// are emulated by having the user program register which weak functions are
// defined. The ASAN DLL will initialize flags prior to user module
// initialization, so __asan_default_options will not point to the user
// definition yet. We still want to ensure we capture when options are passed
// via
// __asan_default_options, so we add a callback to be run
// when it is registered with the runtime.

Expand All @@ -265,21 +267,13 @@ void InitializeFlags() {
// __sanitizer_register_weak_function.
AddRegisterWeakFunctionCallback(
reinterpret_cast<uptr>(__asan_default_options), []() {
FlagParser asan_parser;

RegisterAsanFlags(&asan_parser, flags());
RegisterCommonFlags(&asan_parser);
asan_parser.ParseString(__asan_default_options());

DisplayHelpMessages(&asan_parser);
// We call `InitializeDefaultFlags` again, instead of just parsing
// `__asan_default_options` directly, to ensure that flags set through
// `ASAN_OPTS` take precedence over those set through
// `__asan_default_options`.
InitializeDefaultFlags();
ProcessFlags();

// TODO: Update other globals and data structures that may need to change
// after initialization due to new flags potentially being set changing after
// `__asan_default_options` is registered.
// See GH issue 'https://github.com/llvm/llvm-project/issues/117925' for
// details.
SetAllocatorMayReturnNull(common_flags()->allocator_may_return_null);
ApplyFlags();
});

# if CAN_SANITIZE_UB
Expand Down
8 changes: 4 additions & 4 deletions system/lib/compiler-rt/lib/asan/asan_flags.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@

// ASan flag values can be defined in four ways:
// 1) initialized with default values at startup.
// 2) overriden during compilation of ASan runtime by providing
// 2) overridden during compilation of ASan runtime by providing
// compile definition ASAN_DEFAULT_OPTIONS.
// 3) overriden from string returned by user-specified function
// 3) overridden from string returned by user-specified function
// __asan_default_options().
// 4) overriden from env variable ASAN_OPTIONS.
// 5) overriden during ASan activation (for now used on Android only).
// 4) overridden from env variable ASAN_OPTIONS.
// 5) overridden during ASan activation (for now used on Android only).

namespace __asan {

Expand Down
3 changes: 3 additions & 0 deletions system/lib/compiler-rt/lib/asan/asan_flags.inc
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ ASAN_FLAG(bool, poison_partial, true,
"stack buffers.")
ASAN_FLAG(bool, poison_array_cookie, true,
"Poison (or not) the array cookie after operator new[].")
ASAN_FLAG(int, poison_history_size, 0,
"[EXPERIMENTAL] Number of most recent memory poisoning calls for "
"which the stack traces will be recorded.")

// Turn off alloc/dealloc mismatch checker on Mac and Windows for now.
// https://github.com/google/sanitizers/issues/131
Expand Down
5 changes: 5 additions & 0 deletions system/lib/compiler-rt/lib/asan/asan_fuchsia.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@
# include "asan_thread.h"
# include "lsan/lsan_common.h"

namespace __sanitizer {
// ASan doesn't need to do anything else special in the startup hook.
void EarlySanitizerInit() {}
} // namespace __sanitizer

namespace __asan {

// The system already set up the shadow memory for us.
Expand Down
2 changes: 1 addition & 1 deletion system/lib/compiler-rt/lib/asan/asan_interceptors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -826,7 +826,7 @@ void InitializeAsanInterceptors() {
ASAN_INTERCEPT_FUNC(__isoc23_strtoll);
# endif

// Intecept jump-related functions.
// Intercept jump-related functions.
ASAN_INTERCEPT_FUNC(longjmp);

# if ASAN_INTERCEPT_SWAPCONTEXT
Expand Down
2 changes: 2 additions & 0 deletions system/lib/compiler-rt/lib/asan/asan_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ using __sanitizer::StackTrace;

void AsanInitFromRtl();
bool TryAsanInitFromRtl();
void ApplyFlags();

// asan_win.cpp
void InitializePlatformExceptionHandlers();
Expand All @@ -82,6 +83,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
Loading