[llvm-branch-commits] [compiler-rt] 82655c1 - [MSan] Tweak CopyOrigin

2021-01-12 Thread Jianzhou Zhao via llvm-branch-commits

Author: Jianzhou Zhao
Date: 2021-01-13T01:22:05Z
New Revision: 82655c151450e0103a3aa60725639da607f9220c

URL: 
https://github.com/llvm/llvm-project/commit/82655c151450e0103a3aa60725639da607f9220c
DIFF: 
https://github.com/llvm/llvm-project/commit/82655c151450e0103a3aa60725639da607f9220c.diff

LOG: [MSan] Tweak CopyOrigin

There could be some mis-alignments when copying origins not aligned.

I believe inaligned memcpy is rare so the cases do not matter too much
in practice.

1) About the change at line 50

Let dst be (void*)5,
then d=5, beg=4
so we need to write 3 (4+4-5) bytes from 5 to 7.

2) About the change around line 77.

Let dst be (void*)5,
because of lines 50-55, the bytes from 5-7 were already writen.
So the aligned copy is from 8.

Reviewed-by: eugenis
Differential Revision: https://reviews.llvm.org/D94552

Added: 


Modified: 
compiler-rt/lib/msan/msan_poisoning.cpp

Removed: 




diff  --git a/compiler-rt/lib/msan/msan_poisoning.cpp 
b/compiler-rt/lib/msan/msan_poisoning.cpp
index ef3c74e0a35a..8f58432d528a 100644
--- a/compiler-rt/lib/msan/msan_poisoning.cpp
+++ b/compiler-rt/lib/msan/msan_poisoning.cpp
@@ -47,7 +47,7 @@ void CopyOrigin(const void *dst, const void *src, uptr size,
   uptr beg = d & ~3UL;
   // Copy left unaligned origin if that memory is poisoned.
   if (beg < d) {
-u32 o = GetOriginIfPoisoned((uptr)src, d - beg);
+u32 o = GetOriginIfPoisoned((uptr)src, beg + 4 - d);
 if (o) {
   if (__msan_get_track_origins() > 1) o = ChainOrigin(o, stack);
   *(u32 *)MEM_TO_ORIGIN(beg) = o;
@@ -71,12 +71,13 @@ void CopyOrigin(const void *dst, const void *src, uptr size,
   if (beg < end) {
 // Align src up.
 uptr s = ((uptr)src + 3) & ~3UL;
+uptr aligned_beg = ((uptr)dst + 3) & ~3UL;
 // FIXME: factor out to msan_copy_origin_aligned
 if (__msan_get_track_origins() > 1) {
   u32 *src = (u32 *)MEM_TO_ORIGIN(s);
   u32 *src_s = (u32 *)MEM_TO_SHADOW(s);
-  u32 *src_end = (u32 *)MEM_TO_ORIGIN(s + (end - beg));
-  u32 *dst = (u32 *)MEM_TO_ORIGIN(beg);
+  u32 *src_end = (u32 *)MEM_TO_ORIGIN(s + (end - aligned_beg));
+  u32 *dst = (u32 *)MEM_TO_ORIGIN(aligned_beg);
   u32 src_o = 0;
   u32 dst_o = 0;
   for (; src < src_end; ++src, ++src_s, ++dst) {
@@ -88,8 +89,9 @@ void CopyOrigin(const void *dst, const void *src, uptr size,
 *dst = dst_o;
   }
 } else {
-  REAL(memcpy)((void *)MEM_TO_ORIGIN(beg), (void *)MEM_TO_ORIGIN(s),
-   end - beg);
+  REAL(memcpy)
+  ((void *)MEM_TO_ORIGIN(aligned_beg), (void *)MEM_TO_ORIGIN(s),
+   end - aligned_beg);
 }
   }
 }



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [compiler-rt] 0b99385 - [MSan] Partially revert some changes from D94552

2021-01-12 Thread Jianzhou Zhao via llvm-branch-commits

Author: Jianzhou Zhao
Date: 2021-01-13T07:03:17Z
New Revision: 0b99385e151c7cb674d6d29acfe92680f7148434

URL: 
https://github.com/llvm/llvm-project/commit/0b99385e151c7cb674d6d29acfe92680f7148434
DIFF: 
https://github.com/llvm/llvm-project/commit/0b99385e151c7cb674d6d29acfe92680f7148434.diff

LOG: [MSan] Partially revert some changes from D94552

Because of line 55, actually aligned_beg always equals to beg.

Added: 


Modified: 
compiler-rt/lib/msan/msan_poisoning.cpp

Removed: 




diff  --git a/compiler-rt/lib/msan/msan_poisoning.cpp 
b/compiler-rt/lib/msan/msan_poisoning.cpp
index 8f58432d528a..d121d45a1951 100644
--- a/compiler-rt/lib/msan/msan_poisoning.cpp
+++ b/compiler-rt/lib/msan/msan_poisoning.cpp
@@ -71,13 +71,12 @@ void CopyOrigin(const void *dst, const void *src, uptr size,
   if (beg < end) {
 // Align src up.
 uptr s = ((uptr)src + 3) & ~3UL;
-uptr aligned_beg = ((uptr)dst + 3) & ~3UL;
 // FIXME: factor out to msan_copy_origin_aligned
 if (__msan_get_track_origins() > 1) {
   u32 *src = (u32 *)MEM_TO_ORIGIN(s);
   u32 *src_s = (u32 *)MEM_TO_SHADOW(s);
-  u32 *src_end = (u32 *)MEM_TO_ORIGIN(s + (end - aligned_beg));
-  u32 *dst = (u32 *)MEM_TO_ORIGIN(aligned_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;
   for (; src < src_end; ++src, ++src_s, ++dst) {
@@ -89,9 +88,8 @@ void CopyOrigin(const void *dst, const void *src, uptr size,
 *dst = dst_o;
   }
 } else {
-  REAL(memcpy)
-  ((void *)MEM_TO_ORIGIN(aligned_beg), (void *)MEM_TO_ORIGIN(s),
-   end - aligned_beg);
+  REAL(memcpy)((void *)MEM_TO_ORIGIN(beg), (void *)MEM_TO_ORIGIN(s),
+   end - beg);
 }
   }
 }



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [compiler-rt] f86db34 - [MSan] Move origins for overlapped memory transfer

2021-01-20 Thread Jianzhou Zhao via llvm-branch-commits

Author: Jianzhou Zhao
Date: 2021-01-21T02:11:26Z
New Revision: f86db34defc323135106dc12e9fa888003cdcbd7

URL: 
https://github.com/llvm/llvm-project/commit/f86db34defc323135106dc12e9fa888003cdcbd7
DIFF: 
https://github.com/llvm/llvm-project/commit/f86db34defc323135106dc12e9fa888003cdcbd7.diff

LOG: [MSan] Move origins for overlapped memory transfer

Reviewed-by: eugenis

Differential Revision: https://reviews.llvm.org/D94572

Added: 
compiler-rt/test/msan/chained_origin_memmove.cpp

Modified: 
compiler-rt/lib/msan/msan_poisoning.cpp

Removed: 




diff  --git a/compiler-rt/lib/msan/msan_poisoning.cpp 
b/compiler-rt/lib/msan/msan_poisoning.cpp
index d121d45a1951..a92b0565cfa8 100644
--- a/compiler-rt/lib/msan/msan_poisoning.cpp
+++ b/compiler-rt/lib/msan/msan_poisoning.cpp
@@ -94,23 +94,98 @@ void CopyOrigin(const void *dst, const void *src, uptr size,
   }
 }
 
+void ReverseCopyOrigin(const void *dst, const void *src, uptr size,
+   StackTrace *stack) {
+  if (!MEM_IS_APP(dst) || !MEM_IS_APP(src))
+return;
+
+  uptr d = (uptr)dst;
+  uptr end = (d + size) & ~3UL;
+
+  // Copy right unaligned origin if that memory is poisoned.
+  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) = o;
+}
+  }
+
+  uptr beg = d & ~3UL;
+
+  if (beg + 4 < end) {
+// Align src up.
+uptr s = ((uptr)src + 3) & ~3UL;
+if (__msan_get_track_origins() > 1) {
+  u32 *src = (u32 *)MEM_TO_ORIGIN(s + end - beg - 4);
+  u32 *src_s = (u32 *)MEM_TO_SHADOW(s + end - beg - 4);
+  u32 *src_begin = (u32 *)MEM_TO_ORIGIN(s);
+  u32 *dst = (u32 *)MEM_TO_ORIGIN(end - 4);
+  u32 src_o = 0;
+  u32 dst_o = 0;
+  for (; src >= src_begin; --src, --src_s, --dst) {
+if (!*src_s)
+  continue;
+if (*src != src_o) {
+  src_o = *src;
+  dst_o = ChainOrigin(src_o, stack);
+}
+*dst = dst_o;
+  }
+} else {
+  REAL(memmove)
+  ((void *)MEM_TO_ORIGIN(beg), (void *)MEM_TO_ORIGIN(s), end - beg - 4);
+}
+  }
+
+  // Copy left unaligned origin if that memory is poisoned.
+  if (beg < d) {
+u32 o = GetOriginIfPoisoned((uptr)src, beg + 4 - d);
+if (o) {
+  if (__msan_get_track_origins() > 1)
+o = ChainOrigin(o, stack);
+  *(u32 *)MEM_TO_ORIGIN(beg) = o;
+}
+  }
+}
+
+void MoveOrigin(const void *dst, const void *src, uptr size,
+StackTrace *stack) {
+  // If destination origin range overlaps with source origin range, move
+  // origins by coping origins in a reverse order; otherwise, copy origins in
+  // a normal order.
+  uptr src_aligned_beg = reinterpret_cast(src) & ~3UL;
+  uptr src_aligned_end = (reinterpret_cast(src) + size) & ~3UL;
+  uptr dst_aligned_beg = reinterpret_cast(dst) & ~3UL;
+  if (dst_aligned_beg < src_aligned_end && dst_aligned_beg >= src_aligned_beg)
+return ReverseCopyOrigin(dst, src, size, stack);
+  return CopyOrigin(dst, src, size, stack);
+}
+
 void MoveShadowAndOrigin(const void *dst, const void *src, uptr size,
  StackTrace *stack) {
   if (!MEM_IS_APP(dst)) return;
   if (!MEM_IS_APP(src)) return;
   if (src == dst) return;
+  // MoveOrigin transfers origins by refering to their shadows. So we
+  // need to move origins before moving shadows.
+  if (__msan_get_track_origins())
+MoveOrigin(dst, src, size, stack);
   REAL(memmove)((void *)MEM_TO_SHADOW((uptr)dst),
 (void *)MEM_TO_SHADOW((uptr)src), size);
-  if (__msan_get_track_origins()) CopyOrigin(dst, src, size, stack);
 }
 
 void CopyShadowAndOrigin(const void *dst, const void *src, uptr size,
  StackTrace *stack) {
   if (!MEM_IS_APP(dst)) return;
   if (!MEM_IS_APP(src)) return;
+  // Because origin's range is slightly larger than app range, memcpy may also
+  // cause overlapped origin ranges.
   REAL(memcpy)((void *)MEM_TO_SHADOW((uptr)dst),
(void *)MEM_TO_SHADOW((uptr)src), size);
-  if (__msan_get_track_origins()) CopyOrigin(dst, src, size, stack);
+  if (__msan_get_track_origins())
+MoveOrigin(dst, src, size, stack);
 }
 
 void CopyMemory(void *dst, const void *src, uptr size, StackTrace *stack) {

diff  --git a/compiler-rt/test/msan/chained_origin_memmove.cpp 
b/compiler-rt/test/msan/chained_origin_memmove.cpp
new file mode 100644
index ..af6935767bc9
--- /dev/null
+++ b/compiler-rt/test/msan/chained_origin_memmove.cpp
@@ -0,0 +1,57 @@
+// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -DOFFSET=0 -O3 %s -o 
%t && \
+// RUN: not %run %t >%t.out 2>&1
+// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-Z1 
--check-prefix=CHECK-%short-stack < %t.out
+
+// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -DOFFSE

[llvm-branch-commits] [llvm] 405ea2b - [msan] Replace 8 by kShadowTLSAlignment

2020-12-01 Thread Jianzhou Zhao via llvm-branch-commits

Author: Jianzhou Zhao
Date: 2020-12-02T01:09:49Z
New Revision: 405ea2b93d96f7014e60eeb84040b35372d448e7

URL: 
https://github.com/llvm/llvm-project/commit/405ea2b93d96f7014e60eeb84040b35372d448e7
DIFF: 
https://github.com/llvm/llvm-project/commit/405ea2b93d96f7014e60eeb84040b35372d448e7.diff

LOG: [msan] Replace 8 by kShadowTLSAlignment

Reviewed-by: eugenis

Differential Revision: https://reviews.llvm.org/D92275

Added: 


Modified: 
llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp

Removed: 




diff  --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp 
b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
index 188403b54b53..5ff4c45f681c 100644
--- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
@@ -3708,7 +3708,7 @@ struct MemorySanitizerVisitor : public 
InstVisitor {
   (void)Store;
   assert(Size != 0 && Store != nullptr);
   LLVM_DEBUG(dbgs() << "  Param:" << *Store << "\n");
-  ArgOffset += alignTo(Size, 8);
+  ArgOffset += alignTo(Size, kShadowTLSAlignment);
 }
 LLVM_DEBUG(dbgs() << "  done with call args\n");
 



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [compiler-rt] 6fa0662 - [dfsan] Add test cases for struct/pair

2020-12-02 Thread Jianzhou Zhao via llvm-branch-commits

Author: Jianzhou Zhao
Date: 2020-12-02T21:25:23Z
New Revision: 6fa06628a728ac161b3f61a2a2fb749cd8e4b41b

URL: 
https://github.com/llvm/llvm-project/commit/6fa06628a728ac161b3f61a2a2fb749cd8e4b41b
DIFF: 
https://github.com/llvm/llvm-project/commit/6fa06628a728ac161b3f61a2a2fb749cd8e4b41b.diff

LOG: [dfsan] Add test cases for struct/pair

This is a child diff of D92261.

This locks down the behavior before the change.

Added: 
compiler-rt/test/dfsan/pair.cpp
compiler-rt/test/dfsan/struct.c

Modified: 


Removed: 




diff  --git a/compiler-rt/test/dfsan/pair.cpp b/compiler-rt/test/dfsan/pair.cpp
new file mode 100644
index ..830fe393b17b
--- /dev/null
+++ b/compiler-rt/test/dfsan/pair.cpp
@@ -0,0 +1,138 @@
+// RUN: %clangxx_dfsan %s -mllvm -dfsan-fast-16-labels -mllvm 
-dfsan-track-select-control-flow=false -mllvm 
-dfsan-combine-pointer-labels-on-load=false -o %t && %run %t
+
+#include 
+#include 
+#include 
+#include 
+
+__attribute__((noinline))
+std::pair
+make_pair(int *p, int i) { return {p, i}; }
+
+__attribute__((noinline))
+std::pair
+copy_pair1(const std::pair &pair) {
+  return pair;
+}
+
+__attribute__((noinline))
+std::pair
+copy_pair2(std::pair *pair) {
+  return *pair;
+}
+
+__attribute__((noinline))
+std::pair
+copy_pair3(std::pair &&pair) {
+  return std::move(pair);
+}
+
+__attribute__((noinline))
+std::pair
+return_ptr_and_i32(const char *p, uint32_t res) {
+  for (uint32_t i = 2; i < 5; i++) {
+uint32_t byte = static_cast(p[i]);
+res += (byte - 1) << (7 * i);
+if (byte < 128) {
+  return {p + i + 1, res};
+}
+  }
+  return {nullptr, 0};
+}
+
+__attribute__((noinline))
+std::pair
+return_ptr_and_i64(const char *p, uint32_t res32) {
+  uint64_t res = res32;
+  for (uint32_t i = 2; i < 10; i++) {
+uint64_t byte = static_cast(p[i]);
+res += (byte - 1) << (7 * i);
+if (byte < 128) {
+  return {p + i + 1, res};
+}
+  }
+  return {nullptr, 0};
+}
+
+void test_simple_constructors() {
+  int i = 1;
+  int *ptr = NULL;
+  dfsan_set_label(8, &i, sizeof(i));
+  dfsan_set_label(2, &ptr, sizeof(ptr));
+
+  std::pair pair1 = make_pair(ptr, i);
+  int i1 = pair1.second;
+  int *ptr1 = pair1.first;
+
+  assert(dfsan_read_label(&i1, sizeof(i1)) == 10);
+  assert(dfsan_read_label(&ptr1, sizeof(ptr1)) == 10);
+
+  std::pair pair2 = copy_pair1(pair1);
+  int i2 = pair2.second;
+  int *ptr2 = pair2.first;
+
+  assert(dfsan_read_label(&i2, sizeof(i2)) == 10);
+  assert(dfsan_read_label(&ptr2, sizeof(ptr2)) == 10);
+
+  std::pair pair3 = copy_pair2(&pair1);
+  int i3 = pair3.second;
+  int *ptr3 = pair3.first;
+
+  assert(dfsan_read_label(&i3, sizeof(i3)) == 10);
+  assert(dfsan_read_label(&ptr3, sizeof(ptr3)) == 10);
+
+  std::pair pair4 = copy_pair3(std::move(pair1));
+  int i4 = pair4.second;
+  int *ptr4 = pair4.first;
+
+  assert(dfsan_read_label(&i4, sizeof(i4)) == 10);
+  assert(dfsan_read_label(&ptr4, sizeof(ptr4)) == 10);
+}
+
+void test_branches() {
+  uint32_t res = 4;
+  dfsan_set_label(8, &res, sizeof(res));
+
+  char p[100];
+  const char *q = p;
+  dfsan_set_label(2, &q, sizeof(q));
+
+  {
+std::fill_n(p, 100, static_cast(128));
+
+{
+  std::pair r = return_ptr_and_i32(q, res);
+  assert(dfsan_read_label(&r.first, sizeof(r.first)) == 0);
+  assert(dfsan_read_label(&r.second, sizeof(r.second)) == 0);
+}
+
+{
+  std::pair r = return_ptr_and_i64(q, res);
+  assert(dfsan_read_label(&r.first, sizeof(r.first)) == 0);
+  assert(dfsan_read_label(&r.second, sizeof(r.second)) == 0);
+}
+  }
+
+  {
+std::fill_n(p, 100, 0);
+
+{
+  std::pair r = return_ptr_and_i32(q, res);
+  assert(dfsan_read_label(&r.first, sizeof(r.first)) == 10);
+  assert(dfsan_read_label(&r.second, sizeof(r.second)) == 10);
+}
+
+{
+  std::pair r = return_ptr_and_i64(q, res);
+  assert(dfsan_read_label(&r.first, sizeof(r.first)) == 10);
+  assert(dfsan_read_label(&r.second, sizeof(r.second)) == 10);
+}
+  }
+}
+
+int main(void) {
+  test_simple_constructors();
+  test_branches();
+
+  return 0;
+}

diff  --git a/compiler-rt/test/dfsan/struct.c b/compiler-rt/test/dfsan/struct.c
new file mode 100644
index ..6441ad4de163
--- /dev/null
+++ b/compiler-rt/test/dfsan/struct.c
@@ -0,0 +1,77 @@
+// RUN: %clang_dfsan %s -o %t && %run %t
+
+#include 
+#include 
+
+typedef struct Pair {
+  int i;
+  char *ptr;
+} Pair;
+
+__attribute__((noinline))
+Pair make_pair(int i, char *ptr) {
+  Pair pair;
+  pair.i = i;
+  pair.ptr = ptr;
+  return pair;
+}
+
+__attribute__((noinline))
+Pair copy_pair1(const Pair *pair0) {
+  Pair pair;
+  pair.i = pair0->i;
+  pair.ptr = pair0->ptr;
+  return pair;
+}
+
+__attribute__((noinline))
+Pair copy_pair2(const Pair pair0) {
+  Pair pair;
+  pair.i = pair0.i;
+  pair.ptr = pair0.ptr;
+  return pair;
+}
+
+int main(void) {
+  int i = 1;
+  char *ptr = NULL;
+  dfsan_label 

[llvm-branch-commits] [llvm] baa005c - [dfsan] Add a test case for phi

2020-12-02 Thread Jianzhou Zhao via llvm-branch-commits

Author: Jianzhou Zhao
Date: 2020-12-02T21:29:44Z
New Revision: baa005c96ce610e9ee91ef55a3a1b1eacd5a0a27

URL: 
https://github.com/llvm/llvm-project/commit/baa005c96ce610e9ee91ef55a3a1b1eacd5a0a27
DIFF: 
https://github.com/llvm/llvm-project/commit/baa005c96ce610e9ee91ef55a3a1b1eacd5a0a27.diff

LOG: [dfsan] Add a test case for phi

Added: 
llvm/test/Instrumentation/DataFlowSanitizer/phi.ll

Modified: 


Removed: 




diff  --git a/llvm/test/Instrumentation/DataFlowSanitizer/phi.ll 
b/llvm/test/Instrumentation/DataFlowSanitizer/phi.ll
new file mode 100644
index ..08c457f3bfc7
--- /dev/null
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/phi.ll
@@ -0,0 +1,24 @@
+; RUN: opt < %s -dfsan -S | FileCheck %s
+target datalayout = 
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define {i32, i32} @test({i32, i32} %a, i1 %c) {
+  ; CHECK: [[E0:%.*]] = load i16, i16* getelementptr inbounds ([64 x i16], [64 
x i16]* @__dfsan_arg_tls, i64 0, i64 0), align 2
+  ; CHECK: [[E3:%.*]] = phi i16 [ [[E0]], %T ], [ [[E0]], %F ]
+  ; CHECK: store i16 [[E3]], i16* @__dfsan_retval_tls, align 2
+
+entry:
+  br i1 %c, label %T, label %F
+  
+T:
+  %at = insertvalue {i32, i32} %a, i32 1, 0
+  br label %done
+  
+F:
+  %af = insertvalue {i32, i32} %a, i32 1, 1
+  br label %done
+  
+done:
+  %b = phi {i32, i32} [%at, %T], [%af, %F]
+  ret {i32, i32} %b  
+}



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] 838ecf2 - [dfsan] Test loading global ptrs

2020-12-02 Thread Jianzhou Zhao via llvm-branch-commits

Author: Jianzhou Zhao
Date: 2020-12-02T21:35:41Z
New Revision: 838ecf2ea483ce6986a1d38208555155bbc53bba

URL: 
https://github.com/llvm/llvm-project/commit/838ecf2ea483ce6986a1d38208555155bbc53bba
DIFF: 
https://github.com/llvm/llvm-project/commit/838ecf2ea483ce6986a1d38208555155bbc53bba.diff

LOG: [dfsan] Test loading global ptrs

This covers a branch in the loadShadow method.

Reviewed-by: morehouse

Differential Revision: https://reviews.llvm.org/D92460

Added: 


Modified: 
llvm/test/Instrumentation/DataFlowSanitizer/load.ll

Removed: 




diff  --git a/llvm/test/Instrumentation/DataFlowSanitizer/load.ll 
b/llvm/test/Instrumentation/DataFlowSanitizer/load.ll
index 5bb3984227df..9cdf69d11ddb 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/load.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/load.ll
@@ -166,3 +166,12 @@ define i64 @load64(i64* %p) {
   %a = load i64, i64* %p
   ret i64 %a
 }
+
+@X = constant i1 1
+define i1 @load_global() {
+  ; NO_COMBINE_PTR_LABEL: @"dfs$load_global"
+  ; NO_COMBINE_PTR_LABEL: store i16 0, i16* @__dfsan_retval_tls, align 2
+
+  %a = load i1, i1* @X
+  ret i1 %a
+}
\ No newline at end of file



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] dad5d95 - [dfsan] Rename CachedCombinedShadow to be CachedShadow

2020-12-02 Thread Jianzhou Zhao via llvm-branch-commits

Author: Jianzhou Zhao
Date: 2020-12-02T21:39:16Z
New Revision: dad5d9588335d6e4232b7c263da24ae2676673da

URL: 
https://github.com/llvm/llvm-project/commit/dad5d9588335d6e4232b7c263da24ae2676673da
DIFF: 
https://github.com/llvm/llvm-project/commit/dad5d9588335d6e4232b7c263da24ae2676673da.diff

LOG: [dfsan] Rename CachedCombinedShadow to be CachedShadow

At D92261, this type will be used to cache both combined shadow and
converted shadow values.

Reviewed-by: morehouse

Differential Revision: https://reviews.llvm.org/D92458

Added: 


Modified: 
llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp

Removed: 




diff  --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp 
b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
index 4fd6308fcc49..46f4becb511f 100644
--- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
@@ -428,12 +428,12 @@ struct DFSanFunction {
   std::vector NonZeroChecks;
   bool AvoidNewBlocks;
 
-  struct CachedCombinedShadow {
-BasicBlock *Block;
+  struct CachedShadow {
+BasicBlock *Block; // The block where Shadow is defined.
 Value *Shadow;
   };
-  DenseMap, CachedCombinedShadow>
-  CachedCombinedShadows;
+  /// Maps a value to its latest shadow value in terms of domination tree.
+  DenseMap, CachedShadow> CachedShadows;
   DenseMap> ShadowElements;
 
   DFSanFunction(DataFlowSanitizer &DFS, Function *F, bool IsNativeABI)
@@ -1145,7 +1145,7 @@ Value *DFSanFunction::combineShadows(Value *V1, Value 
*V2, Instruction *Pos) {
   auto Key = std::make_pair(V1, V2);
   if (V1 > V2)
 std::swap(Key.first, Key.second);
-  CachedCombinedShadow &CCS = CachedCombinedShadows[Key];
+  CachedShadow &CCS = CachedShadows[Key];
   if (CCS.Block && DT.dominates(CCS.Block, Pos->getParent()))
 return CCS.Shadow;
 



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] bd726d2 - [dfsan] Rename ShadowTy/ZeroShadow with prefix Primitive

2020-12-02 Thread Jianzhou Zhao via llvm-branch-commits

Author: Jianzhou Zhao
Date: 2020-12-03T05:31:01Z
New Revision: bd726d2796b1a5d2c936b5708bfb49a4b7fb89de

URL: 
https://github.com/llvm/llvm-project/commit/bd726d2796b1a5d2c936b5708bfb49a4b7fb89de
DIFF: 
https://github.com/llvm/llvm-project/commit/bd726d2796b1a5d2c936b5708bfb49a4b7fb89de.diff

LOG: [dfsan] Rename ShadowTy/ZeroShadow with prefix Primitive

This is a child diff of D92261.

After supporting field/index-level shadow, the existing shadow with type
i16 works for only primitive types.

Reviewed-by: morehouse

Differential Revision: https://reviews.llvm.org/D92459

Added: 


Modified: 
llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp

Removed: 




diff  --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp 
b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
index 46f4becb511f..9dad9817acea 100644
--- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
@@ -354,10 +354,13 @@ class DataFlowSanitizer {
   Module *Mod;
   LLVMContext *Ctx;
   Type *Int8Ptr;
-  IntegerType *ShadowTy;
-  PointerType *ShadowPtrTy;
+  /// The shadow type for all primitive types. Until we support field/index
+  /// level shadow values, aggregate and vector types also use this shadow
+  /// type.
+  IntegerType *PrimitiveShadowTy;
+  PointerType *PrimitiveShadowPtrTy;
   IntegerType *IntptrTy;
-  ConstantInt *ZeroShadow;
+  ConstantInt *ZeroPrimitiveShadow;
   ConstantInt *ShadowPtrMask;
   ConstantInt *ShadowPtrMul;
   Constant *ArgTLS;
@@ -504,12 +507,12 @@ DataFlowSanitizer::DataFlowSanitizer(
 
 FunctionType *DataFlowSanitizer::getArgsFunctionType(FunctionType *T) {
   SmallVector ArgTypes(T->param_begin(), T->param_end());
-  ArgTypes.append(T->getNumParams(), ShadowTy);
+  ArgTypes.append(T->getNumParams(), PrimitiveShadowTy);
   if (T->isVarArg())
-ArgTypes.push_back(ShadowPtrTy);
+ArgTypes.push_back(PrimitiveShadowPtrTy);
   Type *RetType = T->getReturnType();
   if (!RetType->isVoidTy())
-RetType = StructType::get(RetType, ShadowTy);
+RetType = StructType::get(RetType, PrimitiveShadowTy);
   return FunctionType::get(RetType, ArgTypes, T->isVarArg());
 }
 
@@ -518,10 +521,10 @@ FunctionType 
*DataFlowSanitizer::getTrampolineFunctionType(FunctionType *T) {
   SmallVector ArgTypes;
   ArgTypes.push_back(T->getPointerTo());
   ArgTypes.append(T->param_begin(), T->param_end());
-  ArgTypes.append(T->getNumParams(), ShadowTy);
+  ArgTypes.append(T->getNumParams(), PrimitiveShadowTy);
   Type *RetType = T->getReturnType();
   if (!RetType->isVoidTy())
-ArgTypes.push_back(ShadowPtrTy);
+ArgTypes.push_back(PrimitiveShadowPtrTy);
   return FunctionType::get(T->getReturnType(), ArgTypes, false);
 }
 
@@ -547,12 +550,12 @@ TransformedFunction 
DataFlowSanitizer::getCustomFunctionType(FunctionType *T) {
 }
   }
   for (unsigned i = 0, e = T->getNumParams(); i != e; ++i)
-ArgTypes.push_back(ShadowTy);
+ArgTypes.push_back(PrimitiveShadowTy);
   if (T->isVarArg())
-ArgTypes.push_back(ShadowPtrTy);
+ArgTypes.push_back(PrimitiveShadowPtrTy);
   Type *RetType = T->getReturnType();
   if (!RetType->isVoidTy())
-ArgTypes.push_back(ShadowPtrTy);
+ArgTypes.push_back(PrimitiveShadowPtrTy);
   return TransformedFunction(
   T, FunctionType::get(T->getReturnType(), ArgTypes, T->isVarArg()),
   ArgumentIndexMapping);
@@ -570,10 +573,10 @@ bool DataFlowSanitizer::init(Module &M) {
   Mod = &M;
   Ctx = &M.getContext();
   Int8Ptr = Type::getInt8PtrTy(*Ctx);
-  ShadowTy = IntegerType::get(*Ctx, ShadowWidthBits);
-  ShadowPtrTy = PointerType::getUnqual(ShadowTy);
+  PrimitiveShadowTy = IntegerType::get(*Ctx, ShadowWidthBits);
+  PrimitiveShadowPtrTy = PointerType::getUnqual(PrimitiveShadowTy);
   IntptrTy = DL.getIntPtrType(*Ctx);
-  ZeroShadow = ConstantInt::getSigned(ShadowTy, 0);
+  ZeroPrimitiveShadow = ConstantInt::getSigned(PrimitiveShadowTy, 0);
   ShadowPtrMul = ConstantInt::getSigned(IntptrTy, ShadowWidthBytes);
   if (IsX86_64)
 ShadowPtrMask = ConstantInt::getSigned(IntptrTy, ~0x7000LL);
@@ -585,28 +588,30 @@ bool DataFlowSanitizer::init(Module &M) {
   else
 report_fatal_error("unsupported triple");
 
-  Type *DFSanUnionArgs[2] = { ShadowTy, ShadowTy };
+  Type *DFSanUnionArgs[2] = {PrimitiveShadowTy, PrimitiveShadowTy};
   DFSanUnionFnTy =
-  FunctionType::get(ShadowTy, DFSanUnionArgs, /*isVarArg=*/ false);
-  Type *DFSanUnionLoadArgs[2] = { ShadowPtrTy, IntptrTy };
-  DFSanUnionLoadFnTy =
-  FunctionType::get(ShadowTy, DFSanUnionLoadArgs, /*isVarArg=*/ false);
+  FunctionType::get(PrimitiveShadowTy, DFSanUnionArgs, /*isVarArg=*/false);
+  Type *DFSanUnionLoadArgs[2] = {PrimitiveShadowPtrTy, IntptrTy};
+  DFSanUnionLoadFnTy = FunctionType::get(PrimitiveShadowTy, DFSanUnionLoadArgs,
+ /*isVarArg=*/false);
   DFSanUni

[llvm-branch-commits] [llvm] 80e326a - [dfsan] Support passing non-i16 shadow values in TLS mode

2020-12-03 Thread Jianzhou Zhao via llvm-branch-commits

Author: Jianzhou Zhao
Date: 2020-12-04T02:45:07Z
New Revision: 80e326a8c4cfae770c10d7bb3d0ae291011bd91f

URL: 
https://github.com/llvm/llvm-project/commit/80e326a8c4cfae770c10d7bb3d0ae291011bd91f
DIFF: 
https://github.com/llvm/llvm-project/commit/80e326a8c4cfae770c10d7bb3d0ae291011bd91f.diff

LOG: [dfsan] Support passing non-i16 shadow values in TLS mode

This is a child diff of D92261.

It extended TLS arg/ret to work with aggregate types.

For a function
  t foo(t1 a1, t2 a2, ... tn an)
Its arguments shadow are saved in TLS args like
  a1_s, a2_s, ..., an_s
TLS ret simply includes r_s. By calculating the type size of each shadow
value, we can get their offset.

This is similar to what MSan does. See __msan_retval_tls and __msan_param_tls
from llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp.

Note that this change does not add test cases for overflowed TLS
arg/ret because this is hard to test w/o supporting aggregate shdow
types. We will be adding them after supporting that.

Reviewed-by: morehouse

Differential Revision: https://reviews.llvm.org/D92440

Added: 


Modified: 
compiler-rt/lib/dfsan/dfsan.cpp
llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
llvm/test/Instrumentation/DataFlowSanitizer/arith.ll
llvm/test/Instrumentation/DataFlowSanitizer/call.ll
llvm/test/Instrumentation/DataFlowSanitizer/callback.ll
llvm/test/Instrumentation/DataFlowSanitizer/fast16labels.ll
llvm/test/Instrumentation/DataFlowSanitizer/load.ll
llvm/test/Instrumentation/DataFlowSanitizer/phi.ll
llvm/test/Instrumentation/DataFlowSanitizer/select.ll

Removed: 




diff  --git a/compiler-rt/lib/dfsan/dfsan.cpp b/compiler-rt/lib/dfsan/dfsan.cpp
index db610857834c..c17bfe0ccb32 100644
--- a/compiler-rt/lib/dfsan/dfsan.cpp
+++ b/compiler-rt/lib/dfsan/dfsan.cpp
@@ -41,8 +41,15 @@ static dfsan_label_info __dfsan_label_info[kNumLabels];
 
 Flags __dfsan::flags_data;
 
-SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL dfsan_label __dfsan_retval_tls;
-SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL dfsan_label __dfsan_arg_tls[64];
+// The size of TLS variables. These constants must be kept in sync with the 
ones
+// in DataFlowSanitizer.cpp.
+static const int kDFsanArgTlsSize = 800;
+static const int kDFsanRetvalTlsSize = 800;
+
+SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL u64
+__dfsan_retval_tls[kDFsanRetvalTlsSize / sizeof(u64)];
+SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL u64
+__dfsan_arg_tls[kDFsanArgTlsSize / sizeof(u64)];
 
 SANITIZER_INTERFACE_ATTRIBUTE uptr __dfsan_shadow_ptr_mask;
 

diff  --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp 
b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
index 9dad9817acea..fc784e72797c 100644
--- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
@@ -106,6 +106,14 @@
 
 using namespace llvm;
 
+// This must be consistent with ShadowWidthBits.
+static const Align kShadowTLSAlignment = Align(2);
+
+// The size of TLS variables. These constants must be kept in sync with the 
ones
+// in dfsan.cpp.
+static const unsigned kArgTLSSize = 800;
+static const unsigned kRetvalTLSSize = 800;
+
 // External symbol to be used when generating the shadow address for
 // architectures with multiple VMAs. Instead of using a constant integer
 // the runtime will set the external mask based on the VMA range.
@@ -447,7 +455,14 @@ struct DFSanFunction {
 AvoidNewBlocks = F->size() > 1000;
   }
 
-  Value *getArgTLS(unsigned Index, Instruction *Pos);
+  /// Computes the shadow address for a given function argument.
+  ///
+  /// Shadow = ArgTLS+ArgOffset.
+  Value *getArgTLS(unsigned ArgOffset, IRBuilder<> &IRB);
+
+  /// Computes the shadow address for a retval.
+  Value *getRetvalTLS(IRBuilder<> &IRB);
+
   Value *getShadow(Value *V);
   void setShadow(Instruction *I, Value *Shadow);
   Value *combineShadows(Value *V1, Value *V2, Instruction *Pos);
@@ -456,6 +471,10 @@ struct DFSanFunction {
 Instruction *Pos);
   void storeShadow(Value *Addr, uint64_t Size, Align Alignment, Value *Shadow,
Instruction *Pos);
+
+private:
+  /// Returns the shadow value of an argument A.
+  Value *getShadowForTLSArgument(Argument *A);
 };
 
 class DFSanVisitor : public InstVisitor {
@@ -816,13 +835,15 @@ bool DataFlowSanitizer::runImpl(Module &M) {
 
   bool Changed = false;
 
-  Type *ArgTLSTy = ArrayType::get(PrimitiveShadowTy, 64);
+  Type *ArgTLSTy = ArrayType::get(Type::getInt64Ty(*Ctx), kArgTLSSize / 8);
   ArgTLS = Mod->getOrInsertGlobal("__dfsan_arg_tls", ArgTLSTy);
   if (GlobalVariable *G = dyn_cast(ArgTLS)) {
 Changed |= G->getThreadLocalMode() != GlobalVariable::InitialExecTLSModel;
 G->setThreadLocalMode(GlobalVariable::InitialExecTLSModel);
   }
-  RetvalTLS = Mod->getOrInsertGlobal("__dfsan_retval_tls", PrimitiveShadowTy);
+  Type *RetvalT

[llvm-branch-commits] [llvm] fa4c3f7 - [dfsan] Add a test case of storing zero

2020-12-04 Thread Jianzhou Zhao via llvm-branch-commits

Author: Jianzhou Zhao
Date: 2020-12-04T20:28:44Z
New Revision: fa4c3f70ff0768a270b0620dc6d158ed1205ec4e

URL: 
https://github.com/llvm/llvm-project/commit/fa4c3f70ff0768a270b0620dc6d158ed1205ec4e
DIFF: 
https://github.com/llvm/llvm-project/commit/fa4c3f70ff0768a270b0620dc6d158ed1205ec4e.diff

LOG: [dfsan] Add a test case of storing zero

This covers a branch in storeShadow.

Reviewed-by: morehouse

Differential Revision: https://reviews.llvm.org/D92632

Added: 


Modified: 
llvm/test/Instrumentation/DataFlowSanitizer/store.ll

Removed: 




diff  --git a/llvm/test/Instrumentation/DataFlowSanitizer/store.ll 
b/llvm/test/Instrumentation/DataFlowSanitizer/store.ll
index a66cedf70b10..4560c3d7fb8f 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/store.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/store.ll
@@ -158,3 +158,9 @@ define void @store64(i64 %v, i64* %p) {
   store i64 %v, i64* %p
   ret void
 }
+
+define void @store_zero(i32* %p) {
+  ;  NO_COMBINE_PTR_LABEL: store i64 0, i64* {{.*}}, align 2
+  store i32 0, i32* %p
+  ret void
+}



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] a28db8b - [dfsan] Add empty APIs for field-level shadow

2020-12-04 Thread Jianzhou Zhao via llvm-branch-commits

Author: Jianzhou Zhao
Date: 2020-12-04T21:42:07Z
New Revision: a28db8b27a232cffcb77d0f902d76ee07cd54c05

URL: 
https://github.com/llvm/llvm-project/commit/a28db8b27a232cffcb77d0f902d76ee07cd54c05
DIFF: 
https://github.com/llvm/llvm-project/commit/a28db8b27a232cffcb77d0f902d76ee07cd54c05.diff

LOG: [dfsan] Add empty APIs for field-level shadow

This is a child diff of D92261.

This diff adds APIs that return shadow type/value/zero from origin
objects. For the time being these APIs simply returns primitive
shadow type/value/zero. The following diff will be implementing the
conversion.

As D92261 explains, some cases still use primitive shadow during
the incremential changes. The cases include
1) alloca/load/store
2) custom function IO
3) vectors
At the cases this diff does not use the new APIs, but uses primitive
shadow objects explicitly.

Reviewed-by: morehouse

Differential Revision: https://reviews.llvm.org/D92629

Added: 


Modified: 
llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp

Removed: 




diff  --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp 
b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
index fc784e72797c..87cf67705324 100644
--- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
@@ -419,6 +419,17 @@ class DataFlowSanitizer {
 
   bool init(Module &M);
 
+  /// Returns a zero constant with the shadow type of V's type. Until we 
support
+  /// field/index level shadow values, the following methods always return
+  /// primitive types, values or zero constants.
+  Constant *getZeroShadow(Value *V);
+  /// Checks if V is a zero shadow.
+  bool isZeroShadow(Value *V);
+  /// Returns the shadow type of OrigTy.
+  Type *getShadowTy(Type *OrigTy);
+  /// Returns the shadow type of of V's type.
+  Type *getShadowTy(Value *V);
+
 public:
   DataFlowSanitizer(const std::vector &ABIListFiles);
 
@@ -458,10 +469,10 @@ struct DFSanFunction {
   /// Computes the shadow address for a given function argument.
   ///
   /// Shadow = ArgTLS+ArgOffset.
-  Value *getArgTLS(unsigned ArgOffset, IRBuilder<> &IRB);
+  Value *getArgTLS(Type *T, unsigned ArgOffset, IRBuilder<> &IRB);
 
   /// Computes the shadow address for a retval.
-  Value *getRetvalTLS(IRBuilder<> &IRB);
+  Value *getRetvalTLS(Type *T, IRBuilder<> &IRB);
 
   Value *getShadow(Value *V);
   void setShadow(Instruction *I, Value *Shadow);
@@ -580,6 +591,20 @@ TransformedFunction 
DataFlowSanitizer::getCustomFunctionType(FunctionType *T) {
   ArgumentIndexMapping);
 }
 
+bool DataFlowSanitizer::isZeroShadow(Value *V) {
+  return ZeroPrimitiveShadow == V;
+}
+
+Constant *DataFlowSanitizer::getZeroShadow(Value *V) {
+  return ZeroPrimitiveShadow;
+}
+
+Type *DataFlowSanitizer::getShadowTy(Type *OrigTy) { return PrimitiveShadowTy; 
}
+
+Type *DataFlowSanitizer::getShadowTy(Value *V) {
+  return getShadowTy(V->getType());
+}
+
 bool DataFlowSanitizer::init(Module &M) {
   Triple TargetTriple(M.getTargetTriple());
   bool IsX86_64 = TargetTriple.getArch() == Triple::x86_64;
@@ -1075,17 +1100,17 @@ bool DataFlowSanitizer::runImpl(Module &M) {
  M.global_size() != InitialGlobalSize || M.size() != InitialModuleSize;
 }
 
-Value *DFSanFunction::getArgTLS(unsigned ArgOffset, IRBuilder<> &IRB) {
+Value *DFSanFunction::getArgTLS(Type *T, unsigned ArgOffset, IRBuilder<> &IRB) 
{
   Value *Base = IRB.CreatePointerCast(DFS.ArgTLS, DFS.IntptrTy);
   if (ArgOffset)
 Base = IRB.CreateAdd(Base, ConstantInt::get(DFS.IntptrTy, ArgOffset));
-  return IRB.CreateIntToPtr(Base, PointerType::get(DFS.PrimitiveShadowTy, 0),
+  return IRB.CreateIntToPtr(Base, PointerType::get(DFS.getShadowTy(T), 0),
 "_dfsarg");
 }
 
-Value *DFSanFunction::getRetvalTLS(IRBuilder<> &IRB) {
+Value *DFSanFunction::getRetvalTLS(Type *T, IRBuilder<> &IRB) {
   return IRB.CreatePointerCast(
-  DFS.RetvalTLS, PointerType::get(DFS.PrimitiveShadowTy, 0), "_dfsret");
+  DFS.RetvalTLS, PointerType::get(DFS.getShadowTy(T), 0), "_dfsret");
 }
 
 Value *DFSanFunction::getShadowForTLSArgument(Argument *A) {
@@ -1098,7 +1123,7 @@ Value *DFSanFunction::getShadowForTLSArgument(Argument 
*A) {
   continue;
 }
 
-unsigned Size = DL.getTypeAllocSize(DFS.PrimitiveShadowTy);
+unsigned Size = DL.getTypeAllocSize(DFS.getShadowTy(&FArg));
 if (A != &FArg) {
   ArgOffset += alignTo(Size, kShadowTLSAlignment);
   if (ArgOffset > kArgTLSSize)
@@ -,22 +1136,22 @@ Value *DFSanFunction::getShadowForTLSArgument(Argument 
*A) {
 
 Instruction *ArgTLSPos = &*F->getEntryBlock().begin();
 IRBuilder<> IRB(ArgTLSPos);
-Value *ArgShadowPtr = getArgTLS(ArgOffset, IRB);
-return IRB.CreateAlignedLoad(DFS.PrimitiveShadowTy, ArgShadowPtr,
+Value *ArgShadowPtr = getArgTLS(FArg.getType(), ArgOffset, IRB);
+return IRB.CreateAlignedLoad

[llvm-branch-commits] [compiler-rt] ea98116 - [dfsan] Track field/index-level shadow values in variables

2020-12-09 Thread Jianzhou Zhao via llvm-branch-commits

Author: Jianzhou Zhao
Date: 2020-12-09T19:38:35Z
New Revision: ea981165a4ef2d6e8be0655f04cc4b61604db6d4

URL: 
https://github.com/llvm/llvm-project/commit/ea981165a4ef2d6e8be0655f04cc4b61604db6d4
DIFF: 
https://github.com/llvm/llvm-project/commit/ea981165a4ef2d6e8be0655f04cc4b61604db6d4.diff

LOG: [dfsan] Track field/index-level shadow values in variables

*
* The problem
*
See motivation examples in compiler-rt/test/dfsan/pair.cpp. The current
DFSan always uses a 16bit shadow value for a variable with any type by
combining all shadow values of all bytes of the variable. So it cannot
distinguish two fields of a struct: each field's shadow value equals the
combined shadow value of all fields. This introduces an overtaint issue.

Consider a parsing function

   std::pair get_token(char* p);

where p points to a buffer to parse, the returned pair includes the next
token and the pointer to the position in the buffer after the token.

If the token is tainted, then both the returned pointer and int ar
tainted. If the parser keeps on using get_token for the rest parsing,
all the following outputs are tainted because of the tainted pointer.

The CL is the first change to address the issue.

**
* The proposed improvement
**
Eventually all fields and indices have their own shadow values in
variables and memory.

For example, variables with type {i1, i3}, [2 x i1], {[2 x i4], i8},
[2 x {i1, i1}] have shadow values with type {i16, i16}, [2 x i16],
{[2 x i16], i16}, [2 x {i16, i16}] correspondingly; variables with
primary type still have shadow values i16.

***
* An potential implementation plan
***

The idea is to adopt the change incrementially.

1) This CL
Support field-level accuracy at variables/args/ret in TLS mode,
load/store/alloca still use combined shadow values.

After the alloca promotion and SSA construction phases (>=-O1), we
assume alloca and memory operations are reduced. So if struct
variables do not relate to memory, their tracking is accurate at
field level.

2) Support field-level accuracy at alloca
3) Support field-level accuracy at load/store

These two should make O0 and real memory access work.

4) Support vector if necessary.
5) Support Args mode if necessary.
6) Support passing more accurate shadow values via custom functions if
necessary.

***
* About this CL.
***
The CL did the following

1) extended TLS arg/ret to work with aggregate types. This is similar
to what MSan does.

2) implemented how to map between an original type/value/zero-const to
its shadow type/value/zero-const.

3) extended (insert|extract)value to use field/index-level progagation.

4) for other instructions, propagation rules are combining inputs by or.
The CL converts between aggragate and primary shadow values at the
cases.

5) Custom function interfaces also need such a conversion because
all existing custom functions use i16. It is unclear whether custome
functions need more accurate shadow propagation yet.

6) Added test cases for aggregate type related cases.

