Skip to content

Commit

Permalink
[sanitizer] Add memset, memmove, and memcpy to the common interceptors
Browse files Browse the repository at this point in the history
Summary:
Currently, sanitizer_common_interceptors.inc has an implicit, undocumented
assumption that the sanitizer including it has previously declared
interceptors for memset and memmove.  Since the memset, memmove, and memcpy
routines require interception by many sanitizers, we add them to the
set of common interceptions, both to address the undocumented assumption
and to speed future tool development.  They are intercepted under a new
flag intercept_intrin.

The tsan interceptors are removed in favor of the new common versions.  The
asan and msan interceptors for these are more complex (they incur extra
interception steps and their function bodies are exposed to the compiler)
so they opt out of the common versions and keep their own.

Reviewers: vitalybuka

Subscribers: zhaoqin, llvm-commits, kcc

Differential Revision: http://reviews.llvm.org/D18465

llvm-svn: 264451
  • Loading branch information
derekbruening committed Mar 25, 2016
1 parent 2544788 commit e988af9
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 36 deletions.
2 changes: 1 addition & 1 deletion compiler-rt/lib/asan/asan_flags.inc
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ ASAN_FLAG(
"If set, uses custom wrappers and replacements for libc string functions "
"to find more errors.")
ASAN_FLAG(bool, replace_intrin, true,
"If set, uses custom wrappers for memset/memcpy/memmove intinsics.")
"If set, uses custom wrappers for memset/memcpy/memmove intrinsics.")
ASAN_FLAG(bool, detect_stack_use_after_return, false,
"Enables stack-use-after-return checking at run-time.")
ASAN_FLAG(int, min_uar_stack_size_log, 16, // We can't do smaller anyway.
Expand Down
4 changes: 4 additions & 0 deletions compiler-rt/lib/asan/asan_interceptors.cc
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,10 @@ DECLARE_REAL_AND_INTERCEPTOR(void, free, void *)
} else { \
*begin = *end = 0; \
}
// Asan needs custom handling of these:
#undef SANITIZER_INTERCEPT_MEMSET
#undef SANITIZER_INTERCEPT_MEMMOVE
#undef SANITIZER_INTERCEPT_MEMCPY
#include "sanitizer_common/sanitizer_common_interceptors.inc"

// Syscall interceptors don't have contexts, we don't support suppressions
Expand Down
5 changes: 5 additions & 0 deletions compiler-rt/lib/msan/msan_interceptors.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1436,6 +1436,11 @@ int OnExit() {
*begin = *end = 0; \
}

#include "sanitizer_common/sanitizer_platform_interceptors.h"
// Msan needs custom handling of these:
#undef SANITIZER_INTERCEPT_MEMSET
#undef SANITIZER_INTERCEPT_MEMMOVE
#undef SANITIZER_INTERCEPT_MEMCPY
#include "sanitizer_common/sanitizer_common_interceptors.inc"

#define COMMON_SYSCALL_PRE_READ_RANGE(p, s) CHECK_UNPOISONED(p, s)
Expand Down
61 changes: 61 additions & 0 deletions compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,64 @@ INTERCEPTOR(char *, strpbrk, const char *s1, const char *s2) {
#define INIT_STRPBRK
#endif

#if SANITIZER_INTERCEPT_MEMSET
INTERCEPTOR(void*, memset, void *dst, int v, uptr size) {
if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
return internal_memset(dst, v, size);
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, memset, dst, v, size);
if (common_flags()->intercept_intrin)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size);
return REAL(memset)(dst, v, size);
}

#define INIT_MEMSET COMMON_INTERCEPT_FUNCTION(memset)
#else
#define INIT_MEMSET
#endif

#if SANITIZER_INTERCEPT_MEMMOVE
INTERCEPTOR(void*, memmove, void *dst, const void *src, uptr size) {
if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
return internal_memmove(dst, src, size);
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, memmove, dst, src, size);
if (common_flags()->intercept_intrin) {
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size);
COMMON_INTERCEPTOR_READ_RANGE(ctx, src, size);
}
return REAL(memmove)(dst, src, size);
}

#define INIT_MEMMOVE COMMON_INTERCEPT_FUNCTION(memmove)
#else
#define INIT_MEMMOVE
#endif

#if SANITIZER_INTERCEPT_MEMCPY
INTERCEPTOR(void*, memcpy, void *dst, const void *src, uptr size) {
if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) {
// On OS X, calling internal_memcpy here will cause memory corruptions,
// because memcpy and memmove are actually aliases of the same
// implementation. We need to use internal_memmove here.
return internal_memmove(dst, src, size);
}
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, memcpy, dst, src, size);
if (common_flags()->intercept_intrin) {
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size);
COMMON_INTERCEPTOR_READ_RANGE(ctx, src, size);
}
// N.B.: If we switch this to internal_ we'll have to use internal_memmove
// due to memcpy being an alias of memmove on OS X.
return REAL(memcpy)(dst, src, size);
}

#define INIT_MEMCPY COMMON_INTERCEPT_FUNCTION(memcpy)
#else
#define INIT_MEMCPY
#endif

