summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Samsonov <samsonov@google.com>2013-07-16 12:51:53 +0000
committerAlexey Samsonov <samsonov@google.com>2013-07-16 12:51:53 +0000
commit67505a8a0cf9621243ed21b67dfa041224c78e4b (patch)
tree565c336ae94f87da18bdf70095eebe01c8c2bc62
parentb6bde4d2bc5231cd1b38ff92e51afb3f6e157386 (diff)
downloadcompiler-rt-67505a8a0cf9621243ed21b67dfa041224c78e4b.tar.gz
compiler-rt-67505a8a0cf9621243ed21b67dfa041224c78e4b.tar.bz2
compiler-rt-67505a8a0cf9621243ed21b67dfa041224c78e4b.tar.xz
[Sanitizer] move strcpy and strncpy to common interceptors
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@186408 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/asan/asan_interceptors.cc40
-rw-r--r--lib/msan/tests/msan_test.cc14
-rw-r--r--lib/sanitizer_common/sanitizer_common_interceptors.inc44
-rw-r--r--lib/sanitizer_common/sanitizer_platform_interceptors.h1
-rw-r--r--lib/tsan/rtl/tsan_interceptors.cc26
5 files changed, 59 insertions, 66 deletions
diff --git a/lib/asan/asan_interceptors.cc b/lib/asan/asan_interceptors.cc
index 124bd3bc..10b3778b 100644
--- a/lib/asan/asan_interceptors.cc
+++ b/lib/asan/asan_interceptors.cc
@@ -432,24 +432,6 @@ INTERCEPTOR(char*, strncat, char *to, const char *from, uptr size) {
return REAL(strncat)(to, from, size);
}
-INTERCEPTOR(int, strcmp, const char *s1, const char *s2) {
- if (!asan_inited) return internal_strcmp(s1, s2);
- if (asan_init_is_running) {
- return REAL(strcmp)(s1, s2);
- }
- ENSURE_ASAN_INITED();
- unsigned char c1, c2;
- uptr i;
- for (i = 0; ; i++) {
- c1 = (unsigned char)s1[i];
- c2 = (unsigned char)s2[i];
- if (c1 != c2 || c1 == '\0') break;
- }
- ASAN_READ_RANGE(s1, i + 1);
- ASAN_READ_RANGE(s2, i + 1);
- return CharCmp(c1, c2);
-}
-
INTERCEPTOR(char*, strcpy, char *to, const char *from) { // NOLINT
#if SANITIZER_MAC
if (!asan_inited) return REAL(strcpy)(to, from); // NOLINT
@@ -499,26 +481,6 @@ INTERCEPTOR(uptr, strlen, const char *s) {
return length;
}
-INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) {
- if (!asan_inited) return internal_strncmp(s1, s2, size);
- // strncmp is called from malloc_default_purgeable_zone()
- // in __asan::ReplaceSystemAlloc() on Mac.
- if (asan_init_is_running) {
- return REAL(strncmp)(s1, s2, size);
- }
- ENSURE_ASAN_INITED();
- unsigned char c1 = 0, c2 = 0;
- uptr i;
- for (i = 0; i < size; i++) {
- c1 = (unsigned char)s1[i];
- c2 = (unsigned char)s2[i];
- if (c1 != c2 || c1 == '\0') break;
- }
- ASAN_READ_RANGE(s1, Min(i + 1, size));
- ASAN_READ_RANGE(s2, Min(i + 1, size));
- return CharCmp(c1, c2);
-}
-
INTERCEPTOR(char*, strncpy, char *to, const char *from, uptr size) {
ENSURE_ASAN_INITED();
if (flags()->replace_str) {
@@ -715,11 +677,9 @@ void InitializeAsanInterceptors() {
// Intercept str* functions.
ASAN_INTERCEPT_FUNC(strcat); // NOLINT
ASAN_INTERCEPT_FUNC(strchr);
- ASAN_INTERCEPT_FUNC(strcmp);
ASAN_INTERCEPT_FUNC(strcpy); // NOLINT
ASAN_INTERCEPT_FUNC(strlen);
ASAN_INTERCEPT_FUNC(strncat);
- ASAN_INTERCEPT_FUNC(strncmp);
ASAN_INTERCEPT_FUNC(strncpy);
#if ASAN_INTERCEPT_STRDUP
ASAN_INTERCEPT_FUNC(strdup);
diff --git a/lib/msan/tests/msan_test.cc b/lib/msan/tests/msan_test.cc
index fe75d359..a13f05d9 100644
--- a/lib/msan/tests/msan_test.cc
+++ b/lib/msan/tests/msan_test.cc
@@ -524,6 +524,20 @@ LargeStruct LargeRetTest() {
return res;
}
+TEST(MemorySanitizer, strcmp) {
+ char s1[10];
+ char s2[10];
+ strncpy(s1, "foo", 10);
+ s2[0] = 'f';
+ s2[1] = 'n';
+ EXPECT_GT(strcmp(s1, s2), 0);
+ s2[1] = 'o';
+ int res;
+ EXPECT_UMR(res = strcmp(s1, s2));
+ EXPECT_NOT_POISONED(res);
+ EXPECT_EQ(strncmp(s1, s2, 1), 0);
+}
+
TEST(MemorySanitizer, LargeRet) {
LargeStruct a = LargeRetTest();
EXPECT_POISONED(a.x[0]);
diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc b/lib/sanitizer_common/sanitizer_common_interceptors.inc
index e63c2dfc..e48b3922 100644
--- a/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -28,6 +28,48 @@
#define va_copy(dst, src) ((dst) = (src))
#endif // _WIN32
+#if SANITIZER_INTERCEPT_STRCMP
+static inline int CharCmpX(unsigned char c1, unsigned char c2) {
+ return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
+}
+
+INTERCEPTOR(int, strcmp, const char *s1, const char *s2) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strcmp, s1, s2);
+ unsigned char c1, c2;
+ uptr i;
+ for (i = 0; ; i++) {
+ c1 = (unsigned char)s1[i];
+ c2 = (unsigned char)s2[i];
+ if (c1 != c2 || c1 == '\0') break;
+ }
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, i + 1);
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, i + 1);
+ return CharCmpX(c1, c2);
+}
+
+INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strncmp, s1, s2, size);
+ unsigned char c1 = 0, c2 = 0;
+ uptr i;
+ for (i = 0; i < size; i++) {
+ c1 = (unsigned char)s1[i];
+ c2 = (unsigned char)s2[i];
+ if (c1 != c2 || c1 == '\0') break;
+ }
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size));
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size));
+ return CharCmpX(c1, c2);
+}
+
+#define INIT_STRCMP INTERCEPT_FUNCTION(strcmp)
+#define INIT_STRNCMP INTERCEPT_FUNCTION(strncmp)
+#else
+#define INIT_STRCMP
+#define INIT_STRNCMP
+#endif
+
#if SANITIZER_INTERCEPT_STRCASECMP
static inline int CharCaseCmp(unsigned char c1, unsigned char c2) {
int c1_low = ToLower(c1);
@@ -1706,6 +1748,8 @@ INTERCEPTOR(char *, canonicalize_file_name, const char *path) {
#endif
#define SANITIZER_COMMON_INTERCEPTORS_INIT \
+ INIT_STRCMP; \
+ INIT_STRNCMP; \
INIT_STRCASECMP; \
INIT_STRNCASECMP; \
INIT_READ; \
diff --git a/lib/sanitizer_common/sanitizer_platform_interceptors.h b/lib/sanitizer_common/sanitizer_platform_interceptors.h
index 0b98d3a6..e07a134e 100644
--- a/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -41,6 +41,7 @@
# define SI_MAC 0
#endif
+# define SANITIZER_INTERCEPT_STRCMP 1
# define SANITIZER_INTERCEPT_STRCASECMP SI_NOT_WINDOWS
# define SANITIZER_INTERCEPT_READ SI_NOT_WINDOWS
diff --git a/lib/tsan/rtl/tsan_interceptors.cc b/lib/tsan/rtl/tsan_interceptors.cc
index 92d8ae19..936a2150 100644
--- a/lib/tsan/rtl/tsan_interceptors.cc
+++ b/lib/tsan/rtl/tsan_interceptors.cc
@@ -590,30 +590,6 @@ TSAN_INTERCEPTOR(int, memcmp, const void *s1, const void *s2, uptr n) {
return res;
}
-TSAN_INTERCEPTOR(int, strcmp, const char *s1, const char *s2) {
- SCOPED_TSAN_INTERCEPTOR(strcmp, s1, s2);
- uptr len = 0;
- for (; s1[len] && s2[len]; len++) {
- if (s1[len] != s2[len])
- break;
- }
- MemoryAccessRange(thr, pc, (uptr)s1, len + 1, false);
- MemoryAccessRange(thr, pc, (uptr)s2, len + 1, false);
- return s1[len] - s2[len];
-}
-
-TSAN_INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr n) {
- SCOPED_TSAN_INTERCEPTOR(strncmp, s1, s2, n);
- uptr len = 0;
- for (; len < n && s1[len] && s2[len]; len++) {
- if (s1[len] != s2[len])
- break;
- }
- MemoryAccessRange(thr, pc, (uptr)s1, len < n ? len + 1 : n, false);
- MemoryAccessRange(thr, pc, (uptr)s2, len < n ? len + 1 : n, false);
- return len == n ? 0 : s1[len] - s2[len];
-}
-
TSAN_INTERCEPTOR(void*, memchr, void *s, int c, uptr n) {
SCOPED_TSAN_INTERCEPTOR(memchr, s, c, n);
void *res = REAL(memchr)(s, c, n);
@@ -1957,7 +1933,6 @@ void InitializeInterceptors() {
TSAN_INTERCEPT(strlen);
TSAN_INTERCEPT(memset);
TSAN_INTERCEPT(memcpy);
- TSAN_INTERCEPT(strcmp);
TSAN_INTERCEPT(memchr);
TSAN_INTERCEPT(memrchr);
TSAN_INTERCEPT(memmove);
@@ -1965,7 +1940,6 @@ void InitializeInterceptors() {
TSAN_INTERCEPT(strchr);
TSAN_INTERCEPT(strchrnul);
TSAN_INTERCEPT(strrchr);
- TSAN_INTERCEPT(strncmp);
TSAN_INTERCEPT(strcpy); // NOLINT
TSAN_INTERCEPT(strncpy);
TSAN_INTERCEPT(strstr);