Skip to content
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
11 changes: 11 additions & 0 deletions compiler-rt/lib/asan/asan_errors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,17 @@ ErrorGeneric::ErrorGeneric(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr addr,
scariness.Scare(bug_type_score + read_after_free_bonus, bug_descr);
if (far_from_bounds) scariness.Scare(10, "far-from-bounds");
}
#if SANITIZER_EMSCRIPTEN
// If address is in the first page (64 KB), then it is likely that the
// access is a result of a null pointer dereference.
else if (addr < 65536) {
bug_descr = "null-pointer-dereference";
scariness.Scare(25, bug_descr);
} else if (AddrIsInShadow(addr)) {
bug_descr = "shadow-access";
scariness.Scare(25, bug_descr);
}
#endif
}
}

Expand Down
4 changes: 2 additions & 2 deletions compiler-rt/lib/asan/asan_fake_stack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,11 @@ FakeStack* FakeStack::Create(uptr stack_size_log) {
VReport(1,
"T%d: FakeStack created: %p -- %p stack_size_log: %zd; "
"mmapped %zdK, noreserve=%d, true_start: %p, start of first frame: "
"0x%zx\n",
"%p\n",
GetCurrentTidOrInvalid(), (void*)p,
(void*)(p + FakeStack::RequiredSize(stack_size_log)), stack_size_log,
size >> 10, flags()->uar_noreserve, res->true_start,
res->GetFrame(stack_size_log, /*class_id*/ 0, /*pos*/ 0));
(void*)res->GetFrame(stack_size_log, /*class_id*/ 0, /*pos*/ 0));
return res;
}

Expand Down
33 changes: 33 additions & 0 deletions compiler-rt/lib/asan/asan_flags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@
#include "ubsan/ubsan_flags.h"
#include "ubsan/ubsan_platform.h"

#if SANITIZER_EMSCRIPTEN
#include <emscripten/heap.h>
#include "emscripten_internal.h"
#endif