Reviewed-by: morehouse

Differential Revision: https://reviews.llvm.org/D92261

Added: 
llvm/test/Instrumentation/DataFlowSanitizer/abilist_aggregate.ll
llvm/test/Instrumentation/DataFlowSanitizer/array.ll
llvm/test/Instrumentation/DataFlowSanitizer/struct.ll
llvm/test/Instrumentation/DataFlowSanitizer/vector.ll

Modified: 
compiler-rt/test/dfsan/pair.cpp
compiler-rt/test/dfsan/struct.c
llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
llvm/test/Instrumentation/DataFlowSanitizer/phi.ll
llvm/test/Instrumentation/DataFlowSanitizer/store.ll

Removed: 




diff  --git a/compiler-rt/test/dfsan/pair.cpp b/compiler-rt/test/dfsan/pair.cpp
index 830fe393b17b..52fa8bdde7e8 100644
--- a/compiler-rt/test/dfsan/pair.cpp
+++ b/compiler-rt/test/dfsan/pair.cpp
@@ -1,4 +1,5 @@
-// RUN: %clangxx_dfsan %s -mllvm -dfsan-fast-16-labels -mllvm 
-dfsan-track-select-control-flow=false -mllvm 
-dfsan-combine-pointer-labels-on-load=false -o %t && %run %t
+// RUN: %clangxx_dfsan %s -mllvm -dfsan-fast-16-labels -mllvm 
-dfsan-track-select-control-flow=false -mllvm 
-dfsan-combine-pointer-labels-on-load=false -O0 -DO0 -o %t && %run %t
+// RUN: %clangxx_dfsan %s -mllvm -dfsan-fast-16-labels -mllvm 
-dfsan-track-select-control-flow=false -mllvm 
-dfsan-combine-pointer-labels-on-load=false -O1 -o %t && %run %t
 
 #include 
 #include 
@@ -64,29 +65,49 @@ void test_simple_constructors() {
   int i1 = pair1.second;
   int *ptr1 = pair1.first;
 
+#ifdef O0
   assert(dfsan_read_label(&i1, sizeof(i1)) == 10);
   assert(dfsan_read_label(&ptr1, sizeof(ptr1)) == 10);
+#else
+  assert(dfsan_read_label(&i1, sizeof(i1)) == 8);
+  assert(dfsan_read_label(&ptr1, sizeof(ptr1)) == 2);
+#endif
 
   std::pair pair2 = copy_pair1(pair1);
   i