[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
Thu Sep 12 06:23:52 PDT 2024
https://github.com/gbMattN created https://github.com/llvm/llvm-project/pull/108385
Fixes issue #105960
If a member in a struct is also a struct, accessing a member partway through this inner struct currently causes a false positive. This is because when checking aliasing, the access offset is seen as greater than the starting offset of the inner struct, so the loop continues one iteration, and believes we are accessing the member after the inner struct.
The next member's offset is greater than the offset we are looking for, so when we subtract the next member's offset from what we are looking for, the offset underflows.
To fix this, we check if the member we think we are accessing has a greater offset than the offset we are looking for. If so, we take a step back. We cannot do this in the loop, since the loop does not check the final member. This means the penultimate member would still cause false positives.
>From 2dffe46bc8af4ccd5627478ba9546647907104cc 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] [TySan] Fix struct access with different bases
---
compiler-rt/lib/tysan/tysan.cpp | 4 +++
.../tysan/struct-offset-different-base.cpp | 31 +++++++++++++++++++
2 files changed, 35 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 f627851d049e6a..f2cb6faddf45ac 100644
--- a/compiler-rt/lib/tysan/tysan.cpp
+++ b/compiler-rt/lib/tysan/tysan.cpp
@@ -128,6 +128,10 @@ static bool isAliasingLegalUp(tysan_type_descriptor *TDA,
break;
}
+ //You can't have negative offset, you must be 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..c1ef5f8669c280
--- /dev/null
+++ b/compiler-rt/test/tysan/struct-offset-different-base.cpp
@@ -0,0 +1,31 @@
+// RUN: %clangxx_tysan -O0 %s -o %t && %run %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out
+
+#include <stdio.h>
+
+struct inner {
+ char buffer;
+ int i;
+};
+
+void init_inner(inner *list) {
+ list->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
More information about the llvm-branch-commits
mailing list