[compiler-rt] r212534 - [msan] Fix out of bounds access in origin copying.

Evgeniy Stepanov eugeni.stepanov at gmail.com
Tue Jul 8 07:15:23 PDT 2014


Author: eugenis
Date: Tue Jul  8 09:15:23 2014
New Revision: 212534

URL: http://llvm.org/viewvc/llvm-project?rev=212534&view=rev
Log:
[msan] Fix out of bounds access in origin copying.


Modified:
    compiler-rt/trunk/lib/msan/msan_interceptors.cc
    compiler-rt/trunk/lib/msan/tests/msan_test.cc

Modified: compiler-rt/trunk/lib/msan/msan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan_interceptors.cc?rev=212534&r1=212533&r2=212534&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/msan/msan_interceptors.cc Tue Jul  8 09:15:23 2014
@@ -1412,6 +1412,9 @@ void CopyOrigin(void *dst, const void *s
   }
 
   uptr end = (d + size) & ~3UL;
+  // If both ends fall into the same 4-byte slot, we are done.
+  if (end < beg) return;
+
   // Copy right unaligned origin if that memory is poisoned.
   if (end < d + size) {
     u32 o = GetOriginIfPoisoned((uptr)src + (end - d), (d + size) - end);
@@ -1428,7 +1431,7 @@ void CopyOrigin(void *dst, const void *s
     if (__msan_get_track_origins() > 1) {
       u32 *src = (u32 *)MEM_TO_ORIGIN(s);
       u32 *src_s = (u32 *)MEM_TO_SHADOW(s);
-      u32 *src_end = src + (end - beg);
+      u32 *src_end = (u32 *)MEM_TO_ORIGIN(s + (end - beg));
       u32 *dst = (u32 *)MEM_TO_ORIGIN(beg);
       u32 src_o = 0;
       u32 dst_o = 0;

Modified: compiler-rt/trunk/lib/msan/tests/msan_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/tests/msan_test.cc?rev=212534&r1=212533&r2=212534&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/tests/msan_test.cc (original)
+++ compiler-rt/trunk/lib/msan/tests/msan_test.cc Tue Jul  8 09:15:23 2014
@@ -1292,64 +1292,56 @@ 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);
-  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);
-}
+void TestUnalignedMemcpy(unsigned left, unsigned right, bool src_is_aligned,
+                         bool src_is_poisoned, bool dst_is_poisoned) {
+  fprintf(stderr, "%s(%d, %d, %d, %d, %d)\n", __func__, left, right,
+          src_is_aligned, src_is_poisoned, dst_is_poisoned);
 
-TEST(MemorySanitizer, memcpy_unaligned) {
-  for (int i = 0; i < 10; ++i) {
-    for (int j = 0; j < 10; ++j) {
-      TestUnalignedMemcpy(i, j, true);
-      TestUnalignedMemcpy(i, j, false);
-    }
-  }
-}
-
-// Src is poisoned, dst is clean.
-void TestUnalignedPoisonedMemcpy(int left, int right, bool src_is_aligned) {
-  const int sz = 20;
+  const unsigned sz = 20;
+  U4 dst_origin, src_origin;
   char *dst = (char *)malloc(sz);
-  memset(dst, 0, sz);
+  if (dst_is_poisoned)
+    dst_origin = __msan_get_origin(dst);
+  else
+    memset(dst, 0, sz);
 
   char *src = (char *)malloc(sz);
-  U4 origin = __msan_get_origin(src);
+  if (src_is_poisoned)
+    src_origin = __msan_get_origin(src);
+  else
+    memset(src, 0, sz);
 
   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);
+
+  for (unsigned i = 0; i < (left & (~3U)); ++i)
+    if (dst_is_poisoned)
+      EXPECT_POISONED_O(dst[i], dst_origin);
+    else
+      EXPECT_NOT_POISONED(dst[i]);
+
+  for (unsigned i = 0; i < (right & (~3U)); ++i)
+    if (dst_is_poisoned)
+      EXPECT_POISONED_O(dst[sz - i - 1], dst_origin);
+    else
+      EXPECT_NOT_POISONED(dst[sz - i - 1]);
+
+  for (unsigned i = left; i < sz - right; ++i)
+    if (src_is_poisoned)
+      EXPECT_POISONED_O(dst[i], src_origin);
+    else
+      EXPECT_NOT_POISONED(dst[i]);
 
   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, memcpy_unaligned) {
+  for (int i = 0; i < 10; ++i)
+    for (int j = 0; j < 10; ++j)
+      for (int aligned = 0; aligned < 2; ++aligned)
+        for (int srcp = 0; srcp < 2; ++srcp)
+          for (int dstp = 0; dstp < 2; ++dstp)
+            TestUnalignedMemcpy(i, j, aligned, srcp, dstp);
 }
 
 TEST(MemorySanitizer, memmove) {





More information about the llvm-commits mailing list