diff options
author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2017-06-27 22:52:38 +0000 |
---|---|---|
committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2017-06-27 22:52:38 +0000 |
commit | 054ff981e8e285ba623c9255f2ecc52263f0e03a (patch) | |
tree | 2d8c33596e9711851c2d62e45a3042971f38d4fc /lib/msan | |
parent | a8a922c4f3636a58856848406755786e69c6d7a5 (diff) |
[msan] Intercept wcscat, wcsncat.
Also move wcslen, wscnlen to common interceptors.
Reviewers: vitalybuka
Reviewed By: vitalybuka
Subscribers: kubamracek, llvm-commits
Differential Revision: https://reviews.llvm.org/D34656
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@306482 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/msan')
-rw-r--r-- | lib/msan/msan_interceptors.cc | 82 | ||||
-rw-r--r-- | lib/msan/tests/msan_test.cc | 42 |
2 files changed, 76 insertions, 48 deletions
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; \ |