forked from OSchip/llvm-project
[sanitizer] Add strlen to the common interceptors
Summary: Adds strlen to the common interceptors, under a new common flag intercept_strlen. This provides better sharing of interception code among sanitizers and cleans up the inconsistent type declarations of the previously duplicated interceptors. Removes the now-duplicate strlen interceptor from asan, msan, and tsan. The entry check semantics are normalized now for msan and asan, whose private strlen interceptors contained multiple layers of checks that included impossible-to-reach code. The new semantics are identical to the old: bypass interception if in the middle of init or if both on Mac and not initialized; else, call the init routine and proceed. Patch by Derek Bruening! Reviewers: samsonov, vitalybuka Subscribers: llvm-commits, kcc, zhaoqin Differential Revision: http://reviews.llvm.org/D18020 llvm-svn: 263177
This commit is contained in:
parent
92a46991b5
commit
ed3d347e25
|
@ -159,6 +159,10 @@ void InitializeFlags() {
|
||||||
(ASAN_LOW_MEMORY) ? 1UL << 6 : 1UL << 8;
|
(ASAN_LOW_MEMORY) ? 1UL << 6 : 1UL << 8;
|
||||||
f->quarantine_size_mb = kDefaultQuarantineSizeMb;
|
f->quarantine_size_mb = kDefaultQuarantineSizeMb;
|
||||||
}
|
}
|
||||||
|
if (!f->replace_str && common_flags()->intercept_strlen) {
|
||||||
|
Report("WARNING: strlen interceptor is enabled even though replace_str=0. "
|
||||||
|
"Use intercept_strlen=0 to disable it.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace __asan
|
} // namespace __asan
|
||||||
|
|
|
@ -580,23 +580,6 @@ INTERCEPTOR(char*, strdup, const char *s) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
INTERCEPTOR(SIZE_T, strlen, const char *s) {
|
|
||||||
void *ctx;
|
|
||||||
ASAN_INTERCEPTOR_ENTER(ctx, strlen);
|
|
||||||
if (UNLIKELY(!asan_inited)) return internal_strlen(s);
|
|
||||||
// strlen is called from malloc_default_purgeable_zone()
|
|
||||||
// in __asan::ReplaceSystemAlloc() on Mac.
|
|
||||||
if (asan_init_is_running) {
|
|
||||||
return REAL(strlen)(s);
|
|
||||||
}
|
|
||||||
ENSURE_ASAN_INITED();
|
|
||||||
SIZE_T length = REAL(strlen)(s);
|
|
||||||
if (flags()->replace_str) {
|
|
||||||
ASAN_READ_RANGE(ctx, s, length + 1);
|
|
||||||
}
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
INTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) {
|
INTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) {
|
||||||
void *ctx;
|
void *ctx;
|
||||||
ASAN_INTERCEPTOR_ENTER(ctx, wcslen);
|
ASAN_INTERCEPTOR_ENTER(ctx, wcslen);
|
||||||
|
@ -763,7 +746,6 @@ void InitializeAsanInterceptors() {
|
||||||
ASAN_INTERCEPT_FUNC(strcat); // NOLINT
|
ASAN_INTERCEPT_FUNC(strcat); // NOLINT
|
||||||
ASAN_INTERCEPT_FUNC(strchr);
|
ASAN_INTERCEPT_FUNC(strchr);
|
||||||
ASAN_INTERCEPT_FUNC(strcpy); // NOLINT
|
ASAN_INTERCEPT_FUNC(strcpy); // NOLINT
|
||||||
ASAN_INTERCEPT_FUNC(strlen);
|
|
||||||
ASAN_INTERCEPT_FUNC(wcslen);
|
ASAN_INTERCEPT_FUNC(wcslen);
|
||||||
ASAN_INTERCEPT_FUNC(strncat);
|
ASAN_INTERCEPT_FUNC(strncat);
|
||||||
ASAN_INTERCEPT_FUNC(strncpy);
|
ASAN_INTERCEPT_FUNC(strncpy);
|
||||||
|
|
|
@ -43,6 +43,8 @@ using __sanitizer::atomic_load;
|
||||||
using __sanitizer::atomic_store;
|
using __sanitizer::atomic_store;
|
||||||
using __sanitizer::atomic_uintptr_t;
|
using __sanitizer::atomic_uintptr_t;
|
||||||
|
|
||||||
|
DECLARE_REAL(SIZE_T, strlen, const char *s)
|
||||||
|
|
||||||
#if SANITIZER_FREEBSD
|
#if SANITIZER_FREEBSD
|
||||||
#define __errno_location __error
|
#define __errno_location __error
|
||||||
#endif
|
#endif
|
||||||
|
@ -280,15 +282,6 @@ INTERCEPTOR(void, malloc_stats, void) {
|
||||||
#define MSAN_MAYBE_INTERCEPT_MALLOC_STATS
|
#define MSAN_MAYBE_INTERCEPT_MALLOC_STATS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
INTERCEPTOR(SIZE_T, strlen, const char *s) {
|
|
||||||
if (msan_init_is_running)
|
|
||||||
return REAL(strlen)(s);
|
|
||||||
ENSURE_MSAN_INITED();
|
|
||||||
SIZE_T res = REAL(strlen)(s);
|
|
||||||
CHECK_UNPOISONED(s, res + 1);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
INTERCEPTOR(SIZE_T, strnlen, const char *s, SIZE_T n) {
|
INTERCEPTOR(SIZE_T, strnlen, const char *s, SIZE_T n) {
|
||||||
ENSURE_MSAN_INITED();
|
ENSURE_MSAN_INITED();
|
||||||
SIZE_T res = REAL(strnlen)(s, n);
|
SIZE_T res = REAL(strnlen)(s, n);
|
||||||
|
@ -1562,7 +1555,6 @@ void InitializeInterceptors() {
|
||||||
INTERCEPT_FUNCTION(strndup);
|
INTERCEPT_FUNCTION(strndup);
|
||||||
MSAN_MAYBE_INTERCEPT___STRNDUP;
|
MSAN_MAYBE_INTERCEPT___STRNDUP;
|
||||||
INTERCEPT_FUNCTION(strncpy); // NOLINT
|
INTERCEPT_FUNCTION(strncpy); // NOLINT
|
||||||
INTERCEPT_FUNCTION(strlen);
|
|
||||||
INTERCEPT_FUNCTION(strnlen);
|
INTERCEPT_FUNCTION(strnlen);
|
||||||
INTERCEPT_FUNCTION(gcvt);
|
INTERCEPT_FUNCTION(gcvt);
|
||||||
INTERCEPT_FUNCTION(strcat); // NOLINT
|
INTERCEPT_FUNCTION(strcat); // NOLINT
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
// ThreadSanitizer, MemorySanitizer, etc.
|
// ThreadSanitizer, MemorySanitizer, etc.
|
||||||
//
|
//
|
||||||
// This file should be included into the tool's interceptor file,
|
// This file should be included into the tool's interceptor file,
|
||||||
// which has to define it's own macros:
|
// which has to define its own macros:
|
||||||
// COMMON_INTERCEPTOR_ENTER
|
// COMMON_INTERCEPTOR_ENTER
|
||||||
// COMMON_INTERCEPTOR_ENTER_NOIGNORE
|
// COMMON_INTERCEPTOR_ENTER_NOIGNORE
|
||||||
// COMMON_INTERCEPTOR_READ_RANGE
|
// COMMON_INTERCEPTOR_READ_RANGE
|
||||||
|
@ -200,6 +200,20 @@ UNUSED static void DeleteInterceptorMetadata(void *addr) {
|
||||||
}
|
}
|
||||||
#endif // SI_NOT_WINDOWS
|
#endif // SI_NOT_WINDOWS
|
||||||
|
|
||||||
|
#if SANITIZER_INTERCEPT_STRLEN
|
||||||
|
INTERCEPTOR(SIZE_T, strlen, const char *s) {
|
||||||
|
void *ctx;
|
||||||
|
COMMON_INTERCEPTOR_ENTER(ctx, strlen, s);
|
||||||
|
SIZE_T result = REAL(strlen)(s);
|
||||||
|
if (common_flags()->intercept_strlen)
|
||||||
|
COMMON_INTERCEPTOR_READ_RANGE(ctx, s, result + 1);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#define INIT_STRLEN COMMON_INTERCEPT_FUNCTION(strlen)
|
||||||
|
#else
|
||||||
|
#define INIT_STRLEN
|
||||||
|
#endif
|
||||||
|
|
||||||
#if SANITIZER_INTERCEPT_TEXTDOMAIN
|
#if SANITIZER_INTERCEPT_TEXTDOMAIN
|
||||||
INTERCEPTOR(char*, textdomain, const char *domainname) {
|
INTERCEPTOR(char*, textdomain, const char *domainname) {
|
||||||
void *ctx;
|
void *ctx;
|
||||||
|
@ -5376,6 +5390,7 @@ static void InitializeCommonInterceptors() {
|
||||||
interceptor_metadata_map = new((void *)&metadata_mem) MetadataHashMap();
|
interceptor_metadata_map = new((void *)&metadata_mem) MetadataHashMap();
|
||||||
|
|
||||||
INIT_TEXTDOMAIN;
|
INIT_TEXTDOMAIN;
|
||||||
|
INIT_STRLEN;
|
||||||
INIT_STRCMP;
|
INIT_STRCMP;
|
||||||
INIT_STRNCMP;
|
INIT_STRNCMP;
|
||||||
INIT_STRCASECMP;
|
INIT_STRCASECMP;
|
||||||
|
|
|
@ -182,6 +182,9 @@ COMMON_FLAG(bool, intercept_strspn, true,
|
||||||
COMMON_FLAG(bool, intercept_strpbrk, true,
|
COMMON_FLAG(bool, intercept_strpbrk, true,
|
||||||
"If set, uses custom wrappers for strpbrk function "
|
"If set, uses custom wrappers for strpbrk function "
|
||||||
"to find more errors.")
|
"to find more errors.")
|
||||||
|
COMMON_FLAG(bool, intercept_strlen, true,
|
||||||
|
"If set, uses custom wrappers for strlen function "
|
||||||
|
"to find more errors.")
|
||||||
COMMON_FLAG(bool, intercept_memcmp, true,
|
COMMON_FLAG(bool, intercept_memcmp, true,
|
||||||
"If set, uses custom wrappers for memcmp function "
|
"If set, uses custom wrappers for memcmp function "
|
||||||
"to find more errors.")
|
"to find more errors.")
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
# define SI_IOS 0
|
# define SI_IOS 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define SANITIZER_INTERCEPT_STRLEN 1
|
||||||
#define SANITIZER_INTERCEPT_STRCMP 1
|
#define SANITIZER_INTERCEPT_STRCMP 1
|
||||||
#define SANITIZER_INTERCEPT_STRSTR 1
|
#define SANITIZER_INTERCEPT_STRSTR 1
|
||||||
#define SANITIZER_INTERCEPT_STRCASESTR SI_NOT_WINDOWS
|
#define SANITIZER_INTERCEPT_STRCASESTR SI_NOT_WINDOWS
|
||||||
|
|
|
@ -668,13 +668,6 @@ TSAN_INTERCEPTOR(uptr, malloc_usable_size, void *p) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TSAN_INTERCEPTOR(uptr, strlen, const char *s) {
|
|
||||||
SCOPED_TSAN_INTERCEPTOR(strlen, s);
|
|
||||||
uptr len = internal_strlen(s);
|
|
||||||
MemoryAccessRange(thr, pc, (uptr)s, len + 1, false);
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
TSAN_INTERCEPTOR(void*, memset, void *dst, int v, uptr size) {
|
TSAN_INTERCEPTOR(void*, memset, void *dst, int v, uptr size) {
|
||||||
// On FreeBSD we get here from libthr internals on thread initialization.
|
// On FreeBSD we get here from libthr internals on thread initialization.
|
||||||
if (!COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) {
|
if (!COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) {
|
||||||
|
@ -2618,7 +2611,6 @@ void InitializeInterceptors() {
|
||||||
TSAN_MAYBE_INTERCEPT_PVALLOC;
|
TSAN_MAYBE_INTERCEPT_PVALLOC;
|
||||||
TSAN_INTERCEPT(posix_memalign);
|
TSAN_INTERCEPT(posix_memalign);
|
||||||
|
|
||||||
TSAN_INTERCEPT(strlen);
|
|
||||||
TSAN_INTERCEPT(memset);
|
TSAN_INTERCEPT(memset);
|
||||||
TSAN_INTERCEPT(memcpy);
|
TSAN_INTERCEPT(memcpy);
|
||||||
TSAN_INTERCEPT(memmove);
|
TSAN_INTERCEPT(memmove);
|
||||||
|
|
Loading…
Reference in New Issue