[compiler-rt] r195130 - [msan] Fix origin tracking in unaligned load/store.

Evgeniy Stepanov eugeni.stepanov at gmail.com
Tue Nov 19 06:47:56 PST 2013


Author: eugenis
Date: Tue Nov 19 08:47:56 2013
New Revision: 195130

URL: http://llvm.org/viewvc/llvm-project?rev=195130&view=rev
Log:
[msan] Fix origin tracking in unaligned load/store.


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

Modified: compiler-rt/trunk/lib/msan/msan.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan.cc?rev=195130&r1=195129&r2=195130&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan.cc (original)
+++ compiler-rt/trunk/lib/msan/msan.cc Tue Nov 19 08:47:56 2013
@@ -33,9 +33,14 @@ static THREADLOCAL int msan_expected_umr
 
 static int msan_running_under_dr = 0;
 
+// Function argument shadow. Each argument starts at the next available 8-byte
+// aligned address.
 SANITIZER_INTERFACE_ATTRIBUTE
 THREADLOCAL u64 __msan_param_tls[kMsanParamTlsSizeInWords];
 
+// Function argument origin. Each argument starts at the same offset as the
+// corresponding shadow in (__msan_param_tls). Slightly weird, but changing this
+// would break compatibility with older prebuilt binaries.
 SANITIZER_INTERFACE_ATTRIBUTE
 THREADLOCAL u32 __msan_param_origin_tls[kMsanParamTlsSizeInWords];
 
