diff options
author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2013-10-24 11:56:03 +0000 |
---|---|---|
committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2013-10-24 11:56:03 +0000 |
commit | 450eee655289a622ab9acf87d863f38991b184c9 (patch) | |
tree | a4fcb2f6680db8b4ddf7945edd32f276f9513420 /lib/msan/tests/msan_test.cc | |
parent | 48ed0580871e66c61e856a2281280929f6f77593 (diff) | |
download | compiler-rt-450eee655289a622ab9acf87d863f38991b184c9.tar.gz compiler-rt-450eee655289a622ab9acf87d863f38991b184c9.tar.bz2 compiler-rt-450eee655289a622ab9acf87d863f38991b184c9.tar.xz |
[msan] Fix invalid origin copying.
Origin copying may destroy valid origin info. This is caused by
__msan_copy_origin widening the address range to the nearest 4-byte aligned
addresses both on the left and on the right. If the target buffer is
uninitialized and the source is fully initialized, this will result in
overriding valid origin of target buffer with stale (possibly 0) origin of the
source buffer.
With this change the widened origin is copied only if corresponding shadow
values are non zero.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@193338 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/msan/tests/msan_test.cc')
-rw-r--r-- | lib/msan/tests/msan_test.cc | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/lib/msan/tests/msan_test.cc b/lib/msan/tests/msan_test.cc index fcb5fc81..f185a31d 100644 --- a/lib/msan/tests/msan_test.cc +++ b/lib/msan/tests/msan_test.cc @@ -1210,6 +1210,35 @@ TEST(MemorySanitizer, memcpy) { EXPECT_POISONED(y[1]); } +void TestUnalignedMemcpy(int left, int right, bool src_is_aligned) { + const int sz = 20; + char *dst = (char *)malloc(sz); + U4 origin = __msan_get_origin(dst); + + char *src = (char *)malloc(sz); + memset(src, 0, sz); + + memcpy(dst + left, src_is_aligned ? src + left : src, sz - left - right); + for (int i = 0; i < left; ++i) + EXPECT_POISONED_O(dst[i], origin); + for (int i = 0; i < right; ++i) + EXPECT_POISONED_O(dst[sz - i - 1], origin); + EXPECT_NOT_POISONED(dst[left]); + EXPECT_NOT_POISONED(dst[sz - right - 1]); + + free(dst); + free(src); +} + +TEST(MemorySanitizer, memcpy_unaligned) { + for (int i = 0; i < 4; ++i) { + for (int j = 0; j < 4; ++j) { + TestUnalignedMemcpy(i, j, true); + TestUnalignedMemcpy(i, j, false); + } + } +} + TEST(MemorySanitizer, memmove) { char* x = new char[2]; char* y = new char[2]; |