namespace __asan {

Flags asan_flags_dont_use_directly; // use via flags().
Expand Down Expand Up @@ -70,7 +76,11 @@ static void InitializeDefaultFlags() {
CommonFlags cf;
cf.CopyFrom(*common_flags());
cf.detect_leaks = cf.detect_leaks && CAN_SANITIZE_LEAKS;
#if !SANITIZER_EMSCRIPTEN
// getenv on emscripten uses malloc, which we can't when using LSan.
// You can't run external symbolizer executables anyway.
cf.external_symbolizer_path = GetEnv("ASAN_SYMBOLIZER_PATH");
#endif
cf.malloc_context_size = kDefaultMallocContextSize;
cf.intercept_tls_get_addr = true;
cf.exitcode = 1;
Expand Down Expand Up @@ -129,6 +139,23 @@ static void InitializeDefaultFlags() {
lsan_parser.ParseString(lsan_default_options);
#endif

#if SANITIZER_EMSCRIPTEN
char *options;
// Override from Emscripten Module.
// TODO: add EM_ASM_I64 and avoid using a double for a 64-bit pointer.
#define MAKE_OPTION_LOAD(parser, name) \
options = _emscripten_sanitizer_get_option(name); \
parser.ParseString(options); \
free(options);

MAKE_OPTION_LOAD(asan_parser, "ASAN_OPTIONS");
#if CAN_SANITIZE_LEAKS
MAKE_OPTION_LOAD(lsan_parser, "LSAN_OPTIONS");
#endif
#if CAN_SANITIZE_UB
MAKE_OPTION_LOAD(ubsan_parser, "UBSAN_OPTIONS");
#endif
#else
// Override from command line.
asan_parser.ParseStringFromEnv("ASAN_OPTIONS");
#if CAN_SANITIZE_LEAKS
Expand All @@ -137,9 +164,15 @@ static void InitializeDefaultFlags() {
#if CAN_SANITIZE_UB
ubsan_parser.ParseStringFromEnv("UBSAN_OPTIONS");
#endif
#endif // SANITIZER_EMSCRIPTEN

InitializeCommonFlags();

#if SANITIZER_EMSCRIPTEN
if (common_flags()->malloc_context_size <= 1)
StackTrace::snapshot_stack = false;
#endif // SANITIZER_EMSCRIPTEN
//
// TODO(samsonov): print all of the flags (ASan, LSan, common).
DisplayHelpMessages(&asan_parser);
}
Expand Down
2 changes: 2 additions & 0 deletions compiler-rt/lib/asan/asan_globals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,7 @@ void PrintGlobalLocation(InternalScopedString *str, const __asan_global &g,
// ---------------------- Interface ---------------- {{{1
using namespace __asan;

#if !SANITIZER_EMSCRIPTEN
// Apply __asan_register_globals to all globals found in the same loaded
// executable or shared library as `flag'. The flag tracks whether globals have
// already been registered or not for this image.
Expand Down Expand Up @@ -424,6 +425,7 @@ void __asan_unregister_elf_globals(uptr *flag, void *start, void *stop) {
__asan_unregister_globals(globals_start, globals_stop - globals_start);
*flag = 0;
}
#endif

// Register an array of globals.
void __asan_register_globals(__asan_global *globals, uptr n) {
Expand Down
6 changes: 3 additions & 3 deletions compiler-rt/lib/asan/asan_interceptors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@
#include "sanitizer_common/sanitizer_internal_defs.h"
#include "sanitizer_common/sanitizer_libc.h"

// There is no general interception at all on Fuchsia.
// There is no general interception at all on Fuchsia or Emscripten.
// Only the functions in asan_interceptors_memintrinsics.cpp are
// really defined to replace libc functions.
#if !SANITIZER_FUCHSIA
#if !SANITIZER_FUCHSIA && !SANITIZER_EMSCRIPTEN

# if SANITIZER_POSIX
# include "sanitizer_common/sanitizer_posix.h"
Expand Down Expand Up @@ -960,4 +960,4 @@ void InitializeAsanInterceptors() {

} // namespace __asan

#endif // !SANITIZER_FUCHSIA
#endif // !SANITIZER_FUCHSIA && !SANITIZER_EMSCRIPTEN
6 changes: 3 additions & 3 deletions compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ void *__asan_memmove(void *to, const void *from, uptr size) {
ASAN_MEMMOVE_IMPL(nullptr, to, from, size);
}

#if SANITIZER_FUCHSIA
#if SANITIZER_FUCHSIA || SANITIZER_EMSCRIPTEN

// Fuchsia doesn't use sanitizer_common_interceptors.inc, but
// the only things there it wants are these three. Just define them
Expand All @@ -83,7 +83,7 @@ extern "C" decltype(__asan_memcpy) memcpy[[gnu::alias("__asan_memcpy")]];
extern "C" decltype(__asan_memmove) memmove[[gnu::alias("__asan_memmove")]];
extern "C" decltype(__asan_memset) memset[[gnu::alias("__asan_memset")]];

#else // SANITIZER_FUCHSIA
#else // SANITIZER_FUCHSIA || SANITIZER_EMSCRIPTEN

#define COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size) \
do { \
Expand All @@ -105,4 +105,4 @@ extern "C" decltype(__asan_memset) memset[[gnu::alias("__asan_memset")]];

#include "sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc"

#endif // SANITIZER_FUCHSIA
#endif // SANITIZER_FUCHSIA || SANITIZER_EMSCRIPTEN
6 changes: 4 additions & 2 deletions compiler-rt/lib/asan/asan_malloc_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@

#include "sanitizer_common/sanitizer_platform.h"
#if SANITIZER_FREEBSD || SANITIZER_FUCHSIA || SANITIZER_LINUX || \
SANITIZER_NETBSD || SANITIZER_SOLARIS || SANITIZER_HAIKU || SANITIZER_AIX
SANITIZER_NETBSD || SANITIZER_SOLARIS || SANITIZER_HAIKU || \
SANITIZER_AIX || SANITIZER_EMSCRIPTEN

# include "asan_allocator.h"
# include "asan_interceptors.h"
Expand Down Expand Up @@ -217,4 +218,5 @@ void ReplaceSystemMalloc() {
#endif // SANITIZER_ANDROID

#endif // SANITIZER_FREEBSD || SANITIZER_FUCHSIA || SANITIZER_LINUX ||
// SANITIZER_NETBSD || SANITIZER_SOLARIS || SANITIZER_HAIKU
// SANITIZER_NETBSD || SANITIZER_SOLARIS || SANITIZER_HAIKU ||
// SANITIZER_EMSCRIPTEN
2 changes: 2 additions & 0 deletions compiler-rt/lib/asan/asan_mapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,8 @@ extern uptr kHighMemEnd, kMidMemBeg, kMidMemEnd; // Initialized in __asan_init.

# if defined(__sparc__) && SANITIZER_WORDSIZE == 64
# include "asan_mapping_sparc64.h"
# elif SANITIZER_EMSCRIPTEN
# include "asan_mapping_emscripten.h"
# else
# define MEM_TO_SHADOW(mem) \
((STRIP_MTE_TAG(mem) >> ASAN_SHADOW_SCALE) + (ASAN_SHADOW_OFFSET))
Expand Down
9 changes: 9 additions & 0 deletions compiler-rt/lib/asan/asan_poisoning.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,15 @@ uptr __asan_region_is_poisoned(uptr beg, uptr size) {
if (!size)
return 0;
uptr end = beg + size;
#if SANITIZER_EMSCRIPTEN
// XXX Emscripten hack XXX
// Null pointer handling, since Emscripten does not crash on null pointer,
// ASan must catch null pointer dereference by itself.
// Unfortunately, this function returns 0 to mean the region is not
// poisoned, so we must return 1 instead if we receive a region
// starting at 0.
if (!beg) return 1;
#endif
if (!AddrIsInMem(beg))
return beg;
if (!AddrIsInMem(end))
Expand Down
4 changes: 4 additions & 0 deletions compiler-rt/lib/asan/asan_poisoning.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ ALWAYS_INLINE void FastPoisonShadow(uptr aligned_beg, uptr aligned_size,
// probably provide higher-level interface for these operations.
// For now, just memset on Windows.
if (value || SANITIZER_WINDOWS == 1 ||
// Emscripten doesn't have a nice way to zero whole pages.
// The bulk memory proposal will allow memset to be optimized, but
// even then, we still must use memset.
SANITIZER_EMSCRIPTEN == 1 ||
shadow_end - shadow_beg < common_flags()->clear_shadow_mmap_threshold) {
REAL(memset)((void*)shadow_beg, value, shadow_end - shadow_beg);
} else {
Expand Down
4 changes: 4 additions & 0 deletions compiler-rt/lib/asan/asan_posix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ void AsanOnDeadlySignal(int signo, void *siginfo, void *context) {
}

bool PlatformUnpoisonStacks() {
#if SANITIZER_EMSCRIPTEN
return false;
#else
stack_t signal_stack;
CHECK_EQ(0, sigaltstack(nullptr, &signal_stack));
uptr sigalt_bottom = (uptr)signal_stack.ss_sp;
Expand All @@ -64,6 +67,7 @@ bool PlatformUnpoisonStacks() {
&tls_end);
UnpoisonStack(stack_begin, stack_end, "default");
return true;
#endif
}

// ---------------------- TSD ---------------- {{{1
Expand Down
8 changes: 8 additions & 0 deletions compiler-rt/lib/asan/asan_rtl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ static void AsanDie() {

WaitForDebugger(flags()->sleep_before_dying, "before dying");

#if !SANITIZER_EMSCRIPTEN
if (flags()->unmap_shadow_on_exit) {
if (kMidMemBeg) {
UnmapOrDie((void*)kLowShadowBeg, kMidMemBeg - kLowShadowBeg);
Expand All @@ -63,6 +64,7 @@ static void AsanDie() {
UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg);
}
}
#endif
}

static void CheckUnwind() {
Expand Down Expand Up @@ -324,13 +326,15 @@ static void asan_atexit() {
}

static void InitializeHighMemEnd() {
#if !SANITIZER_EMSCRIPTEN
#if !ASAN_FIXED_MAPPING
kHighMemEnd = GetMaxUserVirtualAddress();
// Increase kHighMemEnd to make sure it's properly
// aligned together with kHighMemBeg:
kHighMemEnd |= (GetMmapGranularity() << ASAN_SHADOW_SCALE) - 1;
#endif // !ASAN_FIXED_MAPPING
CHECK_EQ((kHighMemBeg % GetMmapGranularity()), 0);
#endif // !SANITIZER_EMSCRIPTEN
}

void PrintAddressSpaceLayout() {
Expand Down Expand Up @@ -476,6 +480,7 @@ static bool AsanInitInternal() {

ReplaceSystemMalloc();

#if !SANITIZER_EMSCRIPTEN
DisableCoreDumperIfNecessary();

#if SANITIZER_POSIX
Expand All @@ -489,11 +494,14 @@ static bool AsanInitInternal() {
// issues.
}
#endif // SANITIZER_POSIX
#endif // !SANITIZER_EMSCRIPTEN

InitializeShadowMemory();

AsanTSDInit(PlatformTSDDtor);
#if !SANITIZER_EMSCRIPTEN
InstallDeadlySignalHandlers(AsanOnDeadlySignal);
#endif

AllocatorOptions allocator_options;
allocator_options.SetFrom(flags(), common_flags());
Expand Down
5 changes: 3 additions & 2 deletions compiler-rt/lib/asan/asan_shadow_setup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@

#include "sanitizer_common/sanitizer_platform.h"

// asan_fuchsia.cpp has their own InitializeShadowMemory implementation.
#if !SANITIZER_FUCHSIA
// asan_fuchsia.cpp and asan_emscripten.cc have have their own
// InitializeShadowMemory implementation.
#if !SANITIZER_FUCHSIA && !SANITIZER_EMSCRIPTEN

# include "asan_internal.h"
# include "asan_mapping.h"
Expand Down
10 changes: 10 additions & 0 deletions compiler-rt/lib/asan/asan_thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,10 @@ void AsanThread::Destroy() {
if (AsanThread *thread = GetCurrentThread())
CHECK_EQ(this, thread);
malloc_storage().CommitBack();
#if !SANITIZER_EMSCRIPTEN
if (common_flags()->use_sigaltstack)
UnsetAlternateSignalStack();
#endif
FlushToDeadThreadStats(&stats_);
// We also clear the shadow on thread destruction because
// some code may still be executing in later TSD destructors
Expand Down Expand Up @@ -287,8 +289,10 @@ void AsanThread::ThreadStart(ThreadID os_id) {
Init();
asanThreadRegistry().StartThread(tid(), os_id, ThreadType::Regular, nullptr);

#if !SANITIZER_EMSCRIPTEN
if (common_flags()->use_sigaltstack)
SetAlternateSignalStack();
#endif
}

AsanThread *CreateMainThread() {
Expand Down Expand Up @@ -578,6 +582,12 @@ void PrintThreads() {

} // namespace __lsan

namespace __sanitizer {
ThreadRegistry *GetThreadRegistryLocked() {
return __lsan::GetAsanThreadRegistryLocked();
}
} // namespace __sanitizer

// ---------------------- Interface ---------------- {{{1
using namespace __asan;

Expand Down
8 changes: 4 additions & 4 deletions compiler-rt/lib/builtins/atomic.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ bool __atomic_is_lock_free_c(size_t size, void *ptr) {

/// An atomic load operation. This is atomic with respect to the source
/// pointer only.
void __atomic_load_c(int size, void *src, void *dest, int model) {
void __atomic_load_c(size_t size, void *src, void *dest, int model) {
#define LOCK_FREE_ACTION(type) \
*((type *)dest) = __c11_atomic_load((_Atomic(type) *)src, model); \
return;
Expand All @@ -199,7 +199,7 @@ void __atomic_load_c(int size, void *src, void *dest, int model) {

/// An atomic store operation. This is atomic with respect to the destination
/// pointer only.
void __atomic_store_c(int size, void *dest, void *src, int model) {
void __atomic_store_c(size_t size, void *dest, void *src, int model) {
#define LOCK_FREE_ACTION(type) \
__c11_atomic_store((_Atomic(type) *)dest, *(type *)src, model); \
return;
Expand All @@ -216,7 +216,7 @@ void __atomic_store_c(int size, void *dest, void *src, int model) {
/// they are not, then this stores the current value from *ptr in *expected.
///
/// This function returns 1 if the exchange takes place or 0 if it fails.
int __atomic_compare_exchange_c(int size, void *ptr, void *expected,
int __atomic_compare_exchange_c(size_t size, void *ptr, void *expected,
void *desired, int success, int failure) {
#define LOCK_FREE_ACTION(type) \
return __c11_atomic_compare_exchange_strong( \
Expand All @@ -238,7 +238,7 @@ int __atomic_compare_exchange_c(int size, void *ptr, void *expected,

/// Performs an atomic exchange operation between two pointers. This is atomic
/// with respect to the target address.
void __atomic_exchange_c(int size, void *ptr, void *val, void *old, int model) {
void __atomic_exchange_c(size_t size, void *ptr, void *val, void *old, int model) {
#define LOCK_FREE_ACTION(type) \
*(type *)old = \
__c11_atomic_exchange((_Atomic(type) *)ptr, *(type *)val, model); \
Expand Down
2 changes: 1 addition & 1 deletion compiler-rt/lib/builtins/fp_compare_impl.inc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// functions. We need to ensure that the return value is sign-extended in the
// same way as GCC expects (since otherwise GCC-generated __builtin_isinf
// returns true for finite 128-bit floating-point numbers).
#if defined(__aarch64__) || defined(__arm64ec__)
#if defined(__aarch64__) || defined(__arm64ec__) || defined(__wasm__)
// AArch64 GCC overrides libgcc_cmp_return to use int instead of long.
typedef int CMP_RESULT;
#elif __SIZEOF_POINTER__ == 8 && __SIZEOF_LONG__ == 4
Expand Down
Loading
Loading