[llvm-branch-commits] [compiler-rt] [TySan] Fix struct access with different bases (PR #108385)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Nov 26 08:44:59 PST 2024


https://github.com/gbMattN updated https://github.com/llvm/llvm-project/pull/108385

>From 4f5a7f198988a45fe64b9d1ba88e68a6d7f14e32 Mon Sep 17 00:00:00 2001
From: Matthew Nagy <gbmatt at tiger-linux2.domain.snsys.com>
Date: Thu, 12 Sep 2024 12:36:57 +0000
Subject: [PATCH 1/3] [TySan] Fix struct access with different bases

---
 compiler-rt/lib/tysan/tysan.cpp               |  5 +++
 .../tysan/struct-offset-different-base.cpp    | 33 +++++++++++++++++++
 2 files changed, 38 insertions(+)
 create mode 100644 compiler-rt/test/tysan/struct-offset-different-base.cpp

diff --git a/compiler-rt/lib/tysan/tysan.cpp b/compiler-rt/lib/tysan/tysan.cpp
index f1b6bdcf0d8261..c339a0fca11397 100644
--- a/compiler-rt/lib/tysan/tysan.cpp
+++ b/compiler-rt/lib/tysan/tysan.cpp
@@ -129,6 +129,11 @@ static bool isAliasingLegalUp(tysan_type_descriptor *TDA,
           break;
       }
 
+      // This offset can't be negative. Therefore we must be accessing something
+      // partially inside the last type
+      if (TDA->Struct.Members[Idx].Offset > OffsetA)
+        Idx -= 1;
+        
       OffsetA -= TDA->Struct.Members[Idx].Offset;
       TDA = TDA->Struct.Members[Idx].Type;
     } else {
diff --git a/compiler-rt/test/tysan/struct-offset-different-base.cpp b/compiler-rt/test/tysan/struct-offset-different-base.cpp
new file mode 100644
index 00000000000000..3e1d6f2a6a42f5
--- /dev/null
+++ b/compiler-rt/test/tysan/struct-offset-different-base.cpp
@@ -0,0 +1,33 @@
+// RUN: %clangxx_tysan -O0 %s -o %t && %run %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out
+
+// Modified reproducer from https://github.com/llvm/llvm-project/issues/105960
+
+#include <stdio.h>
+
+struct inner {
+	char buffer;
+	int i;
+};
+
+void init_inner(inner *iPtr) {
+	iPtr->i = 0;
+}
+
+struct outer {
+	inner foo;
+    char buffer;
+};
+
+int main(void) {
+    outer *l = new outer();
+
+    init_inner(&l->foo);
+    
+    int access_offsets_with_different_base = l->foo.i;
+    printf("%d\n", access_offsets_with_different_base);
+    
+    return 0;
+}
+
+// CHECK-NOT: ERROR: TypeSanitizer: type-aliasing-violation

>From 6f795458c4c16522533dbdcb4d8ace299bfda9ff Mon Sep 17 00:00:00 2001
From: gbMattN <matthew.nagy at sony.com>
Date: Tue, 12 Nov 2024 17:05:44 +0000
Subject: [PATCH 2/3] Changed test to check for output

---
 compiler-rt/test/tysan/struct-offset-different-base.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/compiler-rt/test/tysan/struct-offset-different-base.cpp b/compiler-rt/test/tysan/struct-offset-different-base.cpp
index 3e1d6f2a6a42f5..4563f7025bea48 100644
--- a/compiler-rt/test/tysan/struct-offset-different-base.cpp
+++ b/compiler-rt/test/tysan/struct-offset-different-base.cpp
@@ -1,5 +1,5 @@
 // RUN: %clangxx_tysan -O0 %s -o %t && %run %t >%t.out 2>&1
-// RUN: FileCheck %s < %t.out
+// RUN: FileCheck %s --implicit-check-not ERROR < %t.out
 
 // Modified reproducer from https://github.com/llvm/llvm-project/issues/105960
 
@@ -11,7 +11,7 @@ struct inner {
 };
 
 void init_inner(inner *iPtr) {
-	iPtr->i = 0;
+	iPtr->i = 200;
 }
 
 struct outer {
@@ -25,9 +25,9 @@ int main(void) {
     init_inner(&l->foo);
     
     int access_offsets_with_different_base = l->foo.i;
-    printf("%d\n", access_offsets_with_different_base);
+    printf("Accessed value is %d\n", access_offsets_with_different_base);
     
     return 0;
 }
 
-// CHECK-NOT: ERROR: TypeSanitizer: type-aliasing-violation
+// CHECK: Accessed value is 200

>From 2d434d0f6e675ea4eeff5a9fbe5d31c72b54799d Mon Sep 17 00:00:00 2001
From: gbMattN <matthew.nagy at sony.com>
Date: Tue, 26 Nov 2024 16:44:43 +0000
Subject: [PATCH 3/3] More format changes

---
 .../tysan/struct-offset-different-base.cpp    | 28 +++++++++----------
 1 file changed, 13 insertions(+), 15 deletions(-)

diff --git a/compiler-rt/test/tysan/struct-offset-different-base.cpp b/compiler-rt/test/tysan/struct-offset-different-base.cpp
index 4563f7025bea48..da0efd2cb6503c 100644
--- a/compiler-rt/test/tysan/struct-offset-different-base.cpp
+++ b/compiler-rt/test/tysan/struct-offset-different-base.cpp
@@ -6,28 +6,26 @@
 #include <stdio.h>
 
 struct inner {
-	char buffer;
-	int i;
+  char buffer;
+  int i;
 };
 
-void init_inner(inner *iPtr) {
-	iPtr->i = 200;
-}
+void init_inner(inner *iPtr) { iPtr->i = 200; }
 
 struct outer {
-	inner foo;
-    char buffer;
+  inner foo;
+  char buffer;
 };
 
 int main(void) {
-    outer *l = new outer();
-
-    init_inner(&l->foo);
-    
-    int access_offsets_with_different_base = l->foo.i;
-    printf("Accessed value is %d\n", access_offsets_with_different_base);
-    
-    return 0;
+  outer *l = new outer();
+
+  init_inner(&l->foo);
+
+  int access_offsets_with_different_base = l->foo.i;
+  printf("Accessed value is %d\n", access_offsets_with_different_base);
+
+  return 0;
 }
 
 // CHECK: Accessed value is 200



More information about the llvm-branch-commits mailing list