[compiler-rt] r223508 - Implement AddressSanitizer suppressions.
Kuba Brecka
kuba.brecka at gmail.com
Fri Dec 5 12:26:09 PST 2014
Author: kuba.brecka
Date: Fri Dec 5 14:26:09 2014
New Revision: 223508
URL: http://llvm.org/viewvc/llvm-project?rev=223508&view=rev
Log:
Implement AddressSanitizer suppressions.
Adds 3 new suppression types, "interceptor_name", "interceptor_via_fun", "interceptor_via_lib".
Reviewed at http://reviews.llvm.org/D6280.
Added:
compiler-rt/trunk/lib/asan/asan_suppressions.cc
compiler-rt/trunk/lib/asan/asan_suppressions.h
compiler-rt/trunk/test/asan/TestCases/Darwin/suppressions-darwin.cc
compiler-rt/trunk/test/asan/TestCases/suppressions-function.cc
compiler-rt/trunk/test/asan/TestCases/suppressions-interceptor.cc
compiler-rt/trunk/test/asan/TestCases/suppressions-library.cc
Modified:
compiler-rt/trunk/lib/asan/CMakeLists.txt
compiler-rt/trunk/lib/asan/asan_interceptors.cc
compiler-rt/trunk/lib/asan/asan_rtl.cc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.cc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.h
compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_suppressions_test.cc
Modified: compiler-rt/trunk/lib/asan/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/CMakeLists.txt?rev=223508&r1=223507&r2=223508&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/asan/CMakeLists.txt Fri Dec 5 14:26:09 2014
@@ -18,6 +18,7 @@ set(ASAN_SOURCES
asan_rtl.cc
asan_stack.cc
asan_stats.cc
+ asan_suppressions.cc
asan_thread.cc
asan_win.cc)
Modified: compiler-rt/trunk/lib/asan/asan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.cc?rev=223508&r1=223507&r2=223508&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_interceptors.cc Fri Dec 5 14:26:09 2014
@@ -20,6 +20,7 @@
#include "asan_report.h"
#include "asan_stack.h"
#include "asan_stats.h"
+#include "asan_suppressions.h"
#include "sanitizer_common/sanitizer_libc.h"
namespace __asan {
@@ -34,12 +35,16 @@ static inline bool QuickCheckForUnpoison
return false;
}
+struct AsanInterceptorContext {
+ const char *interceptor_name;
+};
+
// We implement ACCESS_MEMORY_RANGE, ASAN_READ_RANGE,
// and ASAN_WRITE_RANGE as macro instead of function so
// that no extra frames are created, and stack trace contains
// relevant information only.
// We check all shadow bytes.
-#define ACCESS_MEMORY_RANGE(offset, size, isWrite) do { \
+#define ACCESS_MEMORY_RANGE(ctx, offset, size, isWrite) do { \
uptr __offset = (uptr)(offset); \
uptr __size = (uptr)(size); \
uptr __bad = 0; \
@@ -49,13 +54,26 @@ static inline bool QuickCheckForUnpoison
} \
if (!QuickCheckForUnpoisonedRegion(__offset, __size) && \
(__bad = __asan_region_is_poisoned(__offset, __size))) { \
- GET_CURRENT_PC_BP_SP; \
- __asan_report_error(pc, bp, sp, __bad, isWrite, __size); \
+ AsanInterceptorContext *_ctx = (AsanInterceptorContext *)ctx; \
+ bool suppressed = false; \
+ if (_ctx) { \
+ suppressed = IsInterceptorSuppressed(_ctx->interceptor_name); \
+ if (!suppressed && HaveStackTraceBasedSuppressions()) { \
+ GET_STACK_TRACE_FATAL_HERE; \
+ suppressed = IsStackTraceSuppressed(&stack); \
+ } \
+ } \
+ if (!suppressed) { \
+ GET_CURRENT_PC_BP_SP; \
+ __asan_report_error(pc, bp, sp, __bad, isWrite, __size); \
+ } \
} \
} while (0)
-#define ASAN_READ_RANGE(offset, size) ACCESS_MEMORY_RANGE(offset, size, false)
-#define ASAN_WRITE_RANGE(offset, size) ACCESS_MEMORY_RANGE(offset, size, true)
+#define ASAN_READ_RANGE(ctx, offset, size) \
+ ACCESS_MEMORY_RANGE(ctx, offset, size, false)
+#define ASAN_WRITE_RANGE(ctx, offset, size) \
+ ACCESS_MEMORY_RANGE(ctx, offset, size, true)
// Behavior of functions like "memcpy" or "strcpy" is undefined
// if memory intervals overlap. We report error in this case.
@@ -113,16 +131,21 @@ DECLARE_REAL_AND_INTERCEPTOR(void, free,
#define ASAN_INTERCEPT_FUNC(name)
#endif // SANITIZER_MAC
+#define ASAN_INTERCEPTOR_ENTER(ctx, func) \
+ AsanInterceptorContext _ctx = {#func}; \
+ ctx = (void *)&_ctx; \
+ (void) ctx; \
+
#define COMMON_INTERCEPT_FUNCTION(name) ASAN_INTERCEPT_FUNC(name)
#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
- ASAN_WRITE_RANGE(ptr, size)
-#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) ASAN_READ_RANGE(ptr, size)
+ ASAN_WRITE_RANGE(ctx, ptr, size)
+#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \
+ ASAN_READ_RANGE(ctx, ptr, size)
#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \
do { \
if (asan_init_is_running) \
return REAL(func)(__VA_ARGS__); \
- ctx = 0; \
- (void) ctx; \
+ ASAN_INTERCEPTOR_ENTER(ctx, func); \
if (SANITIZER_MAC && UNLIKELY(!asan_inited)) \
return REAL(func)(__VA_ARGS__); \
ENSURE_ASAN_INITED(); \
@@ -151,8 +174,10 @@ DECLARE_REAL_AND_INTERCEPTOR(void, free,
#define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (!asan_inited)
#include "sanitizer_common/sanitizer_common_interceptors.inc"
-#define COMMON_SYSCALL_PRE_READ_RANGE(p, s) ASAN_READ_RANGE(p, s)
-#define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) ASAN_WRITE_RANGE(p, s)
+// Syscall interceptors don't have contexts, we don't support suppressions
+// for them.
+#define COMMON_SYSCALL_PRE_READ_RANGE(p, s) ASAN_READ_RANGE(nullptr, p, s)
+#define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) ASAN_WRITE_RANGE(nullptr, p, s)
#define COMMON_SYSCALL_POST_READ_RANGE(p, s) \
do { \
(void)(p); \
@@ -347,14 +372,16 @@ static inline int CharCmp(unsigned char
}
INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) {
+ void *ctx;
+ ASAN_INTERCEPTOR_ENTER(ctx, memcmp);
if (UNLIKELY(!asan_inited)) return internal_memcmp(a1, a2, size);
ENSURE_ASAN_INITED();
if (flags()->replace_intrin) {
if (flags()->strict_memcmp) {
// Check the entire regions even if the first bytes of the buffers are
// different.
- ASAN_READ_RANGE(a1, size);
- ASAN_READ_RANGE(a2, size);
+ ASAN_READ_RANGE(ctx, a1, size);
+ ASAN_READ_RANGE(ctx, a2, size);
// Fallthrough to REAL(memcmp) below.
} else {
unsigned char c1 = 0, c2 = 0;
@@ -366,65 +393,81 @@ INTERCEPTOR(int, memcmp, const void *a1,
c2 = s2[i];
if (c1 != c2) break;
}
- ASAN_READ_RANGE(s1, Min(i + 1, size));
- ASAN_READ_RANGE(s2, Min(i + 1, size));
+ ASAN_READ_RANGE(ctx, s1, Min(i + 1, size));
+ ASAN_READ_RANGE(ctx, s2, Min(i + 1, size));
return CharCmp(c1, c2);
}
}
return REAL(memcmp(a1, a2, size));
}
+// memcpy is called during __asan_init() from the internals of printf(...).
+// We do not treat memcpy with to==from as a bug.
+// See http://llvm.org/bugs/show_bug.cgi?id=11763.
+#define ASAN_MEMCPY_IMPL(ctx, to, from, size) do { \
+ if (UNLIKELY(!asan_inited)) return internal_memcpy(to, from, size); \
+ if (asan_init_is_running) { \
+ return REAL(memcpy)(to, from, size); \
+ } \
+ ENSURE_ASAN_INITED(); \
+ if (flags()->replace_intrin) { \
+ if (to != from) { \
+ CHECK_RANGES_OVERLAP("memcpy", to, size, from, size); \
+ } \
+ ASAN_READ_RANGE(ctx, from, size); \
+ ASAN_WRITE_RANGE(ctx, to, size); \
+ } \
+ return REAL(memcpy)(to, from, size); \
+ } while (0)
+
+
void *__asan_memcpy(void *to, const void *from, uptr size) {
- if (UNLIKELY(!asan_inited)) return internal_memcpy(to, from, size);
- // memcpy is called during __asan_init() from the internals
- // of printf(...).
- if (asan_init_is_running) {
- return REAL(memcpy)(to, from, size);
- }
- ENSURE_ASAN_INITED();
- if (flags()->replace_intrin) {
- if (to != from) {
- // We do not treat memcpy with to==from as a bug.
- // See http://llvm.org/bugs/show_bug.cgi?id=11763.
- CHECK_RANGES_OVERLAP("memcpy", to, size, from, size);
- }
- ASAN_READ_RANGE(from, size);
- ASAN_WRITE_RANGE(to, size);
- }
- return REAL(memcpy)(to, from, size);
+ ASAN_MEMCPY_IMPL(nullptr, to, from, size);
}
+// memset is called inside Printf.
+#define ASAN_MEMSET_IMPL(ctx, block, c, size) do { \
+ if (UNLIKELY(!asan_inited)) return internal_memset(block, c, size); \
+ if (asan_init_is_running) { \
+ return REAL(memset)(block, c, size); \
+ } \
+ ENSURE_ASAN_INITED(); \
+ if (flags()->replace_intrin) { \
+ ASAN_WRITE_RANGE(ctx, block, size); \
+ } \
+ return REAL(memset)(block, c, size); \
+ } while (0)
+
void *__asan_memset(void *block, int c, uptr size) {
- if (UNLIKELY(!asan_inited)) return internal_memset(block, c, size);
- // memset is called inside Printf.
- if (asan_init_is_running) {
- return REAL(memset)(block, c, size);
- }
- ENSURE_ASAN_INITED();
- if (flags()->replace_intrin) {
- ASAN_WRITE_RANGE(block, size);
- }
- return REAL(memset)(block, c, size);
+ ASAN_MEMSET_IMPL(nullptr, block, c, size);
}
+#define ASAN_MEMMOVE_IMPL(ctx, to, from, size) do { \
+ if (UNLIKELY(!asan_inited)) \
+ return internal_memmove(to, from, size); \
+ ENSURE_ASAN_INITED(); \
+ if (flags()->replace_intrin) { \
+ ASAN_READ_RANGE(ctx, from, size); \
+ ASAN_WRITE_RANGE(ctx, to, size); \
+ } \
+ return internal_memmove(to, from, size); \
+ } while (0)
+
void *__asan_memmove(void *to, const void *from, uptr size) {
- if (UNLIKELY(!asan_inited))
- return internal_memmove(to, from, size);
- ENSURE_ASAN_INITED();
- if (flags()->replace_intrin) {
- ASAN_READ_RANGE(from, size);
- ASAN_WRITE_RANGE(to, size);
- }
- return internal_memmove(to, from, size);
+ ASAN_MEMMOVE_IMPL(nullptr, to, from, size);
}
INTERCEPTOR(void*, memmove, void *to, const void *from, uptr size) {
- return __asan_memmove(to, from, size);
+ void *ctx;
+ ASAN_INTERCEPTOR_ENTER(ctx, memmove);
+ ASAN_MEMMOVE_IMPL(ctx, to, from, size);
}
INTERCEPTOR(void*, memcpy, void *to, const void *from, uptr size) {
+ void *ctx;
+ ASAN_INTERCEPTOR_ENTER(ctx, memcpy);
#if !SANITIZER_MAC
- return __asan_memcpy(to, from, size);
+ ASAN_MEMCPY_IMPL(ctx, to, from, size);
#else
// At least on 10.7 and 10.8 both memcpy() and memmove() are being replaced
// with WRAP(memcpy). As a result, false positives are reported for memmove()
@@ -432,15 +475,19 @@ INTERCEPTOR(void*, memcpy, void *to, con
// ASAN_OPTIONS=replace_intrin=0, memmove() is still replaced with
// internal_memcpy(), which may lead to crashes, see
// http://llvm.org/bugs/show_bug.cgi?id=16362.
- return __asan_memmove(to, from, size);
+ ASAN_MEMMOVE_IMPL(ctx, to, from, size);
#endif // !SANITIZER_MAC
}
INTERCEPTOR(void*, memset, void *block, int c, uptr size) {
- return __asan_memset(block, c, size);
+ void *ctx;
+ ASAN_INTERCEPTOR_ENTER(ctx, memset);
+ ASAN_MEMSET_IMPL(ctx, block, c, size);
}
INTERCEPTOR(char*, strchr, const char *str, int c) {
+ void *ctx;
+ ASAN_INTERCEPTOR_ENTER(ctx, strchr);
if (UNLIKELY(!asan_inited)) return internal_strchr(str, c);
// strchr is called inside create_purgeable_zone() when MallocGuardEdges=1 is
// used.
@@ -451,7 +498,7 @@ INTERCEPTOR(char*, strchr, const char *s
char *result = REAL(strchr)(str, c);
if (flags()->replace_str) {
uptr bytes_read = (result ? result - str : REAL(strlen)(str)) + 1;
- ASAN_READ_RANGE(str, bytes_read);
+ ASAN_READ_RANGE(ctx, str, bytes_read);
}
return result;
}
@@ -473,13 +520,15 @@ DEFINE_REAL(char*, index, const char *st
// For both strcat() and strncat() we need to check the validity of |to|
// argument irrespective of the |from| length.
INTERCEPTOR(char*, strcat, char *to, const char *from) { // NOLINT
+ void *ctx;
+ ASAN_INTERCEPTOR_ENTER(ctx, strcat); // NOLINT
ENSURE_ASAN_INITED();
if (flags()->replace_str) {
uptr from_length = REAL(strlen)(from);
- ASAN_READ_RANGE(from, from_length + 1);
+ ASAN_READ_RANGE(ctx, from, from_length + 1);
uptr to_length = REAL(strlen)(to);
- ASAN_READ_RANGE(to, to_length);
- ASAN_WRITE_RANGE(to + to_length, from_length + 1);
+ ASAN_READ_RANGE(ctx, to, to_length);
+ ASAN_WRITE_RANGE(ctx, to + to_length, from_length + 1);
// If the copying actually happens, the |from| string should not overlap
// with the resulting string starting at |to|, which has a length of
// to_length + from_length + 1.
@@ -492,14 +541,16 @@ INTERCEPTOR(char*, strcat, char *to, con
}
INTERCEPTOR(char*, strncat, char *to, const char *from, uptr size) {
+ void *ctx;
+ ASAN_INTERCEPTOR_ENTER(ctx, strncat);
ENSURE_ASAN_INITED();
if (flags()->replace_str) {
uptr from_length = MaybeRealStrnlen(from, size);
uptr copy_length = Min(size, from_length + 1);
- ASAN_READ_RANGE(from, copy_length);
+ ASAN_READ_RANGE(ctx, from, copy_length);
uptr to_length = REAL(strlen)(to);
- ASAN_READ_RANGE(to, to_length);
- ASAN_WRITE_RANGE(to + to_length, from_length + 1);
+ ASAN_READ_RANGE(ctx, to, to_length);
+ ASAN_WRITE_RANGE(ctx, to + to_length, from_length + 1);
if (from_length > 0) {
CHECK_RANGES_OVERLAP("strncat", to, to_length + copy_length + 1,
from, copy_length);
@@ -509,6 +560,8 @@ INTERCEPTOR(char*, strncat, char *to, co
}
INTERCEPTOR(char*, strcpy, char *to, const char *from) { // NOLINT
+ void *ctx;
+ ASAN_INTERCEPTOR_ENTER(ctx, strcpy); // NOLINT
#if SANITIZER_MAC
if (UNLIKELY(!asan_inited)) return REAL(strcpy)(to, from); // NOLINT
#endif
@@ -521,19 +574,21 @@ INTERCEPTOR(char*, strcpy, char *to, con
if (flags()->replace_str) {
uptr from_size = REAL(strlen)(from) + 1;
CHECK_RANGES_OVERLAP("strcpy", to, from_size, from, from_size);
- ASAN_READ_RANGE(from, from_size);
- ASAN_WRITE_RANGE(to, from_size);
+ ASAN_READ_RANGE(ctx, from, from_size);
+ ASAN_WRITE_RANGE(ctx, to, from_size);
}
return REAL(strcpy)(to, from); // NOLINT
}
#if ASAN_INTERCEPT_STRDUP
INTERCEPTOR(char*, strdup, const char *s) {
+ void *ctx;
+ ASAN_INTERCEPTOR_ENTER(ctx, strdup);
if (UNLIKELY(!asan_inited)) return internal_strdup(s);
ENSURE_ASAN_INITED();
uptr length = REAL(strlen)(s);
if (flags()->replace_str) {
- ASAN_READ_RANGE(s, length + 1);
+ ASAN_READ_RANGE(ctx, s, length + 1);
}
GET_STACK_TRACE_MALLOC;
void *new_mem = asan_malloc(length + 1, &stack);
@@ -543,6 +598,8 @@ INTERCEPTOR(char*, strdup, const char *s
#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.
@@ -552,37 +609,43 @@ INTERCEPTOR(SIZE_T, strlen, const char *
ENSURE_ASAN_INITED();
SIZE_T length = REAL(strlen)(s);
if (flags()->replace_str) {
- ASAN_READ_RANGE(s, length + 1);
+ ASAN_READ_RANGE(ctx, s, length + 1);
}
return length;
}
INTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) {
+ void *ctx;
+ ASAN_INTERCEPTOR_ENTER(ctx, wcslen);
SIZE_T length = REAL(wcslen)(s);
if (!asan_init_is_running) {
ENSURE_ASAN_INITED();
- ASAN_READ_RANGE(s, (length + 1) * sizeof(wchar_t));
+ ASAN_READ_RANGE(ctx, s, (length + 1) * sizeof(wchar_t));
}
return length;
}
INTERCEPTOR(char*, strncpy, char *to, const char *from, uptr size) {
+ void *ctx;
+ ASAN_INTERCEPTOR_ENTER(ctx, strncpy);
ENSURE_ASAN_INITED();
if (flags()->replace_str) {
uptr from_size = Min(size, MaybeRealStrnlen(from, size) + 1);
CHECK_RANGES_OVERLAP("strncpy", to, from_size, from, from_size);
- ASAN_READ_RANGE(from, from_size);
- ASAN_WRITE_RANGE(to, size);
+ ASAN_READ_RANGE(ctx, from, from_size);
+ ASAN_WRITE_RANGE(ctx, to, size);
}
return REAL(strncpy)(to, from, size);
}
#if ASAN_INTERCEPT_STRNLEN
INTERCEPTOR(uptr, strnlen, const char *s, uptr maxlen) {
+ void *ctx;
+ ASAN_INTERCEPTOR_ENTER(ctx, strnlen);
ENSURE_ASAN_INITED();
uptr length = REAL(strnlen)(s, maxlen);
if (flags()->replace_str) {
- ASAN_READ_RANGE(s, Min(length + 1, maxlen));
+ ASAN_READ_RANGE(ctx, s, Min(length + 1, maxlen));
}
return length;
}
@@ -607,6 +670,8 @@ static inline void FixRealStrtolEndptr(c
INTERCEPTOR(long, strtol, const char *nptr, // NOLINT
char **endptr, int base) {
+ void *ctx;
+ ASAN_INTERCEPTOR_ENTER(ctx, strtol);
ENSURE_ASAN_INITED();
if (!flags()->replace_str) {
return REAL(strtol)(nptr, endptr, base);
@@ -618,12 +683,14 @@ INTERCEPTOR(long, strtol, const char *np
}
if (IsValidStrtolBase(base)) {
FixRealStrtolEndptr(nptr, &real_endptr);
- ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1);
+ ASAN_READ_RANGE(ctx, nptr, (real_endptr - nptr) + 1);
}
return result;
}
INTERCEPTOR(int, atoi, const char *nptr) {
+ void *ctx;
+ ASAN_INTERCEPTOR_ENTER(ctx, atoi);
#if SANITIZER_MAC
if (UNLIKELY(!asan_inited)) return REAL(atoi)(nptr);
#endif
@@ -638,11 +705,13 @@ INTERCEPTOR(int, atoi, const char *nptr)
// different from int). So, we just imitate this behavior.
int result = REAL(strtol)(nptr, &real_endptr, 10);
FixRealStrtolEndptr(nptr, &real_endptr);
- ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1);
+ ASAN_READ_RANGE(ctx, nptr, (real_endptr - nptr) + 1);
return result;
}
INTERCEPTOR(long, atol, const char *nptr) { // NOLINT
+ void *ctx;
+ ASAN_INTERCEPTOR_ENTER(ctx, atol);
#if SANITIZER_MAC
if (UNLIKELY(!asan_inited)) return REAL(atol)(nptr);
#endif
@@ -653,13 +722,15 @@ INTERCEPTOR(long, atol, const char *nptr
char *real_endptr;
long result = REAL(strtol)(nptr, &real_endptr, 10); // NOLINT
FixRealStrtolEndptr(nptr, &real_endptr);
- ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1);
+ ASAN_READ_RANGE(ctx, nptr, (real_endptr - nptr) + 1);
return result;
}
#if ASAN_INTERCEPT_ATOLL_AND_STRTOLL
INTERCEPTOR(long long, strtoll, const char *nptr, // NOLINT
char **endptr, int base) {
+ void *ctx;
+ ASAN_INTERCEPTOR_ENTER(ctx, strtoll);
ENSURE_ASAN_INITED();
if (!flags()->replace_str) {
return REAL(strtoll)(nptr, endptr, base);
@@ -674,12 +745,14 @@ INTERCEPTOR(long long, strtoll, const ch
// if base is valid.
if (IsValidStrtolBase(base)) {
FixRealStrtolEndptr(nptr, &real_endptr);
- ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1);
+ ASAN_READ_RANGE(ctx, nptr, (real_endptr - nptr) + 1);
}
return result;
}
INTERCEPTOR(long long, atoll, const char *nptr) { // NOLINT
+ void *ctx;
+ ASAN_INTERCEPTOR_ENTER(ctx, atoll);
ENSURE_ASAN_INITED();
if (!flags()->replace_str) {
return REAL(atoll)(nptr);
@@ -687,7 +760,7 @@ INTERCEPTOR(long long, atoll, const char
char *real_endptr;
long long result = REAL(strtoll)(nptr, &real_endptr, 10); // NOLINT
FixRealStrtolEndptr(nptr, &real_endptr);
- ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1);
+ ASAN_READ_RANGE(ctx, nptr, (real_endptr - nptr) + 1);
return result;
}
#endif // ASAN_INTERCEPT_ATOLL_AND_STRTOLL
Modified: compiler-rt/trunk/lib/asan/asan_rtl.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_rtl.cc?rev=223508&r1=223507&r2=223508&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_rtl.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_rtl.cc Fri Dec 5 14:26:09 2014
@@ -21,6 +21,7 @@
#include "asan_report.h"
#include "asan_stack.h"
#include "asan_stats.h"
+#include "asan_suppressions.h"
#include "asan_thread.h"
#include "sanitizer_common/sanitizer_atomic.h"
#include "sanitizer_common/sanitizer_flags.h"
@@ -691,6 +692,8 @@ static void AsanInitInternal() {
}
#endif // CAN_SANITIZE_LEAKS
+ InitializeSuppressions();
+
VReport(1, "AddressSanitizer Init done\n");
}
Added: compiler-rt/trunk/lib/asan/asan_suppressions.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_suppressions.cc?rev=223508&view=auto
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_suppressions.cc (added)
+++ compiler-rt/trunk/lib/asan/asan_suppressions.cc Fri Dec 5 14:26:09 2014
@@ -0,0 +1,87 @@
+//===-- asan_suppressions.cc ----------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of AddressSanitizer, an address sanity checker.
+//
+// Issue suppression and suppression-related functions.
+//===----------------------------------------------------------------------===//
+
+#include "asan_suppressions.h"
+
+#include "asan_stack.h"
+#include "sanitizer_common/sanitizer_suppressions.h"
+#include "sanitizer_common/sanitizer_symbolizer.h"
+
+namespace __asan {
+
+static bool suppressions_inited = false;
+
+void InitializeSuppressions() {
+ CHECK(!suppressions_inited);
+ SuppressionContext::InitIfNecessary();
+ suppressions_inited = true;
+}
+
+bool IsInterceptorSuppressed(const char *interceptor_name) {
+ CHECK(suppressions_inited);
+ SuppressionContext *ctx = SuppressionContext::Get();
+ Suppression *s;
+ // Match "interceptor_name" suppressions.
+ return ctx->Match(interceptor_name, SuppressionInterceptorName, &s);
+}
+
+bool HaveStackTraceBasedSuppressions() {
+ CHECK(suppressions_inited);
+ SuppressionContext *ctx = SuppressionContext::Get();
+ return ctx->HasSuppressionType(SuppressionInterceptorViaFunction) ||
+ ctx->HasSuppressionType(SuppressionInterceptorViaLibrary);
+}
+
+bool IsStackTraceSuppressed(const StackTrace *stack) {
+ CHECK(suppressions_inited);
+ if (!HaveStackTraceBasedSuppressions())
+ return false;
+
+ SuppressionContext *ctx = SuppressionContext::Get();
+ Symbolizer *symbolizer = Symbolizer::GetOrInit();
+ Suppression *s;
+ for (uptr i = 0; i < stack->size && stack->trace[i]; i++) {
+ uptr addr = stack->trace[i];
+
+ if (ctx->HasSuppressionType(SuppressionInterceptorViaLibrary)) {
+ const char *module_name;
+ uptr module_offset;
+ // Match "interceptor_via_lib" suppressions.
+ if (symbolizer->GetModuleNameAndOffsetForPC(addr, &module_name,
+ &module_offset) &&
+ ctx->Match(module_name, SuppressionInterceptorViaLibrary, &s)) {
+ return true;
+ }
+ }
+
+ if (ctx->HasSuppressionType(SuppressionInterceptorViaFunction)) {
+ SymbolizedStack *frames = symbolizer->SymbolizePC(addr);
+ for (SymbolizedStack *cur = frames; cur; cur = cur->next) {
+ const char *function_name = cur->info.function;
+ if (!function_name) {
+ continue;
+ }
+ // Match "interceptor_via_fun" suppressions.
+ if (ctx->Match(function_name, SuppressionInterceptorViaFunction, &s)) {
+ frames->ClearAll();
+ return true;
+ }
+ }
+ frames->ClearAll();
+ }
+ }
+ return false;
+}
+
+} // namespace __asan
Added: compiler-rt/trunk/lib/asan/asan_suppressions.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_suppressions.h?rev=223508&view=auto
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_suppressions.h (added)
+++ compiler-rt/trunk/lib/asan/asan_suppressions.h Fri Dec 5 14:26:09 2014
@@ -0,0 +1,29 @@
+//===-- asan_suppressions.h -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of AddressSanitizer, an address sanity checker.
+//
+// ASan-private header for asan_suppressions.cc.
+//===----------------------------------------------------------------------===//
+#ifndef ASAN_SUPPRESSIONS_H
+#define ASAN_SUPPRESSIONS_H
+
+#include "asan_internal.h"
+#include "sanitizer_common/sanitizer_stacktrace.h"
+
+namespace __asan {
+
+void InitializeSuppressions();
+bool IsInterceptorSuppressed(const char *interceptor_name);
+bool HaveStackTraceBasedSuppressions();
+bool IsStackTraceSuppressed(const StackTrace *stack);
+
+} // namespace __asan
+
+#endif // ASAN_SUPPRESSIONS_H
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.cc?rev=223508&r1=223507&r2=223508&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.cc Fri Dec 5 14:26:09 2014
@@ -22,8 +22,9 @@
namespace __sanitizer {
static const char *const kTypeStrings[SuppressionTypeCount] = {
- "none", "race", "mutex", "thread", "signal",
- "leak", "called_from_lib", "deadlock", "vptr_check"};
+ "none", "race", "mutex", "thread", "signal", "leak", "called_from_lib",
+ "deadlock", "vptr_check", "interceptor_name", "interceptor_via_fun",
+ "interceptor_via_lib"};
bool TemplateMatch(char *templ, const char *str) {
if (str == 0 || str[0] == 0)
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.h?rev=223508&r1=223507&r2=223508&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_suppressions.h Fri Dec 5 14:26:09 2014
@@ -28,6 +28,9 @@ enum SuppressionType {
SuppressionLib,
SuppressionDeadlock,
SuppressionVptrCheck,
+ SuppressionInterceptorName,
+ SuppressionInterceptorViaFunction,
+ SuppressionInterceptorViaLibrary,
SuppressionTypeCount
};
Modified: compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_suppressions_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_suppressions_test.cc?rev=223508&r1=223507&r2=223508&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_suppressions_test.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_suppressions_test.cc Fri Dec 5 14:26:09 2014
@@ -71,8 +71,16 @@ TEST(Suppressions, TypeStrings) {
!internal_strcmp(SuppressionTypeString(SuppressionDeadlock), "deadlock"));
CHECK(!internal_strcmp(SuppressionTypeString(SuppressionVptrCheck),
"vptr_check"));
+ CHECK(!internal_strcmp(SuppressionTypeString(SuppressionInterceptorName),
+ "interceptor_name"));
+ CHECK(
+ !internal_strcmp(SuppressionTypeString(SuppressionInterceptorViaFunction),
+ "interceptor_via_fun"));
+ CHECK(
+ !internal_strcmp(SuppressionTypeString(SuppressionInterceptorViaLibrary),
+ "interceptor_via_lib"));
// Ensure this test is up-to-date when suppression types are added.
- CHECK_EQ(9, SuppressionTypeCount);
+ CHECK_EQ(12, SuppressionTypeCount);
}
class SuppressionContextTest : public ::testing::Test {
Added: compiler-rt/trunk/test/asan/TestCases/Darwin/suppressions-darwin.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Darwin/suppressions-darwin.cc?rev=223508&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Darwin/suppressions-darwin.cc (added)
+++ compiler-rt/trunk/test/asan/TestCases/Darwin/suppressions-darwin.cc Fri Dec 5 14:26:09 2014
@@ -0,0 +1,34 @@
+// Check that without suppressions, we catch the issue.
+// RUN: %clangxx_asan -O0 %s -o %t -framework Foundation
+// RUN: not %run %t 2>&1 | FileCheck --check-prefix=CHECK-CRASH %s
+
+// Check that suppressing the interceptor by name works.
+// RUN: echo "interceptor_name:memmove" > %t.supp
+// RUN: ASAN_OPTIONS=suppressions=%t.supp %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
+
+// Check that suppressing by interceptor name works even without the symbolizer
+// RUN: ASAN_OPTIONS=suppressions=%t.supp:symbolize=false %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
+
+// Check that suppressing all reports from a library works.
+// RUN: echo "interceptor_via_lib:CoreFoundation" > %t.supp
+// RUN: ASAN_OPTIONS=suppressions=%t.supp %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
+
+// Check that suppressing library works even without the symbolizer.
+// RUN: ASAN_OPTIONS=suppressions=%t.supp:symbolize=false %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
+
+#include <CoreFoundation/CoreFoundation.h>
+
+int main() {
+ char *a = (char *)malloc(6);
+ strcpy(a, "hello");
+ CFStringRef str =
+ CFStringCreateWithBytes(kCFAllocatorDefault, (unsigned char *)a, 10,
+ kCFStringEncodingUTF8, FALSE); // BOOM
+ fprintf(stderr, "Ignored.\n");
+ free(a);
+}
+
+// CHECK-CRASH: AddressSanitizer: heap-buffer-overflow
+// CHECK-CRASH-NOT: Ignored.
+// CHECK-IGNORE-NOT: AddressSanitizer: heap-buffer-overflow
+// CHECK-IGNORE: Ignored.
Added: compiler-rt/trunk/test/asan/TestCases/suppressions-function.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/suppressions-function.cc?rev=223508&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/suppressions-function.cc (added)
+++ compiler-rt/trunk/test/asan/TestCases/suppressions-function.cc Fri Dec 5 14:26:09 2014
@@ -0,0 +1,27 @@
+// Check that without suppressions, we catch the issue.
+// RUN: %clangxx_asan -O0 %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck --check-prefix=CHECK-CRASH %s
+
+// RUN: echo "interceptor_via_fun:crash_function" > %t.supp
+// RUN: %clangxx_asan -O0 %s -o %t && ASAN_OPTIONS=suppressions=%t.supp %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
+// RUN: %clangxx_asan -O3 %s -o %t && ASAN_OPTIONS=suppressions=%t.supp %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+void crash_function() {
+ char *a = (char *)malloc(6);
+ free(a);
+ size_t len = strlen(a); // BOOM
+ fprintf(stderr, "strlen ignored, len = %zu\n", len);
+}
+
+int main() {
+ crash_function();
+}
+
+// CHECK-CRASH: AddressSanitizer: heap-use-after-free
+// CHECK-CRASH-NOT: strlen ignored
+// CHECK-IGNORE-NOT: AddressSanitizer: heap-use-after-free
+// CHECK-IGNORE: strlen ignored
Added: compiler-rt/trunk/test/asan/TestCases/suppressions-interceptor.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/suppressions-interceptor.cc?rev=223508&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/suppressions-interceptor.cc (added)
+++ compiler-rt/trunk/test/asan/TestCases/suppressions-interceptor.cc Fri Dec 5 14:26:09 2014
@@ -0,0 +1,22 @@
+// Check that without suppressions, we catch the issue.
+// RUN: %clangxx_asan -O0 %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck --check-prefix=CHECK-CRASH %s
+
+// RUN: echo "interceptor_name:strlen" > %t.supp
+// RUN: ASAN_OPTIONS=suppressions=%t.supp %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int main() {
+ char *a = (char *)malloc(6);
+ free(a);
+ size_t len = strlen(a); // BOOM
+ fprintf(stderr, "strlen ignored, len = %zu\n", len);
+}
+
+// CHECK-CRASH: AddressSanitizer: heap-use-after-free
+// CHECK-CRASH-NOT: strlen ignored
+// CHECK-IGNORE-NOT: AddressSanitizer: heap-use-after-free
+// CHECK-IGNORE: strlen ignored
Added: compiler-rt/trunk/test/asan/TestCases/suppressions-library.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/suppressions-library.cc?rev=223508&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/suppressions-library.cc (added)
+++ compiler-rt/trunk/test/asan/TestCases/suppressions-library.cc Fri Dec 5 14:26:09 2014
@@ -0,0 +1,37 @@
+// RUN: %clangxx_asan -O0 -DSHARED_LIB %s -fPIC -shared -o %t-so.so
+// RUN: %clangxx_asan -O0 %s %t-so.so -o %t
+
+// Check that without suppressions, we catch the issue.
+// RUN: not %run %t 2>&1 | FileCheck --check-prefix=CHECK-CRASH %s
+
+// RUN: echo "interceptor_via_lib:%t-so.so" > %t.supp
+// RUN: ASAN_OPTIONS=suppressions=%t.supp %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if !defined(SHARED_LIB)
+
+void crash_function();
+
+int main(int argc, char *argv[]) {
+ crash_function();
+ return 0;
+}
+
+#else // SHARED_LIB
+
+void crash_function() {
+ char *a = (char *)malloc(6);
+ free(a);
+ size_t len = strlen(a); // BOOM
+ fprintf(stderr, "strlen ignored, %zu\n", len);
+}
+
+#endif // SHARED_LIB
+
+// CHECK-CRASH: AddressSanitizer: heap-use-after-free
+// CHECK-CRASH-NOT: strlen ignored
+// CHECK-IGNORE-NOT: AddressSanitizer: heap-use-after-free
+// CHECK-IGNORE: strlen ignored
More information about the llvm-commits
mailing list