Vendor import of compiler-rt trunk r303571:
https://llvm.org/svn/llvm-project/compiler-rt/trunk@303571
This commit is contained in:
parent
834763c1a4
commit
99ea5e489f
@ -69,6 +69,10 @@ extern int __xray_remove_handler_arg1();
|
||||
/// Provide a function to invoke when XRay encounters a custom event.
|
||||
extern int __xray_set_customevent_handler(void (*entry)(void*, std::size_t));
|
||||
|
||||
/// This removes whatever the currently provided custom event handler is.
|
||||
/// Returns 1 on success, 0 on error.
|
||||
extern int __xray_remove_customevent_handler();
|
||||
|
||||
enum XRayPatchingStatus {
|
||||
NOT_INITIALIZED = 0,
|
||||
SUCCESS = 1,
|
||||
|
@ -194,10 +194,6 @@ void InitializeFlags() {
|
||||
Report("WARNING: strchr* interceptors are enabled even though "
|
||||
"replace_str=0. Use intercept_strchr=0 to disable them.");
|
||||
}
|
||||
if (!f->replace_str && common_flags()->intercept_strndup) {
|
||||
Report("WARNING: strndup* interceptors are enabled even though "
|
||||
"replace_str=0. Use intercept_strndup=0 to disable them.");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace __asan
|
||||
|
@ -154,27 +154,6 @@ TEST(AddressSanitizer, MAYBE_StrDupOOBTest) {
|
||||
free(str);
|
||||
}
|
||||
|
||||
#if SANITIZER_TEST_HAS_STRNDUP
|
||||
TEST(AddressSanitizer, MAYBE_StrNDupOOBTest) {
|
||||
size_t size = Ident(42);
|
||||
char *str = MallocAndMemsetString(size);
|
||||
char *new_str;
|
||||
// Normal strndup calls.
|
||||
str[size - 1] = '\0';
|
||||
new_str = strndup(str, size - 13);
|
||||
free(new_str);
|
||||
new_str = strndup(str + size - 1, 13);
|
||||
free(new_str);
|
||||
// Argument points to not allocated memory.
|
||||
EXPECT_DEATH(Ident(strndup(str - 1, 13)), LeftOOBReadMessage(1));
|
||||
EXPECT_DEATH(Ident(strndup(str + size, 13)), RightOOBReadMessage(0));
|
||||
// Overwrite the terminating '\0' and hit unallocated memory.
|
||||
str[size - 1] = 'z';
|
||||
EXPECT_DEATH(Ident(strndup(str, size + 13)), RightOOBReadMessage(0));
|
||||
free(str);
|
||||
}
|
||||
#endif // SANITIZER_TEST_HAS_STRNDUP
|
||||
|
||||
TEST(AddressSanitizer, StrCpyOOBTest) {
|
||||
size_t to_size = Ident(30);
|
||||
size_t from_size = Ident(6); // less than to_size
|
||||
|
@ -110,7 +110,8 @@ void ProcessGlobalRegions(Frontier *frontier) {
|
||||
|
||||
for (const __sanitizer::LoadedModule::AddressRange &range :
|
||||
modules[i].ranges()) {
|
||||
if (range.executable || !range.readable) continue;
|
||||
// Sections storing global variables are writable and non-executable
|
||||
if (range.executable || !range.writable) continue;
|
||||
|
||||
ScanGlobalRange(range.beg, range.end, frontier);
|
||||
}
|
||||
|
@ -341,6 +341,33 @@ INTERCEPTOR(char *, __strdup, char *src) {
|
||||
#define MSAN_MAYBE_INTERCEPT___STRDUP
|
||||
#endif
|
||||
|
||||
INTERCEPTOR(char *, strndup, char *src, SIZE_T n) {
|
||||
ENSURE_MSAN_INITED();
|
||||
GET_STORE_STACK_TRACE;
|
||||
// On FreeBSD strndup() leverages strnlen().
|
||||
InterceptorScope interceptor_scope;
|
||||
SIZE_T copy_size = REAL(strnlen)(src, n);
|
||||
char *res = REAL(strndup)(src, n);
|
||||
CopyShadowAndOrigin(res, src, copy_size, &stack);
|
||||
__msan_unpoison(res + copy_size, 1); // \0
|
||||
return res;
|
||||
}
|
||||
|
||||
#if !SANITIZER_FREEBSD
|
||||
INTERCEPTOR(char *, __strndup, char *src, SIZE_T n) {
|
||||
ENSURE_MSAN_INITED();
|
||||
GET_STORE_STACK_TRACE;
|
||||
SIZE_T copy_size = REAL(strnlen)(src, n);
|
||||
char *res = REAL(__strndup)(src, n);
|
||||
CopyShadowAndOrigin(res, src, copy_size, &stack);
|
||||
__msan_unpoison(res + copy_size, 1); // \0
|
||||
return res;
|
||||
}
|
||||
#define MSAN_MAYBE_INTERCEPT___STRNDUP INTERCEPT_FUNCTION(__strndup)
|
||||
#else
|
||||
#define MSAN_MAYBE_INTERCEPT___STRNDUP
|
||||
#endif
|
||||
|
||||
INTERCEPTOR(char *, gcvt, double number, SIZE_T ndigit, char *buf) {
|
||||
ENSURE_MSAN_INITED();
|
||||
char *res = REAL(gcvt)(number, ndigit, buf);
|
||||
@ -1344,13 +1371,6 @@ int OnExit() {
|
||||
return __msan_memcpy(to, from, size); \
|
||||
}
|
||||
|
||||
#define COMMON_INTERCEPTOR_COPY_STRING(ctx, to, from, size) \
|
||||
do { \
|
||||
GET_STORE_STACK_TRACE; \
|
||||
CopyShadowAndOrigin(to, from, size, &stack); \
|
||||
__msan_unpoison(to + size, 1); \
|
||||
} while (false)
|
||||
|
||||
#include "sanitizer_common/sanitizer_platform_interceptors.h"
|
||||
#include "sanitizer_common/sanitizer_common_interceptors.inc"
|
||||
|
||||
@ -1518,6 +1538,8 @@ void InitializeInterceptors() {
|
||||
INTERCEPT_FUNCTION(stpcpy); // NOLINT
|
||||
INTERCEPT_FUNCTION(strdup);
|
||||
MSAN_MAYBE_INTERCEPT___STRDUP;
|
||||
INTERCEPT_FUNCTION(strndup);
|
||||
MSAN_MAYBE_INTERCEPT___STRNDUP;
|
||||
INTERCEPT_FUNCTION(strncpy); // NOLINT
|
||||
INTERCEPT_FUNCTION(gcvt);
|
||||
INTERCEPT_FUNCTION(strcat); // NOLINT
|
||||
|
@ -1581,8 +1581,7 @@ TEST(MemorySanitizer, strdup) {
|
||||
TEST(MemorySanitizer, strndup) {
|
||||
char buf[4] = "abc";
|
||||
__msan_poison(buf + 2, sizeof(*buf));
|
||||
char *x;
|
||||
EXPECT_UMR(x = strndup(buf, 3));
|
||||
char *x = strndup(buf, 3);
|
||||
EXPECT_NOT_POISONED(x[0]);
|
||||
EXPECT_NOT_POISONED(x[1]);
|
||||
EXPECT_POISONED(x[2]);
|
||||
@ -1594,8 +1593,7 @@ TEST(MemorySanitizer, strndup_short) {
|
||||
char buf[4] = "abc";
|
||||
__msan_poison(buf + 1, sizeof(*buf));
|
||||
__msan_poison(buf + 2, sizeof(*buf));
|
||||
char *x;
|
||||
EXPECT_UMR(x = strndup(buf, 2));
|
||||
char *x = strndup(buf, 2);
|
||||
EXPECT_NOT_POISONED(x[0]);
|
||||
EXPECT_POISONED(x[1]);
|
||||
EXPECT_NOT_POISONED(x[2]);
|
||||
|
@ -285,9 +285,9 @@ void LoadedModule::clear() {
|
||||
}
|
||||
|
||||
void LoadedModule::addAddressRange(uptr beg, uptr end, bool executable,
|
||||
bool readable) {
|
||||
bool writable) {
|
||||
void *mem = InternalAlloc(sizeof(AddressRange));
|
||||
AddressRange *r = new(mem) AddressRange(beg, end, executable, readable);
|
||||
AddressRange *r = new(mem) AddressRange(beg, end, executable, writable);
|
||||
ranges_.push_back(r);
|
||||
if (executable && end > max_executable_address_)
|
||||
max_executable_address_ = end;
|
||||
|
@ -717,7 +717,7 @@ class LoadedModule {
|
||||
void set(const char *module_name, uptr base_address, ModuleArch arch,
|
||||
u8 uuid[kModuleUUIDSize], bool instrumented);
|
||||
void clear();
|
||||
void addAddressRange(uptr beg, uptr end, bool executable, bool readable);
|
||||
void addAddressRange(uptr beg, uptr end, bool executable, bool writable);
|
||||
bool containsAddress(uptr address) const;
|
||||
|
||||
const char *full_name() const { return full_name_; }
|
||||
@ -732,14 +732,14 @@ class LoadedModule {
|
||||
uptr beg;
|
||||
uptr end;
|
||||
bool executable;
|
||||
bool readable;
|
||||
bool writable;
|
||||
|
||||
AddressRange(uptr beg, uptr end, bool executable, bool readable)
|
||||
AddressRange(uptr beg, uptr end, bool executable, bool writable)
|
||||
: next(nullptr),
|
||||
beg(beg),
|
||||
end(end),
|
||||
executable(executable),
|
||||
readable(readable) {}
|
||||
writable(writable) {}
|
||||
};
|
||||
|
||||
const IntrusiveList<AddressRange> &ranges() const { return ranges_; }
|
||||
|
@ -34,8 +34,6 @@
|
||||
// COMMON_INTERCEPTOR_MEMSET_IMPL
|
||||
// COMMON_INTERCEPTOR_MEMMOVE_IMPL
|
||||
// COMMON_INTERCEPTOR_MEMCPY_IMPL
|
||||
// COMMON_INTERCEPTOR_COPY_STRING
|
||||
// COMMON_INTERCEPTOR_STRNDUP_IMPL
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "interception/interception.h"
|
||||
@ -219,25 +217,6 @@ bool PlatformHasDifferentMemcpyAndMemmove();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef COMMON_INTERCEPTOR_COPY_STRING
|
||||
#define COMMON_INTERCEPTOR_COPY_STRING(ctx, to, from, size) {}
|
||||
#endif
|
||||
|
||||
#ifndef COMMON_INTERCEPTOR_STRNDUP_IMPL
|
||||
#define COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size) \
|
||||
COMMON_INTERCEPTOR_ENTER(ctx, strndup, s, size); \
|
||||
uptr from_length = internal_strnlen(s, size); \
|
||||
uptr copy_length = Min(size, from_length); \
|
||||
char *new_mem = (char *)WRAP(malloc)(copy_length + 1); \
|
||||
if (common_flags()->intercept_strndup) { \
|
||||
COMMON_INTERCEPTOR_READ_RANGE(ctx, s, copy_length + 1); \
|
||||
} \
|
||||
COMMON_INTERCEPTOR_COPY_STRING(ctx, new_mem, s, copy_length); \
|
||||
internal_memcpy(new_mem, s, copy_length); \
|
||||
new_mem[copy_length] = '\0'; \
|
||||
return new_mem;
|
||||
#endif
|
||||
|
||||
struct FileMetadata {
|
||||
// For open_memstream().
|
||||
char **addr;
|
||||
@ -321,26 +300,6 @@ INTERCEPTOR(SIZE_T, strnlen, const char *s, SIZE_T maxlen) {
|
||||
#define INIT_STRNLEN
|
||||
#endif
|
||||
|
||||
#if SANITIZER_INTERCEPT_STRNDUP
|
||||
INTERCEPTOR(char*, strndup, const char *s, uptr size) {
|
||||
void *ctx;
|
||||
COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size);
|
||||
}
|
||||
#define INIT_STRNDUP COMMON_INTERCEPT_FUNCTION(strndup)
|
||||
#else
|
||||
#define INIT_STRNDUP
|
||||
#endif // SANITIZER_INTERCEPT_STRNDUP
|
||||
|
||||
#if SANITIZER_INTERCEPT___STRNDUP
|
||||
INTERCEPTOR(char*, __strndup, const char *s, uptr size) {
|
||||
void *ctx;
|
||||
COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size);
|
||||
}
|
||||
#define INIT___STRNDUP COMMON_INTERCEPT_FUNCTION(__strndup)
|
||||
#else
|
||||
#define INIT___STRNDUP
|
||||
#endif // SANITIZER_INTERCEPT___STRNDUP
|
||||
|
||||
#if SANITIZER_INTERCEPT_TEXTDOMAIN
|
||||
INTERCEPTOR(char*, textdomain, const char *domainname) {
|
||||
void *ctx;
|
||||
@ -6204,8 +6163,6 @@ static void InitializeCommonInterceptors() {
|
||||
INIT_TEXTDOMAIN;
|
||||
INIT_STRLEN;
|
||||
INIT_STRNLEN;
|
||||
INIT_STRNDUP;
|
||||
INIT___STRNDUP;
|
||||
INIT_STRCMP;
|
||||
INIT_STRNCMP;
|
||||
INIT_STRCASECMP;
|
||||
|
@ -34,24 +34,40 @@ class FlagHandler : public FlagHandlerBase {
|
||||
bool Parse(const char *value) final;
|
||||
};
|
||||
|
||||
template <>
|
||||
inline bool FlagHandler<bool>::Parse(const char *value) {
|
||||
inline bool ParseBool(const char *value, bool *b) {
|
||||
if (internal_strcmp(value, "0") == 0 ||
|
||||
internal_strcmp(value, "no") == 0 ||
|
||||
internal_strcmp(value, "false") == 0) {
|
||||
*t_ = false;
|
||||
*b = false;
|
||||
return true;
|
||||
}
|
||||
if (internal_strcmp(value, "1") == 0 ||
|
||||
internal_strcmp(value, "yes") == 0 ||
|
||||
internal_strcmp(value, "true") == 0) {
|
||||
*t_ = true;
|
||||
*b = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool FlagHandler<bool>::Parse(const char *value) {
|
||||
if (ParseBool(value, t_)) return true;
|
||||
Printf("ERROR: Invalid value for bool option: '%s'\n", value);
|
||||
return false;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool FlagHandler<HandleSignalMode>::Parse(const char *value) {
|
||||
bool b;
|
||||
if (ParseBool(value, &b)) {
|
||||
*t_ = b ? kHandleSignalYes : kHandleSignalNo;
|
||||
return true;
|
||||
}
|
||||
Printf("ERROR: Invalid value for signal handler option: '%s'\n", value);
|
||||
return false;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool FlagHandler<const char *>::Parse(const char *value) {
|
||||
*t_ = internal_strdup(value);
|
||||
|
@ -18,6 +18,11 @@
|
||||
|
||||
namespace __sanitizer {
|
||||
|
||||
enum HandleSignalMode {
|
||||
kHandleSignalNo,
|
||||
kHandleSignalYes,
|
||||
};
|
||||
|
||||
struct CommonFlags {
|
||||
#define COMMON_FLAG(Type, Name, DefaultValue, Description) Type Name;
|
||||
#include "sanitizer_flags.inc"
|
||||
|
@ -78,16 +78,20 @@ COMMON_FLAG(int, print_module_map, 0,
|
||||
"OS X only. 0 = don't print, 1 = print only once before process "
|
||||
"exits, 2 = print after each report.")
|
||||
COMMON_FLAG(bool, check_printf, true, "Check printf arguments.")
|
||||
COMMON_FLAG(bool, handle_segv, true,
|
||||
"If set, registers the tool's custom SIGSEGV handler.")
|
||||
COMMON_FLAG(bool, handle_sigbus, true,
|
||||
"If set, registers the tool's custom SIGBUS handler.")
|
||||
COMMON_FLAG(bool, handle_abort, false,
|
||||
"If set, registers the tool's custom SIGABRT handler.")
|
||||
COMMON_FLAG(bool, handle_sigill, false,
|
||||
"If set, registers the tool's custom SIGILL handler.")
|
||||
COMMON_FLAG(bool, handle_sigfpe, true,
|
||||
"If set, registers the tool's custom SIGFPE handler.")
|
||||
#define COMMON_FLAG_HANDLE_SIGNAL_HELP(signal) \
|
||||
"Controls custom tool's " #signal " handler (0 - do not registers the " \
|
||||
"handler, 1 - register the handler). "
|
||||
COMMON_FLAG(HandleSignalMode, handle_segv, kHandleSignalYes,
|
||||
COMMON_FLAG_HANDLE_SIGNAL_HELP(SIGSEGV))
|
||||
COMMON_FLAG(HandleSignalMode, handle_sigbus, kHandleSignalYes,
|
||||
COMMON_FLAG_HANDLE_SIGNAL_HELP(SIGBUS))
|
||||
COMMON_FLAG(HandleSignalMode, handle_abort, kHandleSignalNo,
|
||||
COMMON_FLAG_HANDLE_SIGNAL_HELP(SIGABRT))
|
||||
COMMON_FLAG(HandleSignalMode, handle_sigill, kHandleSignalNo,
|
||||
COMMON_FLAG_HANDLE_SIGNAL_HELP(SIGILL))
|
||||
COMMON_FLAG(HandleSignalMode, handle_sigfpe, kHandleSignalYes,
|
||||
COMMON_FLAG_HANDLE_SIGNAL_HELP(SIGFPE))
|
||||
#undef COMMON_FLAG_HANDLE_SIGNAL_HELP
|
||||
COMMON_FLAG(bool, allow_user_segv_handler, false,
|
||||
"If set, allows user to register a SEGV handler even if the tool "
|
||||
"registers one.")
|
||||
@ -195,9 +199,6 @@ COMMON_FLAG(bool, intercept_strpbrk, true,
|
||||
COMMON_FLAG(bool, intercept_strlen, true,
|
||||
"If set, uses custom wrappers for strlen and strnlen functions "
|
||||
"to find more errors.")
|
||||
COMMON_FLAG(bool, intercept_strndup, true,
|
||||
"If set, uses custom wrappers for strndup functions "
|
||||
"to find more errors.")
|
||||
COMMON_FLAG(bool, intercept_strchr, true,
|
||||
"If set, uses custom wrappers for strchr, strchrnul, and strrchr "
|
||||
"functions to find more errors.")
|
||||
|
@ -1395,15 +1395,19 @@ AndroidApiLevel AndroidGetApiLevel() {
|
||||
#endif
|
||||
|
||||
bool IsHandledDeadlySignal(int signum) {
|
||||
if (common_flags()->handle_abort && signum == SIGABRT)
|
||||
return true;
|
||||
if (common_flags()->handle_sigill && signum == SIGILL)
|
||||
return true;
|
||||
if (common_flags()->handle_sigfpe && signum == SIGFPE)
|
||||
return true;
|
||||
if (common_flags()->handle_segv && signum == SIGSEGV)
|
||||
return true;
|
||||
return common_flags()->handle_sigbus && signum == SIGBUS;
|
||||
switch (signum) {
|
||||
case SIGABRT:
|
||||
return common_flags()->handle_abort;
|
||||
case SIGILL:
|
||||
return common_flags()->handle_sigill;
|
||||
case SIGFPE:
|
||||
return common_flags()->handle_sigfpe;
|
||||
case SIGSEGV:
|
||||
return common_flags()->handle_segv;
|
||||
case SIGBUS:
|
||||
return common_flags()->handle_sigbus;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#if !SANITIZER_GO
|
||||
|
@ -447,9 +447,9 @@ static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) {
|
||||
uptr cur_beg = info->dlpi_addr + phdr->p_vaddr;
|
||||
uptr cur_end = cur_beg + phdr->p_memsz;
|
||||
bool executable = phdr->p_flags & PF_X;
|
||||
bool readable = phdr->p_flags & PF_R;
|
||||
bool writable = phdr->p_flags & PF_W;
|
||||
cur_module.addAddressRange(cur_beg, cur_end, executable,
|
||||
readable);
|
||||
writable);
|
||||
}
|
||||
}
|
||||
data->modules->push_back(cur_module);
|
||||
|
@ -394,18 +394,22 @@ void ListOfModules::init() {
|
||||
}
|
||||
|
||||
bool IsHandledDeadlySignal(int signum) {
|
||||
// Handling fatal signals on watchOS and tvOS devices is disallowed.
|
||||
if ((SANITIZER_WATCHOS || SANITIZER_TVOS) && !(SANITIZER_IOSSIM))
|
||||
// Handling fatal signals on watchOS and tvOS devices is disallowed.
|
||||
return false;
|
||||
if (common_flags()->handle_abort && signum == SIGABRT)
|
||||
return true;
|
||||
if (common_flags()->handle_sigill && signum == SIGILL)
|
||||
return true;
|
||||
if (common_flags()->handle_sigfpe && signum == SIGFPE)
|
||||
return true;
|
||||
if (common_flags()->handle_segv && signum == SIGSEGV)
|
||||
return true;
|
||||
return common_flags()->handle_sigbus && signum == SIGBUS;
|
||||
switch (signum) {
|
||||
case SIGABRT:
|
||||
return common_flags()->handle_abort;
|
||||
case SIGILL:
|
||||
return common_flags()->handle_sigill;
|
||||
case SIGFPE:
|
||||
return common_flags()->handle_sigfpe;
|
||||
case SIGSEGV:
|
||||
return common_flags()->handle_segv;
|
||||
case SIGBUS:
|
||||
return common_flags()->handle_sigbus;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
MacosVersion cached_macos_version = MACOS_VERSION_UNINITIALIZED;
|
||||
|
@ -25,12 +25,6 @@
|
||||
# define SI_NOT_WINDOWS 0
|
||||
#endif
|
||||
|
||||
#if SANITIZER_POSIX
|
||||
# define SI_POSIX 1
|
||||
#else
|
||||
# define SI_POSIX 0
|
||||
#endif
|
||||
|
||||
#if SANITIZER_LINUX && !SANITIZER_ANDROID
|
||||
# define SI_LINUX_NOT_ANDROID 1
|
||||
#else
|
||||
@ -75,12 +69,6 @@
|
||||
# define SI_UNIX_NOT_MAC 0
|
||||
#endif
|
||||
|
||||
#if SANITIZER_LINUX && !SANITIZER_FREEBSD
|
||||
# define SI_LINUX_NOT_FREEBSD 1
|
||||
# else
|
||||
# define SI_LINUX_NOT_FREEBSD 0
|
||||
#endif
|
||||
|
||||
#define SANITIZER_INTERCEPT_STRLEN 1
|
||||
#define SANITIZER_INTERCEPT_STRNLEN SI_NOT_MAC
|
||||
#define SANITIZER_INTERCEPT_STRCMP 1
|
||||
@ -98,8 +86,6 @@
|
||||
#define SANITIZER_INTERCEPT_MEMMOVE 1
|
||||
#define SANITIZER_INTERCEPT_MEMCPY 1
|
||||
#define SANITIZER_INTERCEPT_MEMCMP 1
|
||||
#define SANITIZER_INTERCEPT_STRNDUP SI_POSIX
|
||||
#define SANITIZER_INTERCEPT___STRNDUP SI_LINUX_NOT_FREEBSD
|
||||
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \
|
||||
__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070
|
||||
# define SI_MAC_DEPLOYMENT_BELOW_10_7 1
|
||||
|
@ -142,7 +142,7 @@ void MemoryMappingLayout::DumpListOfModules(
|
||||
LoadedModule cur_module;
|
||||
cur_module.set(cur_name, base_address);
|
||||
cur_module.addAddressRange(cur_beg, cur_end, prot & kProtectionExecute,
|
||||
prot & kProtectionRead);
|
||||
prot & kProtectionWrite);
|
||||
modules->push_back(cur_module);
|
||||
}
|
||||
}
|
||||
|
@ -336,7 +336,7 @@ void MemoryMappingLayout::DumpListOfModules(
|
||||
current_instrumented_);
|
||||
}
|
||||
cur_module->addAddressRange(cur_beg, cur_end, prot & kProtectionExecute,
|
||||
prot & kProtectionRead);
|
||||
prot & kProtectionWrite);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -554,7 +554,7 @@ void ListOfModules::init() {
|
||||
cur_module.set(module_name, adjusted_base);
|
||||
// We add the whole module as one single address range.
|
||||
cur_module.addAddressRange(base_address, end_address, /*executable*/ true,
|
||||
/*readable*/ true);
|
||||
/*writable*/ true);
|
||||
modules_.push_back(cur_module);
|
||||
}
|
||||
UnmapOrDie(hmodules, modules_buffer_size);
|
||||
|
@ -146,6 +146,15 @@ set_target_properties(SanitizerUnitTests PROPERTIES FOLDER "Compiler-RT Tests")
|
||||
# Adds sanitizer tests for architecture.
|
||||
macro(add_sanitizer_tests_for_arch arch)
|
||||
get_target_flags_for_arch(${arch} TARGET_FLAGS)
|
||||
|
||||
# If the sanitizer library was built with _FILE_OFFSET_BITS=64 we need
|
||||
# to ensure that the library and tests agree on the layout of certain
|
||||
# structures such as 'struct stat'.
|
||||
if( CMAKE_SIZEOF_VOID_P EQUAL 4 )
|
||||
list(APPEND TARGET_FLAGS "-D_LARGEFILE_SOURCE")
|
||||
list(APPEND TARGET_FLAGS "-D_FILE_OFFSET_BITS=64")
|
||||
endif()
|
||||
|
||||
set(SANITIZER_TEST_SOURCES ${SANITIZER_UNITTESTS}
|
||||
${COMPILER_RT_GTEST_SOURCE})
|
||||
set(SANITIZER_TEST_COMPILE_DEPS ${SANITIZER_TEST_HEADERS})
|
||||
|
@ -59,6 +59,36 @@ TEST(SanitizerCommon, BooleanFlags) {
|
||||
TestFlag(true, "flag_name=0", false);
|
||||
TestFlag(true, "flag_name=no", false);
|
||||
TestFlag(true, "flag_name=false", false);
|
||||
|
||||
EXPECT_DEATH(TestFlag(false, "flag_name", true), "expected '='");
|
||||
EXPECT_DEATH(TestFlag(false, "flag_name=", true),
|
||||
"Invalid value for bool option: ''");
|
||||
EXPECT_DEATH(TestFlag(false, "flag_name=2", true),
|
||||
"Invalid value for bool option: '2'");
|
||||
EXPECT_DEATH(TestFlag(false, "flag_name=-1", true),
|
||||
"Invalid value for bool option: '-1'");
|
||||
EXPECT_DEATH(TestFlag(false, "flag_name=on", true),
|
||||
"Invalid value for bool option: 'on'");
|
||||
}
|
||||
|
||||
TEST(SanitizerCommon, HandleSignalMode) {
|
||||
TestFlag(kHandleSignalNo, "flag_name=1", kHandleSignalYes);
|
||||
TestFlag(kHandleSignalNo, "flag_name=yes", kHandleSignalYes);
|
||||
TestFlag(kHandleSignalNo, "flag_name=true", kHandleSignalYes);
|
||||
TestFlag(kHandleSignalYes, "flag_name=0", kHandleSignalNo);
|
||||
TestFlag(kHandleSignalYes, "flag_name=no", kHandleSignalNo);
|
||||
TestFlag(kHandleSignalYes, "flag_name=false", kHandleSignalNo);
|
||||
|
||||
EXPECT_DEATH(TestFlag(kHandleSignalNo, "flag_name", kHandleSignalNo),
|
||||
"expected '='");
|
||||
EXPECT_DEATH(TestFlag(kHandleSignalNo, "flag_name=", kHandleSignalNo),
|
||||
"Invalid value for signal handler option: ''");
|
||||
EXPECT_DEATH(TestFlag(kHandleSignalNo, "flag_name=2", kHandleSignalNo),
|
||||
"Invalid value for signal handler option: '2'");
|
||||
EXPECT_DEATH(TestFlag(kHandleSignalNo, "flag_name=-1", kHandleSignalNo),
|
||||
"Invalid value for signal handler option: '-1'");
|
||||
EXPECT_DEATH(TestFlag(kHandleSignalNo, "flag_name=on", kHandleSignalNo),
|
||||
"Invalid value for signal handler option: 'on'");
|
||||
}
|
||||
|
||||
TEST(SanitizerCommon, IntFlags) {
|
||||
|
@ -124,10 +124,4 @@ static inline uint32_t my_rand() {
|
||||
# define SANITIZER_TEST_HAS_PRINTF_L 0
|
||||
#endif
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
# define SANITIZER_TEST_HAS_STRNDUP 1
|
||||
#else
|
||||
# define SANITIZER_TEST_HAS_STRNDUP 0
|
||||
#endif
|
||||
|
||||
#endif // SANITIZER_TEST_UTILS_H
|
||||
|
@ -68,7 +68,7 @@ void initFlags() {
|
||||
// Sanity checks and default settings for the Quarantine parameters.
|
||||
|
||||
if (f->QuarantineSizeMb < 0) {
|
||||
const int DefaultQuarantineSizeMb = FIRST_32_SECOND_64(16, 64);
|
||||
const int DefaultQuarantineSizeMb = FIRST_32_SECOND_64(4, 16);
|
||||
f->QuarantineSizeMb = DefaultQuarantineSizeMb;
|
||||
}
|
||||
// We enforce an upper limit for the quarantine size of 4Gb.
|
||||
@ -77,7 +77,7 @@ void initFlags() {
|
||||
}
|
||||
if (f->ThreadLocalQuarantineSizeKb < 0) {
|
||||
const int DefaultThreadLocalQuarantineSizeKb =
|
||||
FIRST_32_SECOND_64(256, 1024);
|
||||
FIRST_32_SECOND_64(64, 256);
|
||||
f->ThreadLocalQuarantineSizeKb = DefaultThreadLocalQuarantineSizeKb;
|
||||
}
|
||||
// And an upper limit of 128Mb for the thread quarantine cache.
|
||||
|
@ -119,10 +119,15 @@ int __xray_set_customevent_handler(void (*entry)(void *, size_t))
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int __xray_remove_handler() XRAY_NEVER_INSTRUMENT {
|
||||
return __xray_set_handler(nullptr);
|
||||
}
|
||||
|
||||
int __xray_remove_customevent_handler() XRAY_NEVER_INSTRUMENT {
|
||||
return __xray_set_customevent_handler(nullptr);
|
||||
}
|
||||
|
||||
__sanitizer::atomic_uint8_t XRayPatching{0};
|
||||
|
||||
using namespace __xray;
|
||||
@ -326,7 +331,14 @@ uintptr_t __xray_function_address(int32_t FuncId) XRAY_NEVER_INSTRUMENT {
|
||||
__sanitizer::SpinMutexLock Guard(&XRayInstrMapMutex);
|
||||
if (FuncId <= 0 || static_cast<size_t>(FuncId) > XRayInstrMap.Functions)
|
||||
return 0;
|
||||
return XRayInstrMap.SledsIndex[FuncId - 1].Begin->Address;
|
||||
return XRayInstrMap.SledsIndex[FuncId - 1].Begin->Address
|
||||
// On PPC, function entries are always aligned to 16 bytes. The beginning of a
|
||||
// sled might be a local entry, which is always +8 based on the global entry.
|
||||
// Always return the global entry.
|
||||
#ifdef __PPC__
|
||||
& ~0xf
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
size_t __xray_max_function_id() XRAY_NEVER_INSTRUMENT {
|
||||
|
@ -2,7 +2,7 @@
|
||||
// Defaults to true
|
||||
// RUN: %clangxx_asan -std=c++11 %s -o %t
|
||||
// RUN: not %run %t %T/file 2>&1 | FileCheck %s -check-prefix=CHECK-BUS
|
||||
// RUN: %env_asan_opts=handle_sigbus=false not --crash %run %t %T/file 2>&1 | FileCheck %s
|
||||
// RUN: %env_asan_opts=handle_sigbus=0 not --crash %run %t %T/file 2>&1 | FileCheck %s
|
||||
|
||||
// UNSUPPORTED: ios
|
||||
|
||||
|
@ -1,27 +0,0 @@
|
||||
// RUN: %clangxx_asan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: %clangxx_asan -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: %clangxx_asan -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: %clangxx_asan -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s
|
||||
|
||||
// When built as C on Linux, strndup is transformed to __strndup.
|
||||
// RUN: %clangxx_asan -O3 -xc %s -o %t && not %run %t 2>&1 | FileCheck %s
|
||||
|
||||
// Unwind problem on arm: "main" is missing from the allocation stack trace.
|
||||
// UNSUPPORTED: win32,s390,armv7l-unknown-linux-gnueabihf
|
||||
|
||||
#include <string.h>
|
||||
|
||||
char kString[] = "foo";
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char *copy = strndup(kString, 2);
|
||||
int x = copy[2 + argc]; // BOOM
|
||||
// CHECK: AddressSanitizer: heap-buffer-overflow
|
||||
// CHECK: #0 {{.*}}main {{.*}}strndup_oob_test.cc:[[@LINE-2]]
|
||||
// CHECK-LABEL: allocated by thread T{{.*}} here:
|
||||
// CHECK: #{{[01]}} {{.*}}strndup
|
||||
// CHECK: #{{.*}}main {{.*}}strndup_oob_test.cc:[[@LINE-6]]
|
||||
// CHECK-LABEL: SUMMARY
|
||||
// CHECK: strndup_oob_test.cc:[[@LINE-7]]
|
||||
return x;
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
// RUN: %clangxx_msan %s -o %t && not %run %t 2>&1 | FileCheck --check-prefix=ON %s
|
||||
// RUN: %clangxx_msan %s -o %t && MSAN_OPTIONS=intercept_strndup=0 %run %t 2>&1 | FileCheck --check-prefix=OFF --allow-empty %s
|
||||
|
||||
// When built as C on Linux, strndup is transformed to __strndup.
|
||||
// RUN: %clangxx_msan -O3 -xc %s -o %t && not %run %t 2>&1 | FileCheck --check-prefix=ON %s
|
||||
|
||||
// UNSUPPORTED: win32
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sanitizer/msan_interface.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char kString[4] = "abc";
|
||||
__msan_poison(kString + 2, 1);
|
||||
char *copy = strndup(kString, 4); // BOOM
|
||||
assert(__msan_test_shadow(copy, 4) == 2); // Poisoning is preserved.
|
||||
free(copy);
|
||||
return 0;
|
||||
// ON: Uninitialized bytes in __interceptor_{{(__)?}}strndup at offset 2 inside [{{.*}}, 4)
|
||||
// ON: MemorySanitizer: use-of-uninitialized-value
|
||||
// ON: #0 {{.*}}main {{.*}}strndup.cc:[[@LINE-6]]
|
||||
// ON-LABEL: SUMMARY
|
||||
// ON: {{.*}}strndup.cc:[[@LINE-8]]
|
||||
// OFF-NOT: MemorySanitizer
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ int main() {
|
||||
// CHECK-NEXT: after calling the custom logging...
|
||||
printf("removing custom event handler...\n");
|
||||
// CHECK-NEXT: removing custom event handler...
|
||||
__xray_set_customevent_handler(nullptr);
|
||||
__xray_remove_customevent_handler();
|
||||
foo();
|
||||
// CHECK-NEXT: before calling the custom logging...
|
||||
// CHECK-NEXT: after calling the custom logging...
|
||||
|
@ -31,18 +31,10 @@
|
||||
"each function id must be assigned to a unique function");
|
||||
|
||||
std::set<void *> not_instrumented;
|
||||
const auto comp = [](void *lhs, void *rhs) {
|
||||
#ifdef __PPC__
|
||||
return reinterpret_cast<uintptr_t>(lhs) + 8 <
|
||||
reinterpret_cast<uintptr_t>(rhs);
|
||||
#else
|
||||
return lhs < rhs;
|
||||
#endif
|
||||
};
|
||||
std::set_difference(must_be_instrumented.begin(), must_be_instrumented.end(),
|
||||
all_instrumented.begin(), all_instrumented.end(),
|
||||
std::inserter(not_instrumented, not_instrumented.begin()),
|
||||
comp);
|
||||
std::set_difference(
|
||||
must_be_instrumented.begin(), must_be_instrumented.end(),
|
||||
all_instrumented.begin(), all_instrumented.end(),
|
||||
std::inserter(not_instrumented, not_instrumented.begin()));
|
||||
assert(
|
||||
not_instrumented.empty() &&
|
||||
"we should see all explicitly instrumented functions with function ids");
|
||||
|
Loading…
Reference in New Issue
Block a user