summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/asan/asan_interceptors.cc11
-rw-r--r--lib/msan/msan_interceptors.cc82
-rw-r--r--lib/msan/tests/msan_test.cc42
-rw-r--r--lib/sanitizer_common/sanitizer_common_interceptors.inc77
-rw-r--r--lib/sanitizer_common/sanitizer_platform_interceptors.h2
5 files changed, 145 insertions, 69 deletions
diff --git a/lib/asan/asan_interceptors.cc b/lib/asan/asan_interceptors.cc
index 264d5aee8..e03c0f94c 100644
--- a/lib/asan/asan_interceptors.cc
+++ b/lib/asan/asan_interceptors.cc
@@ -579,17 +579,6 @@ INTERCEPTOR(char*, __strdup, const char *s) {
}
#endif // ASAN_INTERCEPT___STRDUP
-INTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) {
- void *ctx;
- ASAN_INTERCEPTOR_ENTER(ctx, wcslen);
- SIZE_T length = internal_wcslen(s);
- if (!asan_init_is_running) {
- ENSURE_ASAN_INITED();
- 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);
diff --git a/lib/msan/msan_interceptors.cc b/lib/msan/msan_interceptors.cc
index 0f5069344..ce8444a3b 100644
--- a/lib/msan/msan_interceptors.cc
+++ b/lib/msan/msan_interceptors.cc
@@ -538,49 +538,6 @@ INTERCEPTOR(int, mbrtowc, wchar_t *dest, const char *src, SIZE_T n, void *ps) {
return res;
}
-INTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) {
- ENSURE_MSAN_INITED();
- SIZE_T res = REAL(wcslen)(s);
- CHECK_UNPOISONED(s, sizeof(wchar_t) * (res + 1));
- return res;
-}
-
-INTERCEPTOR(SIZE_T, wcsnlen, const wchar_t *s, SIZE_T n) {
- ENSURE_MSAN_INITED();
- SIZE_T res = REAL(wcsnlen)(s, n);
- CHECK_UNPOISONED(s, sizeof(wchar_t) * Min(res + 1, n));
- return res;
-}
-
-// wchar_t *wcschr(const wchar_t *wcs, wchar_t wc);
-INTERCEPTOR(wchar_t *, wcschr, void *s, wchar_t wc, void *ps) {
- ENSURE_MSAN_INITED();
- wchar_t *res = REAL(wcschr)(s, wc, ps);
- return res;
-}
-
-// wchar_t *wcscpy(wchar_t *dest, const wchar_t *src);
-INTERCEPTOR(wchar_t *, wcscpy, wchar_t *dest, const wchar_t *src) {
- ENSURE_MSAN_INITED();
- GET_STORE_STACK_TRACE;
- wchar_t *res = REAL(wcscpy)(dest, src);
- CopyShadowAndOrigin(dest, src, sizeof(wchar_t) * (REAL(wcslen)(src) + 1),
- &stack);
- return res;
-}
-
-INTERCEPTOR(wchar_t *, wcsncpy, wchar_t *dest, const wchar_t *src,
- SIZE_T n) { // NOLINT
- ENSURE_MSAN_INITED();
- GET_STORE_STACK_TRACE;
- SIZE_T copy_size = REAL(wcsnlen)(src, n);
- if (copy_size < n) copy_size++; // trailing \0
- wchar_t *res = REAL(wcsncpy)(dest, src, n); // NOLINT
- CopyShadowAndOrigin(dest, src, copy_size * sizeof(wchar_t), &stack);
- __msan_unpoison(dest + copy_size, (n - copy_size) * sizeof(wchar_t));
- return res;
-}
-
// wchar_t *wmemcpy(wchar_t *dest, const wchar_t *src, SIZE_T n);
INTERCEPTOR(wchar_t *, wmemcpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {
ENSURE_MSAN_INITED();
@@ -1344,11 +1301,11 @@ int OnExit() {
return __msan_memcpy(to, from, size); \
}
-#define COMMON_INTERCEPTOR_COPY_STRING(ctx, to, from, size) \
- do { \
- GET_STORE_STACK_TRACE; \
- CopyShadowAndOrigin(to, from, size, &stack); \
- __msan_unpoison(to + size, 1); \
+#define COMMON_INTERCEPTOR_COPY_STRING(ctx, to, from, size) \
+ do { \
+ GET_STORE_STACK_TRACE; \
+ CopyShadowAndOrigin(to, from, size, &stack); \
+ __msan_unpoison(to + size, 1); \
} while (false)
#include "sanitizer_common/sanitizer_platform_interceptors.h"
@@ -1424,6 +1381,35 @@ INTERCEPTOR(int, dl_iterate_phdr, dl_iterate_phdr_cb callback, void *data) {
return res;
}
+// wchar_t *wcschr(const wchar_t *wcs, wchar_t wc);
+INTERCEPTOR(wchar_t *, wcschr, void *s, wchar_t wc, void *ps) {
+ ENSURE_MSAN_INITED();
+ wchar_t *res = REAL(wcschr)(s, wc, ps);
+ return res;
+}
+
+// wchar_t *wcscpy(wchar_t *dest, const wchar_t *src);
+INTERCEPTOR(wchar_t *, wcscpy, wchar_t *dest, const wchar_t *src) {
+ ENSURE_MSAN_INITED();
+ GET_STORE_STACK_TRACE;
+ wchar_t *res = REAL(wcscpy)(dest, src);
+ CopyShadowAndOrigin(dest, src, sizeof(wchar_t) * (REAL(wcslen)(src) + 1),
+ &stack);
+ return res;
+}
+
+INTERCEPTOR(wchar_t *, wcsncpy, wchar_t *dest, const wchar_t *src,
+ SIZE_T n) { // NOLINT
+ ENSURE_MSAN_INITED();
+ GET_STORE_STACK_TRACE;
+ SIZE_T copy_size = REAL(wcsnlen)(src, n);
+ if (copy_size < n) copy_size++; // trailing \0
+ wchar_t *res = REAL(wcsncpy)(dest, src, n); // NOLINT
+ CopyShadowAndOrigin(dest, src, copy_size * sizeof(wchar_t), &stack);
+ __msan_unpoison(dest + copy_size, (n - copy_size) * sizeof(wchar_t));
+ return res;
+}
+
// These interface functions reside here so that they can use
// REAL(memset), etc.
void __msan_unpoison(const void *a, uptr size) {
diff --git a/lib/msan/tests/msan_test.cc b/lib/msan/tests/msan_test.cc
index 543a7eb98..b2d5f7c60 100644
--- a/lib/msan/tests/msan_test.cc
+++ b/lib/msan/tests/msan_test.cc
@@ -1707,6 +1707,48 @@ TEST(MemorySanitizer, strncat_overflow) { // NOLINT
EXPECT_POISONED(a[7]);
}
+TEST(MemorySanitizer, wcscat) {
+ wchar_t a[10];
+ wchar_t b[] = L"def";
+ wcscpy(a, L"abc");
+
+ wcscat(a, b);
+ EXPECT_EQ(6U, wcslen(a));
+ EXPECT_POISONED(a[7]);
+
+ a[3] = 0;
+ __msan_poison(b + 1, sizeof(wchar_t));
+ EXPECT_UMR(wcscat(a, b));
+
+ __msan_unpoison(b + 1, sizeof(wchar_t));
+ __msan_poison(a + 2, sizeof(wchar_t));
+ EXPECT_UMR(wcscat(a, b));
+}
+
+TEST(MemorySanitizer, wcsncat) {
+ wchar_t a[10];
+ wchar_t b[] = L"def";
+ wcscpy(a, L"abc");
+
+ wcsncat(a, b, 5);
+ EXPECT_EQ(6U, wcslen(a));
+ EXPECT_POISONED(a[7]);
+
+ a[3] = 0;
+ __msan_poison(a + 4, sizeof(wchar_t) * 6);
+ wcsncat(a, b, 2);
+ EXPECT_EQ(5U, wcslen(a));
+ EXPECT_POISONED(a[6]);
+
+ a[3] = 0;
+ __msan_poison(b + 1, sizeof(wchar_t));
+ EXPECT_UMR(wcsncat(a, b, 2));
+
+ __msan_unpoison(b + 1, sizeof(wchar_t));
+ __msan_poison(a + 2, sizeof(wchar_t));
+ EXPECT_UMR(wcsncat(a, b, 2));
+}
+
#define TEST_STRTO_INT(func_name, char_type, str_prefix) \
TEST(MemorySanitizer, func_name) { \
char_type *e; \
diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc b/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 6ca431d8a..af7de6759 100644
--- a/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -224,16 +224,16 @@ bool PlatformHasDifferentMemcpyAndMemmove();
#endif
#ifndef COMMON_INTERCEPTOR_STRNDUP_IMPL
-#define COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size) \
- COMMON_INTERCEPTOR_ENTER(ctx, strndup, s, size); \
- uptr copy_length = internal_strnlen(s, size); \
- char *new_mem = (char *)WRAP(malloc)(copy_length + 1); \
- if (common_flags()->intercept_strndup) { \
- COMMON_INTERCEPTOR_READ_STRING(ctx, s, Min(size, copy_length + 1)); \
- } \
- COMMON_INTERCEPTOR_COPY_STRING(ctx, new_mem, s, copy_length); \
- internal_memcpy(new_mem, s, copy_length); \
- new_mem[copy_length] = '\0'; \
+#define COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size) \
+ COMMON_INTERCEPTOR_ENTER(ctx, strndup, s, size); \
+ uptr copy_length = internal_strnlen(s, size); \
+ char *new_mem = (char *)WRAP(malloc)(copy_length + 1); \
+ if (common_flags()->intercept_strndup) { \
+ COMMON_INTERCEPTOR_READ_STRING(ctx, s, Min(size, copy_length + 1)); \
+ } \
+ COMMON_INTERCEPTOR_COPY_STRING(ctx, new_mem, s, copy_length); \
+ internal_memcpy(new_mem, s, copy_length); \
+ new_mem[copy_length] = '\0'; \
return new_mem;
#endif
@@ -6199,6 +6199,61 @@ INTERCEPTOR(int, mprobe, void *ptr) {
}
#endif
+#if SANITIZER_INTERCEPT_WCSLEN
+INTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, wcslen, s);
+ SIZE_T res = REAL(wcslen)(s);
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(wchar_t) * (res + 1));
+ return res;
+}
+
+INTERCEPTOR(SIZE_T, wcsnlen, const wchar_t *s, SIZE_T n) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, wcsnlen, s, n);
+ SIZE_T res = REAL(wcsnlen)(s, n);
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(wchar_t) * Min(res + 1, n));
+ return res;
+}
+#define INIT_WCSLEN \
+ COMMON_INTERCEPT_FUNCTION(wcslen); \
+ COMMON_INTERCEPT_FUNCTION(wcsnlen);
+#else
+#define INIT_WCSLEN
+#endif
+
+#if SANITIZER_INTERCEPT_WCSCAT
+INTERCEPTOR(wchar_t *, wcscat, wchar_t *dst, const wchar_t *src) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, wcscat, dst, src);
+ SIZE_T src_size = REAL(wcslen)(src);
+ SIZE_T dst_size = REAL(wcslen)(dst);
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, (src_size + 1) * sizeof(wchar_t));
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, dst, (dst_size + 1) * sizeof(wchar_t));
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst + dst_size,
+ (src_size + 1) * sizeof(wchar_t));
+ return REAL(wcscat)(dst, src); // NOLINT
+}
+
+INTERCEPTOR(wchar_t *, wcsncat, wchar_t *dst, const wchar_t *src, SIZE_T n) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, wcsncat, dst, src, n);
+ SIZE_T src_size = REAL(wcsnlen)(src, n);
+ SIZE_T dst_size = REAL(wcslen)(dst);
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src,
+ Min(src_size + 1, n) * sizeof(wchar_t));
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, dst, (dst_size + 1) * sizeof(wchar_t));
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst + dst_size,
+ (src_size + 1) * sizeof(wchar_t));
+ return REAL(wcsncat)(dst, src, n); // NOLINT
+}
+#define INIT_WCSCAT \
+ COMMON_INTERCEPT_FUNCTION(wcscat); \
+ COMMON_INTERCEPT_FUNCTION(wcsncat);
+#else
+#define INIT_WCSCAT
+#endif
+
static void InitializeCommonInterceptors() {
static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1];
interceptor_metadata_map = new((void *)&metadata_mem) MetadataHashMap();
@@ -6403,4 +6458,6 @@ static void InitializeCommonInterceptors() {
INIT_UTMP;
INIT_UTMPX;
INIT_GETLOADAVG;
+ INIT_WCSLEN;
+ INIT_WCSCAT;
}
diff --git a/lib/sanitizer_common/sanitizer_platform_interceptors.h b/lib/sanitizer_common/sanitizer_platform_interceptors.h
index a95497467..da683c62f 100644
--- a/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -354,5 +354,7 @@
#define SANITIZER_INTERCEPT_ALIGNED_ALLOC (!SI_MAC)
#define SANITIZER_INTERCEPT_MALLOC_USABLE_SIZE (!SI_MAC)
#define SANITIZER_INTERCEPT_MCHECK_MPROBE SI_LINUX_NOT_ANDROID
+#define SANITIZER_INTERCEPT_WCSLEN SI_NOT_WINDOWS
+#define SANITIZER_INTERCEPT_WCSCAT SI_NOT_WINDOWS
#endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H