From 8717fec9af49d5a2a8930f6b50b09b7f1d74b0db Mon Sep 17 00:00:00 2001 From: Evgeniy Stepanov Date: Tue, 24 Jun 2014 11:50:26 +0000 Subject: [PATCH] [msan] Fix origin copying. Conditions for the first and the last origin value in range were wrong. llvm-svn: 211585 --- compiler-rt/lib/msan/msan_interceptors.cc | 11 ++++---- compiler-rt/lib/msan/tests/msan_test.cc | 31 +++++++++++++++++++++++ 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/compiler-rt/lib/msan/msan_interceptors.cc b/compiler-rt/lib/msan/msan_interceptors.cc index 854c205341ec..c7f41248427e 100644 --- a/compiler-rt/lib/msan/msan_interceptors.cc +++ b/compiler-rt/lib/msan/msan_interceptors.cc @@ -1389,7 +1389,7 @@ void CopyOrigin(void *dst, const void *src, uptr size, StackTrace *stack) { uptr beg = d & ~3UL; // Copy left unaligned origin if that memory is poisoned. if (beg < d) { - u32 o = GetOriginIfPoisoned(beg, d - beg); + u32 o = GetOriginIfPoisoned((uptr)src, d - beg); if (o) { if (__msan_get_track_origins() > 1) o = ChainOrigin(o, stack); *(u32 *)MEM_TO_ORIGIN(beg) = o; @@ -1397,15 +1397,14 @@ void CopyOrigin(void *dst, const void *src, uptr size, StackTrace *stack) { beg += 4; } - uptr end = (d + size + 3) & ~3UL; + uptr end = (d + size) & ~3UL; // Copy right unaligned origin if that memory is poisoned. - if (end > d + size) { - u32 o = GetOriginIfPoisoned(d + size, end - d - size); + if (end < d + size) { + u32 o = GetOriginIfPoisoned((uptr)src + (end - d), (d + size) - end); if (o) { if (__msan_get_track_origins() > 1) o = ChainOrigin(o, stack); - *(u32 *)MEM_TO_ORIGIN(end - 4) = o; + *(u32 *)MEM_TO_ORIGIN(end) = o; } - end -= 4; } if (beg < end) { diff --git a/compiler-rt/lib/msan/tests/msan_test.cc b/compiler-rt/lib/msan/tests/msan_test.cc index 438a74af50f5..53934ff139d9 100644 --- a/compiler-rt/lib/msan/tests/msan_test.cc +++ b/compiler-rt/lib/msan/tests/msan_test.cc @@ -1291,6 +1291,7 @@ TEST(MemorySanitizer, memcpy) { EXPECT_POISONED(y[1]); } +// Dst is poisoned, src is clean. void TestUnalignedMemcpy(int left, int right, bool src_is_aligned) { const int sz = 20; char *dst = (char *)malloc(sz); @@ -1320,6 +1321,36 @@ TEST(MemorySanitizer, memcpy_unaligned) { } } +// Src is poisoned, dst is clean. +void TestUnalignedPoisonedMemcpy(int left, int right, bool src_is_aligned) { + const int sz = 20; + char *dst = (char *)malloc(sz); + memset(dst, 0, sz); + + char *src = (char *)malloc(sz); + U4 origin = __msan_get_origin(src); + + memcpy(dst + left, src_is_aligned ? src + left : src, sz - left - right); + for (int i = 0; i < left; ++i) + EXPECT_NOT_POISONED(dst[i]); + for (int i = 0; i < right; ++i) + EXPECT_NOT_POISONED(dst[sz - i - 1]); + EXPECT_POISONED_O(dst[left], origin); + EXPECT_POISONED_O(dst[sz - right - 1], origin); + + free(dst); + free(src); +} + +TEST(MemorySanitizer, memcpy_unaligned_poisoned) { + for (int i = 0; i < 10; ++i) { + for (int j = 0; j < 10; ++j) { + TestUnalignedPoisonedMemcpy(i, j, true); + TestUnalignedPoisonedMemcpy(i, j, false); + } + } +} + TEST(MemorySanitizer, memmove) { char* x = new char[2]; char* y = new char[2];