[sanitizer] More interceptors.
bcopy
strtoimax, strtoumax
mbstowcs, mbsrtowcs, mbsnrtowcs
wcstombs, wcsrtombs, wcsnrtombs
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@185624 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/msan/msan_interceptors.cc b/lib/msan/msan_interceptors.cc
index 854e826..13d1033 100644
--- a/lib/msan/msan_interceptors.cc
+++ b/lib/msan/msan_interceptors.cc
@@ -119,6 +119,10 @@
return __msan_memset(s, c, n);
}
+INTERCEPTOR(void *, bcopy, const void *src, void *dest, SIZE_T n) {
+ return __msan_memmove(dest, src, n);
+}
+
INTERCEPTOR(int, posix_memalign, void **memptr, SIZE_T alignment, SIZE_T size) {
GET_MALLOC_STACK_TRACE;
CHECK_EQ(alignment & (alignment - 1), 0);
@@ -394,21 +398,6 @@
return res;
}
-INTERCEPTOR(SIZE_T, wcstombs, void *dest, void *src, SIZE_T size) {
- ENSURE_MSAN_INITED();
- SIZE_T res = REAL(wcstombs)(dest, src, size);
- if (res != (SIZE_T)-1) __msan_unpoison(dest, res + 1);
- return res;
-}
-
-// SIZE_T mbstowcs(wchar_t *dest, const char *src, SIZE_T n);
-INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T n) {
- ENSURE_MSAN_INITED();
- SIZE_T res = REAL(mbstowcs)(dest, src, n);
- if (res != (SIZE_T)-1) __msan_unpoison(dest, (res + 1) * sizeof(wchar_t));
- return res;
-}
-
INTERCEPTOR(int, mbtowc, wchar_t *dest, const char *src, SIZE_T n) {
ENSURE_MSAN_INITED();
int res = REAL(mbtowc)(dest, src, n);
@@ -1157,6 +1146,7 @@
INTERCEPT_FUNCTION(mempcpy);
INTERCEPT_FUNCTION(memset);
INTERCEPT_FUNCTION(memmove);
+ INTERCEPT_FUNCTION(bcopy);
INTERCEPT_FUNCTION(wmemset);
INTERCEPT_FUNCTION(wmemcpy);
INTERCEPT_FUNCTION(wmempcpy);
@@ -1189,8 +1179,6 @@
INTERCEPT_FUNCTION(snprintf);
INTERCEPT_FUNCTION(swprintf);
INTERCEPT_FUNCTION(strftime);
- INTERCEPT_FUNCTION(wcstombs);
- INTERCEPT_FUNCTION(mbstowcs);
INTERCEPT_FUNCTION(mbtowc);
INTERCEPT_FUNCTION(mbrtowc);
INTERCEPT_FUNCTION(wcslen);
diff --git a/lib/msan/tests/msan_test.cc b/lib/msan/tests/msan_test.cc
index a6095d1..a400b16 100644
--- a/lib/msan/tests/msan_test.cc
+++ b/lib/msan/tests/msan_test.cc
@@ -19,6 +19,7 @@
#include "sanitizer/msan_interface.h"
#include "msandr_test_so.h"
+#include <inttypes.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
@@ -958,6 +959,16 @@
EXPECT_POISONED(y[1]);
}
+TEST(MemorySanitizer, bcopy) {
+ char* x = new char[2];
+ char* y = new char[2];
+ x[0] = 1;
+ x[1] = *GetPoisoned<char>();
+ bcopy(x, y, 2);
+ EXPECT_NOT_POISONED(y[0]);
+ EXPECT_POISONED(y[1]);
+}
+
TEST(MemorySanitizer, strdup) {
char buf[4] = "abc";
__msan_poison(buf + 2, sizeof(*buf));
@@ -1077,6 +1088,18 @@
EXPECT_NOT_POISONED((S8) e);
}
+TEST(MemorySanitizer, strtoimax) {
+ char *e;
+ assert(1 == strtoimax("1", &e, 10));
+ EXPECT_NOT_POISONED((S8) e);
+}
+
+TEST(MemorySanitizer, strtoumax) {
+ char *e;
+ assert(1 == strtoumax("1", &e, 10));
+ EXPECT_NOT_POISONED((S8) e);
+}
+
TEST(MemorySanitizer, strtod) {
char *e;
assert(0 != strtod("1.5", &e));
@@ -1180,6 +1203,30 @@
EXPECT_EQ(buff[2], 'c');
}
+TEST(MemorySanitizer, wcsrtombs) {
+ const wchar_t *x = L"abc";
+ const wchar_t *p = x;
+ char buff[10];
+ mbstate_t mbs;
+ int res = wcsrtombs(buff, &p, 4, &mbs);
+ EXPECT_EQ(res, 3);
+ EXPECT_EQ(buff[0], 'a');
+ EXPECT_EQ(buff[1], 'b');
+ EXPECT_EQ(buff[2], 'c');
+}
+
+TEST(MemorySanitizer, wcsnrtombs) {
+ const wchar_t *x = L"abc";
+ const wchar_t *p = x;
+ char buff[10];
+ mbstate_t mbs;
+ int res = wcsnrtombs(buff, &p, 2, 4, &mbs);
+ EXPECT_EQ(res, 2);
+ EXPECT_EQ(buff[0], 'a');
+ EXPECT_EQ(buff[1], 'b');
+ EXPECT_EQ(buff[2], 0);
+}
+
TEST(MemorySanitizer, mbtowc) {
const char *x = "abc";
wchar_t wx;
diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc b/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 1616767..762fe8e 100644
--- a/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -1440,6 +1440,132 @@
#define INIT_GET_CURRENT_DIR_NAME
#endif
+#if SANITIZER_INTERCEPT_STRTOIMAX
+INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base);
+ INTMAX_T res = REAL(strtoimax)(nptr, endptr, base);
+ if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr));
+ return res;
+}
+
+INTERCEPTOR(INTMAX_T, strtoumax, const char *nptr, char **endptr, int base) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base);
+ INTMAX_T res = REAL(strtoumax)(nptr, endptr, base);
+ if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr));
+ return res;
+}
+
+#define INIT_STRTOIMAX \
+ INTERCEPT_FUNCTION(strtoimax); \
+ INTERCEPT_FUNCTION(strtoumax);
+#else
+#define INIT_STRTOIMAX
+#endif
+
+#if SANITIZER_INTERCEPT_MBSTOWCS
+INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len);
+ SIZE_T res = REAL(mbstowcs)(dest, src, len);
+ if (res != (SIZE_T) - 1 && dest)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, (res + 1) * sizeof(wchar_t));
+ return res;
+}
+
+INTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len,
+ void *ps) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps);
+ if (src) {
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
+ }
+ SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps);
+ if (res != (SIZE_T) - 1 && dest)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, (res + 1) * sizeof(wchar_t));
+ return res;
+}
+
+#define INIT_MBSTOWCS \
+ INTERCEPT_FUNCTION(mbstowcs); \
+ INTERCEPT_FUNCTION(mbsrtowcs);
+#else
+#define INIT_MBSTOWCS
+#endif
+
+#if SANITIZER_INTERCEPT_MBSNRTOWCS
+
+INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms,
+ SIZE_T len, void *ps) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps);
+ if (src) {
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
+ if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
+ }
+ SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps);
+ if (res != (SIZE_T) - 1 && dest)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, (res + 1) * sizeof(wchar_t));
+ return res;
+}
+
+#define INIT_MBSNRTOWCS INTERCEPT_FUNCTION(mbsnrtowcs);
+#else
+#define INIT_MBSNRTOWCS
+#endif
+
+#if SANITIZER_INTERCEPT_WCSTOMBS
+INTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len);
+ SIZE_T res = REAL(wcstombs)(dest, src, len);
+ if (res != (SIZE_T) - 1 && dest)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res + 1);
+ return res;
+}
+
+INTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len,
+ void *ps) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps);
+ if (src) {
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
+ }
+ SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps);
+ if (res != (SIZE_T) - 1 && dest)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res + 1);
+ return res;
+}
+
+#define INIT_WCSTOMBS \
+ INTERCEPT_FUNCTION(wcstombs); \
+ INTERCEPT_FUNCTION(wcsrtombs);
+#else
+#define INIT_WCSTOMBS
+#endif
+
+#if SANITIZER_INTERCEPT_WCSNRTOMBS
+
+INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms,
+ SIZE_T len, void *ps) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps);
+ if (src) {
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
+ if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
+ }
+ SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps);
+ if (res != (SIZE_T) - 1 && dest)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res + 1);
+ return res;
+}
+
+#define INIT_WCSNRTOMBS INTERCEPT_FUNCTION(wcsnrtombs);
+#else
+#define INIT_WCSNRTOMBS
+#endif
+
#define SANITIZER_COMMON_INTERCEPTORS_INIT \
INIT_STRCASECMP; \
INIT_STRNCASECMP; \
@@ -1488,4 +1614,9 @@
INIT_PTRACE; \
INIT_SETLOCALE; \
INIT_GETCWD; \
- INIT_GET_CURRENT_DIR_NAME;
+ INIT_GET_CURRENT_DIR_NAME; \
+ INIT_STRTOIMAX; \
+ INIT_MBSTOWCS; \
+ INIT_MBSNRTOWCS; \
+ INIT_WCSTOMBS; \
+ INIT_WCSNRTOMBS;
diff --git a/lib/sanitizer_common/sanitizer_platform_interceptors.h b/lib/sanitizer_common/sanitizer_platform_interceptors.h
index 5d82dd1..fcdcd9b 100644
--- a/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -99,5 +99,10 @@
# define SANITIZER_INTERCEPT_SETLOCALE SI_NOT_WINDOWS
# define SANITIZER_INTERCEPT_GETCWD SI_NOT_WINDOWS
# define SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME SI_LINUX
+# define SANITIZER_INTERCEPT_STRTOIMAX SI_NOT_WINDOWS
+# define SANITIZER_INTERCEPT_MBSTOWCS SI_NOT_WINDOWS
+# define SANITIZER_INTERCEPT_MBSNRTOWCS SI_MAC || SI_LINUX_NOT_ANDROID
+# define SANITIZER_INTERCEPT_WCSTOMBS SI_NOT_WINDOWS
+# define SANITIZER_INTERCEPT_WCSNRTOMBS SI_MAC || SI_LINUX_NOT_ANDROID
#endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H
diff --git a/lib/tsan/rtl/tsan_stat.cc b/lib/tsan/rtl/tsan_stat.cc
index 5982180..76fee33 100644
--- a/lib/tsan/rtl/tsan_stat.cc
+++ b/lib/tsan/rtl/tsan_stat.cc
@@ -340,6 +340,14 @@
name[StatInt_setlocale] = " setlocale ";
name[StatInt_getcwd] = " getcwd ";
name[StatInt_get_current_dir_name] = " get_current_dir_name ";
+ name[StatInt_strtoimax] = " strtoimax ";
+ name[StatInt_strtoumax] = " strtoumax ";
+ name[StatInt_mbstowcs] = " mbstowcs ";
+ name[StatInt_mbsrtowcs] = " mbsrtowcs ";
+ name[StatInt_mbsnrtowcs] = " mbsnrtowcs ";
+ name[StatInt_wcstombs] = " wcstombs ";
+ name[StatInt_wcsrtombs] = " wcsrtombs ";
+ name[StatInt_wcsnrtombs] = " wcsnrtombs ";
name[StatAnnotation] = "Dynamic annotations ";
name[StatAnnotateHappensBefore] = " HappensBefore ";
diff --git a/lib/tsan/rtl/tsan_stat.h b/lib/tsan/rtl/tsan_stat.h
index 1bef6e9..10af377 100644
--- a/lib/tsan/rtl/tsan_stat.h
+++ b/lib/tsan/rtl/tsan_stat.h
@@ -335,6 +335,14 @@
StatInt_setlocale,
StatInt_getcwd,
StatInt_get_current_dir_name,
+ StatInt_strtoimax,
+ StatInt_strtoumax,
+ StatInt_mbstowcs,
+ StatInt_mbsrtowcs,
+ StatInt_mbsnrtowcs,
+ StatInt_wcstombs,
+ StatInt_wcsrtombs,
+ StatInt_wcsnrtombs,
// Dynamic annotations.
StatAnnotation,