@@ -460,8 +465,8 @@ void __msan_set_origin(const void *a, up
   uptr beg = x & ~3UL;  // align down.
   uptr end = (x + size + 3) & ~3UL;  // align up.
   u64 origin64 = ((u64)origin << 32) | origin;
-  // This is like memset, but the value is 32-bit. We unroll by 2 two write
-  // 64-bits at once. May want to unroll further to get 128-bit stores.
+  // This is like memset, but the value is 32-bit. We unroll by 2 to write
+  // 64 bits at once. May want to unroll further to get 128-bit stores.
   if (beg & 7ULL) {
     *(u32*)beg = origin;
     beg += 4;
@@ -521,37 +526,40 @@ u32 __msan_get_umr_origin() {
 u16 __sanitizer_unaligned_load16(const uu16 *p) {
   __msan_retval_tls[0] = *(uu16 *)MEM_TO_SHADOW((uptr)p);
   if (__msan_get_track_origins())
-    __msan_retval_origin_tls = *(uu32 *)MEM_TO_ORIGIN((uptr)p);
+    __msan_retval_origin_tls = *(uu32 *)(MEM_TO_ORIGIN((uptr)p) & ~3UL);
   return *p;
 }
 u32 __sanitizer_unaligned_load32(const uu32 *p) {
   __msan_retval_tls[0] = *(uu32 *)MEM_TO_SHADOW((uptr)p);
   if (__msan_get_track_origins())
-    __msan_retval_origin_tls = *(uu32 *)MEM_TO_ORIGIN((uptr)p);
+    __msan_retval_origin_tls = *(uu32 *)(MEM_TO_ORIGIN((uptr)p) & ~3UL);
   return *p;
 }
 u64 __sanitizer_unaligned_load64(const uu64 *p) {
   __msan_retval_tls[0] = *(uu64 *)MEM_TO_SHADOW((uptr)p);
   if (__msan_get_track_origins())
-    __msan_retval_origin_tls = *(uu32 *)MEM_TO_ORIGIN((uptr)p);
+    __msan_retval_origin_tls = *(uu32 *)(MEM_TO_ORIGIN((uptr)p) & ~3UL);
   return *p;
 }
 void __sanitizer_unaligned_store16(uu16 *p, u16 x) {
   *(uu16 *)MEM_TO_SHADOW((uptr)p) = __msan_param_tls[1];
   if (__msan_get_track_origins())
-    *(uu32 *)MEM_TO_ORIGIN((uptr)p) = __msan_param_origin_tls[1];
+    if (uu32 o = __msan_param_origin_tls[2])
+      __msan_set_origin(p, 2, o);
   *p = x;
 }
 void __sanitizer_unaligned_store32(uu32 *p, u32 x) {
   *(uu32 *)MEM_TO_SHADOW((uptr)p) = __msan_param_tls[1];
   if (__msan_get_track_origins())
-    *(uu32 *)MEM_TO_ORIGIN((uptr)p) = __msan_param_origin_tls[1];
+    if (uu32 o = __msan_param_origin_tls[2])
+      __msan_set_origin(p, 4, o);
   *p = x;
 }
 void __sanitizer_unaligned_store64(uu64 *p, u64 x) {
   *(uu64 *)MEM_TO_SHADOW((uptr)p) = __msan_param_tls[1];
   if (__msan_get_track_origins())
-    *(uu32 *)MEM_TO_ORIGIN((uptr)p) = __msan_param_origin_tls[1];
+    if (uu32 o = __msan_param_origin_tls[2])
+      __msan_set_origin(p, 8, o);
   *p = x;
 }
 

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=195130&r1=195129&r2=195130&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/tests/msan_test.cc (original)
+++ compiler-rt/trunk/lib/msan/tests/msan_test.cc Tue Nov 19 08:47:56 2013
@@ -3085,79 +3085,91 @@ TEST(MemorySanitizer, VolatileBitfield)
 
 TEST(MemorySanitizer, UnalignedLoad) {
   char x[32];
+  U4 origin = __LINE__;
+  __msan_set_origin(&x, sizeof(x), origin);
+
   memset(x + 8, 0, 16);
-  EXPECT_POISONED(__sanitizer_unaligned_load16(x+6));
-  EXPECT_POISONED(__sanitizer_unaligned_load16(x+7));
+  EXPECT_POISONED_O(__sanitizer_unaligned_load16(x+6), origin);
+  EXPECT_POISONED_O(__sanitizer_unaligned_load16(x+7), origin);
   EXPECT_NOT_POISONED(__sanitizer_unaligned_load16(x+8));
   EXPECT_NOT_POISONED(__sanitizer_unaligned_load16(x+9));
   EXPECT_NOT_POISONED(__sanitizer_unaligned_load16(x+22));
-  EXPECT_POISONED(__sanitizer_unaligned_load16(x+23));
-  EXPECT_POISONED(__sanitizer_unaligned_load16(x+24));
+  EXPECT_POISONED_O(__sanitizer_unaligned_load16(x+23), origin);
+  EXPECT_POISONED_O(__sanitizer_unaligned_load16(x+24), origin);
 
-  EXPECT_POISONED(__sanitizer_unaligned_load32(x+4));
-  EXPECT_POISONED(__sanitizer_unaligned_load32(x+7));
+  EXPECT_POISONED_O(__sanitizer_unaligned_load32(x+4), origin);
+  EXPECT_POISONED_O(__sanitizer_unaligned_load32(x+7), origin);
   EXPECT_NOT_POISONED(__sanitizer_unaligned_load32(x+8));
   EXPECT_NOT_POISONED(__sanitizer_unaligned_load32(x+9));
   EXPECT_NOT_POISONED(__sanitizer_unaligned_load32(x+20));
-  EXPECT_POISONED(__sanitizer_unaligned_load32(x+21));
-  EXPECT_POISONED(__sanitizer_unaligned_load32(x+24));
+  EXPECT_POISONED_O(__sanitizer_unaligned_load32(x+21), origin);
+  EXPECT_POISONED_O(__sanitizer_unaligned_load32(x+24), origin);
 
-  EXPECT_POISONED(__sanitizer_unaligned_load64(x));
-  EXPECT_POISONED(__sanitizer_unaligned_load64(x+1));
-  EXPECT_POISONED(__sanitizer_unaligned_load64(x+7));
+  EXPECT_POISONED_O(__sanitizer_unaligned_load64(x), origin);
+  EXPECT_POISONED_O(__sanitizer_unaligned_load64(x+1), origin);
+  EXPECT_POISONED_O(__sanitizer_unaligned_load64(x+7), origin);
   EXPECT_NOT_POISONED(__sanitizer_unaligned_load64(x+8));
   EXPECT_NOT_POISONED(__sanitizer_unaligned_load64(x+9));
   EXPECT_NOT_POISONED(__sanitizer_unaligned_load64(x+16));
-  EXPECT_POISONED(__sanitizer_unaligned_load64(x+17));
-  EXPECT_POISONED(__sanitizer_unaligned_load64(x+21));
-  EXPECT_POISONED(__sanitizer_unaligned_load64(x+24));
+  EXPECT_POISONED_O(__sanitizer_unaligned_load64(x+17), origin);
+  EXPECT_POISONED_O(__sanitizer_unaligned_load64(x+21), origin);
+  EXPECT_POISONED_O(__sanitizer_unaligned_load64(x+24), origin);
 }
 
 TEST(MemorySanitizer, UnalignedStore16) {
   char x[5];
-  U2 y = 0;
-  __msan_poison(&y, 1);
-  __sanitizer_unaligned_store16(x + 1, y);
-  EXPECT_POISONED(x[0]);
-  EXPECT_POISONED(x[1]);
+  U2 y2 = 0;
+  U4 origin = __LINE__;
+  __msan_poison(&y2, 1);
+  __msan_set_origin(&y2, 1, origin);
+
+  __sanitizer_unaligned_store16(x + 1, y2);
+  EXPECT_POISONED_O(x[0], origin);
+  EXPECT_POISONED_O(x[1], origin);
   EXPECT_NOT_POISONED(x[2]);
-  EXPECT_POISONED(x[3]);
-  EXPECT_POISONED(x[4]);
+  EXPECT_POISONED_O(x[3], origin);
+  EXPECT_POISONED_O(x[4], origin);
 }
 
 TEST(MemorySanitizer, UnalignedStore32) {
   char x[8];
   U4 y4 = 0;
+  U4 origin = __LINE__;
   __msan_poison(&y4, 2);
+  __msan_set_origin(&y4, 2, origin);
+
   __sanitizer_unaligned_store32(x+3, y4);
-  EXPECT_POISONED(x[0]);
-  EXPECT_POISONED(x[1]);
-  EXPECT_POISONED(x[2]);
-  EXPECT_POISONED(x[3]);
-  EXPECT_POISONED(x[4]);
+  EXPECT_POISONED_O(x[0], origin);
+  EXPECT_POISONED_O(x[1], origin);
+  EXPECT_POISONED_O(x[2], origin);
+  EXPECT_POISONED_O(x[3], origin);
+  EXPECT_POISONED_O(x[4], origin);
   EXPECT_NOT_POISONED(x[5]);
   EXPECT_NOT_POISONED(x[6]);
-  EXPECT_POISONED(x[7]);
+  EXPECT_POISONED_O(x[7], origin);
 }
 
 TEST(MemorySanitizer, UnalignedStore64) {
   char x[16];
-  U8 y = 0;
-  __msan_poison(&y, 3);
-  __msan_poison(((char *)&y) + sizeof(y) - 2, 1);
-  __sanitizer_unaligned_store64(x+3, y);
-  EXPECT_POISONED(x[0]);
-  EXPECT_POISONED(x[1]);
-  EXPECT_POISONED(x[2]);
-  EXPECT_POISONED(x[3]);
-  EXPECT_POISONED(x[4]);
-  EXPECT_POISONED(x[5]);
+  U8 y8 = 0;
+  U4 origin = __LINE__;
+  __msan_poison(&y8, 3);
+  __msan_poison(((char *)&y8) + sizeof(y8) - 2, 1);
+  __msan_set_origin(&y8, 8, origin);
+
+  __sanitizer_unaligned_store64(x+3, y8);
+  EXPECT_POISONED_O(x[0], origin);
+  EXPECT_POISONED_O(x[1], origin);
+  EXPECT_POISONED_O(x[2], origin);
+  EXPECT_POISONED_O(x[3], origin);
+  EXPECT_POISONED_O(x[4], origin);
+  EXPECT_POISONED_O(x[5], origin);
   EXPECT_NOT_POISONED(x[6]);
   EXPECT_NOT_POISONED(x[7]);
   EXPECT_NOT_POISONED(x[8]);
-  EXPECT_POISONED(x[9]);
+  EXPECT_POISONED_O(x[9], origin);
   EXPECT_NOT_POISONED(x[10]);
-  EXPECT_POISONED(x[11]);
+  EXPECT_POISONED_O(x[11], origin);
 }
 
 TEST(MemorySanitizerDr, StoreInDSOTest) {





More information about the llvm-commits mailing list