[Sanitizer] move strcpy and strncpy to common interceptors

llvm-svn: 186408
This commit is contained in:
Alexey Samsonov 2013-07-16 12:51:53 +00:00
parent ab29d19536
commit 9916aa2d95
5 changed files with 59 additions and 66 deletions

View File

@ -432,24 +432,6 @@ INTERCEPTOR(char*, strncat, char *to, const char *from, uptr size) {
return REAL(strncat)(to, from, 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 INTERCEPTOR(char*, strcpy, char *to, const char *from) { // NOLINT
#if SANITIZER_MAC #if SANITIZER_MAC
if (!asan_inited) return REAL(strcpy)(to, from); // NOLINT if (!asan_inited) return REAL(strcpy)(to, from); // NOLINT
@ -499,26 +481,6 @@ INTERCEPTOR(uptr, strlen, const char *s) {
return length; 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) { INTERCEPTOR(char*, strncpy, char *to, const char *from, uptr size) {
ENSURE_ASAN_INITED(); ENSURE_ASAN_INITED();
if (flags()->replace_str) { if (flags()->replace_str) {
@ -715,11 +677,9 @@ void InitializeAsanInterceptors() {
// Intercept str* functions. // Intercept str* functions.
ASAN_INTERCEPT_FUNC(strcat); // NOLINT ASAN_INTERCEPT_FUNC(strcat); // NOLINT
ASAN_INTERCEPT_FUNC(strchr); ASAN_INTERCEPT_FUNC(strchr);
ASAN_INTERCEPT_FUNC(strcmp);
ASAN_INTERCEPT_FUNC(strcpy); // NOLINT ASAN_INTERCEPT_FUNC(strcpy); // NOLINT
ASAN_INTERCEPT_FUNC(strlen); ASAN_INTERCEPT_FUNC(strlen);
ASAN_INTERCEPT_FUNC(strncat); ASAN_INTERCEPT_FUNC(strncat);
ASAN_INTERCEPT_FUNC(strncmp);
ASAN_INTERCEPT_FUNC(strncpy); ASAN_INTERCEPT_FUNC(strncpy);
#if ASAN_INTERCEPT_STRDUP #if ASAN_INTERCEPT_STRDUP
ASAN_INTERCEPT_FUNC(strdup); ASAN_INTERCEPT_FUNC(strdup);

View File

@ -524,6 +524,20 @@ LargeStruct LargeRetTest() {
return res; 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) { TEST(MemorySanitizer, LargeRet) {
LargeStruct a = LargeRetTest(); LargeStruct a = LargeRetTest();
EXPECT_POISONED(a.x[0]); EXPECT_POISONED(a.x[0]);

View File

@ -28,6 +28,48 @@
#define va_copy(dst, src) ((dst) = (src)) #define va_copy(dst, src) ((dst) = (src))
#endif // _WIN32 #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 #if SANITIZER_INTERCEPT_STRCASECMP
static inline int CharCaseCmp(unsigned char c1, unsigned char c2) { static inline int CharCaseCmp(unsigned char c1, unsigned char c2) {
int c1_low = ToLower(c1); int c1_low = ToLower(c1);
@ -1706,6 +1748,8 @@ INTERCEPTOR(char *, canonicalize_file_name, const char *path) {
#endif #endif
#define SANITIZER_COMMON_INTERCEPTORS_INIT \ #define SANITIZER_COMMON_INTERCEPTORS_INIT \
INIT_STRCMP; \
INIT_STRNCMP; \
INIT_STRCASECMP; \ INIT_STRCASECMP; \
INIT_STRNCASECMP; \ INIT_STRNCASECMP; \
INIT_READ; \ INIT_READ; \

View File

@ -41,6 +41,7 @@
# define SI_MAC 0 # define SI_MAC 0
#endif #endif
# define SANITIZER_INTERCEPT_STRCMP 1
# define SANITIZER_INTERCEPT_STRCASECMP SI_NOT_WINDOWS # define SANITIZER_INTERCEPT_STRCASECMP SI_NOT_WINDOWS
# define SANITIZER_INTERCEPT_READ SI_NOT_WINDOWS # define SANITIZER_INTERCEPT_READ SI_NOT_WINDOWS

View File

@ -590,30 +590,6 @@ TSAN_INTERCEPTOR(int, memcmp, const void *s1, const void *s2, uptr n) {
return res; 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) { TSAN_INTERCEPTOR(void*, memchr, void *s, int c, uptr n) {
SCOPED_TSAN_INTERCEPTOR(memchr, s, c, n); SCOPED_TSAN_INTERCEPTOR(memchr, s, c, n);
void *res = REAL(memchr)(s, c, n); void *res = REAL(memchr)(s, c, n);
@ -1957,7 +1933,6 @@ void InitializeInterceptors() {
TSAN_INTERCEPT(strlen); TSAN_INTERCEPT(strlen);
TSAN_INTERCEPT(memset); TSAN_INTERCEPT(memset);
TSAN_INTERCEPT(memcpy); TSAN_INTERCEPT(memcpy);
TSAN_INTERCEPT(strcmp);
TSAN_INTERCEPT(memchr); TSAN_INTERCEPT(memchr);
TSAN_INTERCEPT(memrchr); TSAN_INTERCEPT(memrchr);
TSAN_INTERCEPT(memmove); TSAN_INTERCEPT(memmove);
@ -1965,7 +1940,6 @@ void InitializeInterceptors() {
TSAN_INTERCEPT(strchr); TSAN_INTERCEPT(strchr);
TSAN_INTERCEPT(strchrnul); TSAN_INTERCEPT(strchrnul);
TSAN_INTERCEPT(strrchr); TSAN_INTERCEPT(strrchr);
TSAN_INTERCEPT(strncmp);
TSAN_INTERCEPT(strcpy); // NOLINT TSAN_INTERCEPT(strcpy); // NOLINT
TSAN_INTERCEPT(strncpy); TSAN_INTERCEPT(strncpy);
TSAN_INTERCEPT(strstr); TSAN_INTERCEPT(strstr);