forked from OSchip/llvm-project
[Sanitizer] move strcpy and strncpy to common interceptors
llvm-svn: 186408
This commit is contained in:
parent
ab29d19536
commit
9916aa2d95
|
@ -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);
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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; \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue