[compiler-rt] r205412 - [msan] Precise origin handling in __unaligned_(load|store)*.

Evgeniy Stepanov eugeni.stepanov at gmail.com
Wed Apr 2 04:06:36 PDT 2014


Author: eugenis
Date: Wed Apr  2 06:06:35 2014
New Revision: 205412

URL: http://llvm.org/viewvc/llvm-project?rev=205412&view=rev
Log:
[msan] Precise origin handling in __unaligned_(load|store)*.

Modified:
    compiler-rt/trunk/lib/msan/msan.cc
    compiler-rt/trunk/lib/msan/msan.h
    compiler-rt/trunk/lib/msan/msan_interceptors.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=205412&r1=205411&r2=205412&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan.cc (original)
+++ compiler-rt/trunk/lib/msan/msan.cc Wed Apr  2 06:06:35 2014
@@ -509,40 +509,43 @@ 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) & ~3UL);
+    __msan_retval_origin_tls = GetOriginIfPoisoned((uptr)p, sizeof(*p));
   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) & ~3UL);
+    __msan_retval_origin_tls = GetOriginIfPoisoned((uptr)p, sizeof(*p));
   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) & ~3UL);
+    __msan_retval_origin_tls = GetOriginIfPoisoned((uptr)p, sizeof(*p));
   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())
+  u16 s = __msan_param_tls[1];
+  *(uu16 *)MEM_TO_SHADOW((uptr)p) = s;
+  if (s && __msan_get_track_origins())
     if (uu32 o = __msan_param_origin_tls[2])
-      __msan_set_origin(p, 2, o);
+      SetOriginIfPoisoned((uptr)p, (uptr)&s, sizeof(s), 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())
+  u32 s = __msan_param_tls[1];
+  *(uu32 *)MEM_TO_SHADOW((uptr)p) = s;
+  if (s && __msan_get_track_origins())
     if (uu32 o = __msan_param_origin_tls[2])
-      __msan_set_origin(p, 4, o);
+      SetOriginIfPoisoned((uptr)p, (uptr)&s, sizeof(s), 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())
+  u64 s = __msan_param_tls[1];
+  *(uu64 *)MEM_TO_SHADOW((uptr)p) = s;
+  if (s && __msan_get_track_origins())
     if (uu32 o = __msan_param_origin_tls[2])
-      __msan_set_origin(p, 8, o);
+      SetOriginIfPoisoned((uptr)p, (uptr)&s, sizeof(s), o);
   *p = x;
 }
 

Modified: compiler-rt/trunk/lib/msan/msan.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan.h?rev=205412&r1=205411&r2=205412&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan.h (original)
+++ compiler-rt/trunk/lib/msan/msan.h Wed Apr  2 06:06:35 2014
@@ -88,6 +88,8 @@ void ReportAtExitStatistics();
 void UnpoisonParam(uptr n);
 void UnpoisonThreadLocalState();
 
+u32 GetOriginIfPoisoned(uptr a, uptr size);
+void SetOriginIfPoisoned(uptr addr, uptr src_shadow, uptr size, u32 src_origin);
 void CopyOrigin(void *dst, const void *src, uptr size, StackTrace *stack);
 void MovePoison(void *dst, const void *src, uptr size, StackTrace *stack);
 void CopyPoison(void *dst, const void *src, uptr size, StackTrace *stack);

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=205412&r1=205411&r2=205412&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/msan/msan_interceptors.cc Wed Apr  2 06:06:35 2014
@@ -1367,14 +1367,6 @@ void __msan_clear_and_unpoison(void *a,
   PoisonShadow((uptr)a, size, 0);
 }
 
-u32 get_origin_if_poisoned(uptr a, uptr size) {
-  unsigned char *s = (unsigned char *)MEM_TO_SHADOW(a);
-  for (uptr i = 0; i < size; ++i)
-    if (s[i])
-      return *(u32 *)SHADOW_TO_ORIGIN((s + i) & ~3UL);
-  return 0;
-}
-
 void *__msan_memcpy(void *dest, const void *src, SIZE_T n) {
   ENSURE_MSAN_INITED();
   GET_STORE_STACK_TRACE;
@@ -1405,6 +1397,24 @@ void __msan_unpoison_string(const char*
 
 namespace __msan {
 
+u32 GetOriginIfPoisoned(uptr addr, uptr size) {
+  unsigned char *s = (unsigned char *)MEM_TO_SHADOW(addr);
+  for (uptr i = 0; i < size; ++i)
+    if (s[i])
+      return *(u32 *)SHADOW_TO_ORIGIN((s + i) & ~3UL);
+  return 0;
+}
+
+void SetOriginIfPoisoned(uptr addr, uptr src_shadow, uptr size,
+                         u32 src_origin) {
+  uptr dst_s = MEM_TO_SHADOW(addr);
+  uptr src_s = src_shadow;
+  uptr src_s_end = src_s + size;
+
+  for (; src_s < src_s_end; ++dst_s, ++src_s)
+    if (*(u8 *)src_s) *(u32 *)SHADOW_TO_ORIGIN(dst_s &~3UL) = src_origin;
+}
+
 void CopyOrigin(void *dst, const void *src, uptr size, StackTrace *stack) {
   if (!__msan_get_track_origins()) return;
   if (!MEM_IS_APP(dst) || !MEM_IS_APP(src)) return;
@@ -1413,7 +1423,7 @@ void CopyOrigin(void *dst, const void *s
   uptr beg = d & ~3UL;
   // Copy left unaligned origin if that memory is poisoned.
   if (beg < d) {
-    u32 o = get_origin_if_poisoned(beg, d - beg);
+    u32 o = GetOriginIfPoisoned(beg, d - beg);
     if (o) {
       if (__msan_get_track_origins() > 1) o = ChainOrigin(o, stack);
       *(u32 *)MEM_TO_ORIGIN(beg) = o;
@@ -1424,7 +1434,7 @@ void CopyOrigin(void *dst, const void *s
   uptr end = (d + size + 3) & ~3UL;
   // Copy right unaligned origin if that memory is poisoned.
   if (end > d + size) {
-    u32 o = get_origin_if_poisoned(d + size, end - d - size);
+    u32 o = GetOriginIfPoisoned(d + size, end - d - size);
     if (o) {
       if (__msan_get_track_origins() > 1) o = ChainOrigin(o, stack);
       *(u32 *)MEM_TO_ORIGIN(end - 4) = o;

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=205412&r1=205411&r2=205412&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/tests/msan_test.cc (original)
+++ compiler-rt/trunk/lib/msan/tests/msan_test.cc Wed Apr  2 06:06:35 2014
@@ -3343,34 +3343,35 @@ TEST(MemorySanitizer, VolatileBitfield)
 TEST(MemorySanitizer, UnalignedLoad) {
   char x[32];
   U4 origin = __LINE__;
-  __msan_set_origin(&x, sizeof(x), origin);
+  for (unsigned i = 0; i < sizeof(x) / 4; ++i)
+    __msan_set_origin(x + 4 * i, 4, origin + i);
 
   memset(x + 8, 0, 16);
-  EXPECT_POISONED_O(__sanitizer_unaligned_load16(x + 6), origin);
-  EXPECT_POISONED_O(__sanitizer_unaligned_load16(x + 7), origin);
+  EXPECT_POISONED_O(__sanitizer_unaligned_load16(x + 6), origin + 1);
+  EXPECT_POISONED_O(__sanitizer_unaligned_load16(x + 7), origin + 1);
   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_O(__sanitizer_unaligned_load16(x + 23), origin);
-  EXPECT_POISONED_O(__sanitizer_unaligned_load16(x + 24), origin);
+  EXPECT_POISONED_O(__sanitizer_unaligned_load16(x + 23), origin + 6);
+  EXPECT_POISONED_O(__sanitizer_unaligned_load16(x + 24), origin + 6);
 
-  EXPECT_POISONED_O(__sanitizer_unaligned_load32(x + 4), origin);
-  EXPECT_POISONED_O(__sanitizer_unaligned_load32(x + 7), origin);
+  EXPECT_POISONED_O(__sanitizer_unaligned_load32(x + 4), origin + 1);
+  EXPECT_POISONED_O(__sanitizer_unaligned_load32(x + 7), origin + 1);
   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_O(__sanitizer_unaligned_load32(x + 21), origin);
-  EXPECT_POISONED_O(__sanitizer_unaligned_load32(x + 24), origin);
+  EXPECT_POISONED_O(__sanitizer_unaligned_load32(x + 21), origin + 6);
+  EXPECT_POISONED_O(__sanitizer_unaligned_load32(x + 24), origin + 6);
 
   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_POISONED_O(__sanitizer_unaligned_load64(x + 7), origin + 1);
   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_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);
+  EXPECT_POISONED_O(__sanitizer_unaligned_load64(x + 17), origin + 6);
+  EXPECT_POISONED_O(__sanitizer_unaligned_load64(x + 21), origin + 6);
+  EXPECT_POISONED_O(__sanitizer_unaligned_load64(x + 24), origin + 6);
 }
 
 TEST(MemorySanitizer, UnalignedStore16) {
@@ -3429,6 +3430,115 @@ TEST(MemorySanitizer, UnalignedStore64)
   EXPECT_POISONED_O(x[11], origin);
 }
 
+TEST(MemorySanitizer, UnalignedStore16_precise) {
+  char x[8];
+  U2 y = 0;
+  U4 originx1 = __LINE__;
+  U4 originx2 = __LINE__;
+  U4 originy = __LINE__;
+  __msan_poison(x, sizeof(x));
+  __msan_set_origin(x, 4, originx1);
+  __msan_set_origin(x + 4, 4, originx2);
+  __msan_poison(((char *)&y) + 1, 1);
+  __msan_set_origin(&y, sizeof(y), originy);
+
+  __sanitizer_unaligned_store16(x + 3, y);
+  EXPECT_POISONED_O(x[0], originx1);
+  EXPECT_POISONED_O(x[1], originx1);
+  EXPECT_POISONED_O(x[2], originx1);
+  EXPECT_NOT_POISONED(x[3]);
+  EXPECT_POISONED_O(x[4], originy);
+  EXPECT_POISONED_O(x[5], originy);
+  EXPECT_POISONED_O(x[6], originy);
+  EXPECT_POISONED_O(x[7], originy);
+}
+
+TEST(MemorySanitizer, UnalignedStore16_precise2) {
+  char x[8];
+  U2 y = 0;
+  U4 originx1 = __LINE__;
+  U4 originx2 = __LINE__;
+  U4 originy = __LINE__;
+  __msan_poison(x, sizeof(x));
+  __msan_set_origin(x, 4, originx1);
+  __msan_set_origin(x + 4, 4, originx2);
+  __msan_poison(((char *)&y), 1);
+  __msan_set_origin(&y, sizeof(y), originy);
+
+  __sanitizer_unaligned_store16(x + 3, y);
+  EXPECT_POISONED_O(x[0], originy);
+  EXPECT_POISONED_O(x[1], originy);
+  EXPECT_POISONED_O(x[2], originy);
+  EXPECT_POISONED_O(x[3], originy);
+  EXPECT_NOT_POISONED(x[4]);
+  EXPECT_POISONED_O(x[5], originx2);
+  EXPECT_POISONED_O(x[6], originx2);
+  EXPECT_POISONED_O(x[7], originx2);
+}
+
+TEST(MemorySanitizer, UnalignedStore64_precise) {
+  char x[12];
+  U8 y = 0;
+  U4 originx1 = __LINE__;
+  U4 originx2 = __LINE__;
+  U4 originx3 = __LINE__;
+  U4 originy = __LINE__;
+  __msan_poison(x, sizeof(x));
+  __msan_set_origin(x, 4, originx1);
+  __msan_set_origin(x + 4, 4, originx2);
+  __msan_set_origin(x + 8, 4, originx3);
+  __msan_poison(((char *)&y) + 1, 1);
+  __msan_poison(((char *)&y) + 7, 1);
+  __msan_set_origin(&y, sizeof(y), originy);
+
+  __sanitizer_unaligned_store64(x + 2, y);
+  EXPECT_POISONED_O(x[0], originy);
+  EXPECT_POISONED_O(x[1], originy);
+  EXPECT_NOT_POISONED(x[2]);
+  EXPECT_POISONED_O(x[3], originy);
+
+  EXPECT_NOT_POISONED(x[4]);
+  EXPECT_NOT_POISONED(x[5]);
+  EXPECT_NOT_POISONED(x[6]);
+  EXPECT_NOT_POISONED(x[7]);
+
+  EXPECT_NOT_POISONED(x[8]);
+  EXPECT_POISONED_O(x[9], originy);
+  EXPECT_POISONED_O(x[10], originy);
+  EXPECT_POISONED_O(x[11], originy);
+}
+
+TEST(MemorySanitizer, UnalignedStore64_precise2) {
+  char x[12];
+  U8 y = 0;
+  U4 originx1 = __LINE__;
+  U4 originx2 = __LINE__;
+  U4 originx3 = __LINE__;
+  U4 originy = __LINE__;
+  __msan_poison(x, sizeof(x));
+  __msan_set_origin(x, 4, originx1);
+  __msan_set_origin(x + 4, 4, originx2);
+  __msan_set_origin(x + 8, 4, originx3);
+  __msan_poison(((char *)&y) + 3, 3);
+  __msan_set_origin(&y, sizeof(y), originy);
+
+  __sanitizer_unaligned_store64(x + 2, y);
+  EXPECT_POISONED_O(x[0], originx1);
+  EXPECT_POISONED_O(x[1], originx1);
+  EXPECT_NOT_POISONED(x[2]);
+  EXPECT_NOT_POISONED(x[3]);
+
+  EXPECT_NOT_POISONED(x[4]);
+  EXPECT_POISONED_O(x[5], originy);
+  EXPECT_POISONED_O(x[6], originy);
+  EXPECT_POISONED_O(x[7], originy);
+
+  EXPECT_NOT_POISONED(x[8]);
+  EXPECT_NOT_POISONED(x[9]);
+  EXPECT_POISONED_O(x[10], originx3);
+  EXPECT_POISONED_O(x[11], originx3);
+}
+
 namespace {
 typedef U2 V8x16 __attribute__((__vector_size__(16)));
 typedef U4 V4x32 __attribute__((__vector_size__(16)));





More information about the llvm-commits mailing list