#if SANITIZER_INTERCEPT_MEMCMP

DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, uptr called_pc,
Expand Down Expand Up @@ -5471,6 +5529,9 @@ static void InitializeCommonInterceptors() {
INIT_STRRCHR;
INIT_STRSPN;
INIT_STRPBRK;
INIT_MEMSET;
INIT_MEMMOVE;
INIT_MEMCPY;
INIT_MEMCHR;
INIT_MEMCMP;
INIT_MEMRCHR;
Expand Down
3 changes: 3 additions & 0 deletions compiler-rt/lib/sanitizer_common/sanitizer_flags.inc
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,9 @@ COMMON_FLAG(bool, intercept_memcmp, true,
COMMON_FLAG(bool, strict_memcmp, true,
"If true, assume that memcmp(p1, p2, n) always reads n bytes before "
"comparing p1 and p2.")
COMMON_FLAG(bool, intercept_intrin, true,
"If set, uses custom wrappers for memset/memcpy/memmove "
"intrinsics to find more errors.")
COMMON_FLAG(bool, decorate_proc_maps, false, "If set, decorate sanitizer "
"mappings in /proc/self/maps with "
"user-readable names")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@
#define SANITIZER_INTERCEPT_STRPBRK 1
#define SANITIZER_INTERCEPT_TEXTDOMAIN SI_LINUX_NOT_ANDROID
#define SANITIZER_INTERCEPT_STRCASECMP SI_NOT_WINDOWS
#define SANITIZER_INTERCEPT_MEMSET 1
#define SANITIZER_INTERCEPT_MEMMOVE 1
#define SANITIZER_INTERCEPT_MEMCPY 1
#define SANITIZER_INTERCEPT_MEMCMP 1
#define SANITIZER_INTERCEPT_MEMCHR 1
#define SANITIZER_INTERCEPT_MEMRCHR SI_FREEBSD || SI_LINUX
Expand Down
36 changes: 1 addition & 35 deletions compiler-rt/lib/tsan/rtl/tsan_interceptors.cc
Original file line number Diff line number Diff line change
Expand Up @@ -668,37 +668,6 @@ TSAN_INTERCEPTOR(uptr, malloc_usable_size, void *p) {
}
#endif

TSAN_INTERCEPTOR(void*, memset, void *dst, int v, uptr size) {
// On FreeBSD we get here from libthr internals on thread initialization.
if (!COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) {
SCOPED_TSAN_INTERCEPTOR(memset, dst, v, size);
MemoryAccessRange(thr, pc, (uptr)dst, size, true);
}
return internal_memset(dst, v, size);
}

TSAN_INTERCEPTOR(void*, memcpy, void *dst, const void *src, uptr size) {
// On FreeBSD we get here from libthr internals on thread initialization.
if (!COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) {
SCOPED_TSAN_INTERCEPTOR(memcpy, dst, src, size);
MemoryAccessRange(thr, pc, (uptr)dst, size, true);
MemoryAccessRange(thr, pc, (uptr)src, size, false);
}
// On OS X, calling internal_memcpy here will cause memory corruptions,
// because memcpy and memmove are actually aliases of the same implementation.
// We need to use internal_memmove here.
return internal_memmove(dst, src, size);
}

TSAN_INTERCEPTOR(void*, memmove, void *dst, void *src, uptr n) {
if (!COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) {
SCOPED_TSAN_INTERCEPTOR(memmove, dst, src, n);
MemoryAccessRange(thr, pc, (uptr)dst, n, true);
MemoryAccessRange(thr, pc, (uptr)src, n, false);
}
return REAL(memmove)(dst, src, n);
}

TSAN_INTERCEPTOR(char*, strcpy, char *dst, const char *src) { // NOLINT
SCOPED_TSAN_INTERCEPTOR(strcpy, dst, src); // NOLINT
uptr srclen = internal_strlen(src);
Expand Down Expand Up @@ -2087,7 +2056,7 @@ TSAN_INTERCEPTOR(int, sigaction, int sig, sigaction_t *act, sigaction_t *old) {
TSAN_INTERCEPTOR(sighandler_t, signal, int sig, sighandler_t h) {
sigaction_t act;
act.sa_handler = h;
REAL(memset)(&act.sa_mask, -1, sizeof(act.sa_mask));
internal_memset(&act.sa_mask, -1, sizeof(act.sa_mask));
act.sa_flags = 0;
sigaction_t old;
int res = sigaction(sig, &act, &old);
Expand Down Expand Up @@ -2598,9 +2567,6 @@ void InitializeInterceptors() {
TSAN_MAYBE_INTERCEPT_PVALLOC;
TSAN_INTERCEPT(posix_memalign);

TSAN_INTERCEPT(memset);
TSAN_INTERCEPT(memcpy);
TSAN_INTERCEPT(memmove);
TSAN_INTERCEPT(strcpy); // NOLINT
TSAN_INTERCEPT(strncpy);
TSAN_INTERCEPT(strdup);
Expand Down

0 comments on commit e988af9

Please sign in to comment.