aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitch Phillips <31459023+hctim@users.noreply.github.com>2024-01-22 11:55:39 +0100
committerGitHub <noreply@github.com>2024-01-22 11:55:39 +0100
commitc9f5b5c935bd12d76d4bafff61d8116cb3229972 (patch)
treee1475c6c54389030a1286e199e1cc8c10cc2a668
parentcc38cff05cfafb92bf91aadc39692ec5e12710a0 (diff)
downloadllvm-c9f5b5c935bd12d76d4bafff61d8116cb3229972.zip
llvm-c9f5b5c935bd12d76d4bafff61d8116cb3229972.tar.gz
llvm-c9f5b5c935bd12d76d4bafff61d8116cb3229972.tar.bz2
[MTE] Disable all MTE protection of globals in sections (#78443)
Previous work in this area (#70186) disabled MTE in constructor sections. Looks like I missed one, ".preinit_array". Also, in the meantime, I found an exciting feature in the linker where globals placed into an explicit section, where the section name is a valid C identifer, gets an implicit '__start_<sectionname>' and '__stop_<sectionname>' symbol as well. This is convenient for iterating over some globals, but of course iteration over differently-tagged globals in MTE explodes. Thus, disable MTE globals for anything that has a section.
-rw-r--r--clang/test/CodeGen/memtag-globals-asm.cpp8
-rw-r--r--llvm/lib/Target/AArch64/AArch64GlobalsTagging.cpp26
2 files changed, 27 insertions, 7 deletions
diff --git a/clang/test/CodeGen/memtag-globals-asm.cpp b/clang/test/CodeGen/memtag-globals-asm.cpp
index 4b76b39..186045f 100644
--- a/clang/test/CodeGen/memtag-globals-asm.cpp
+++ b/clang/test/CodeGen/memtag-globals-asm.cpp
@@ -271,6 +271,10 @@ CONSTRUCTOR(".ctors") func_t func_ctors = func_constructor;
CONSTRUCTOR(".dtors") func_t func_dtors = func_constructor;
CONSTRUCTOR(".init_array") func_t func_init_array = func_constructor;
CONSTRUCTOR(".fini_array") func_t func_fini_array = func_constructor;
+CONSTRUCTOR(".preinit_array") func_t preinit_array = func_constructor;
+CONSTRUCTOR("array_of_globals") int global1;
+CONSTRUCTOR("array_of_globals") int global2;
+CONSTRUCTOR("array_of_globals") int global_string;
// CHECK-NOT: .memtag func_constructor
// CHECK-NOT: .memtag func_init
@@ -279,3 +283,7 @@ CONSTRUCTOR(".fini_array") func_t func_fini_array = func_constructor;
// CHECK-NOT: .memtag func_dtors
// CHECK-NOT: .memtag func_init_array
// CHECK-NOT: .memtag func_fini_array
+// CHECK-NOT: .memtag preinit_array
+// CHECK-NOT: .memtag global1
+// CHECK-NOT: .memtag global2
+// CHECK-NOT: .memtag global_string
diff --git a/llvm/lib/Target/AArch64/AArch64GlobalsTagging.cpp b/llvm/lib/Target/AArch64/AArch64GlobalsTagging.cpp
index 8ce6f94..2795948 100644
--- a/llvm/lib/Target/AArch64/AArch64GlobalsTagging.cpp
+++ b/llvm/lib/Target/AArch64/AArch64GlobalsTagging.cpp
@@ -43,13 +43,25 @@ static bool shouldTagGlobal(GlobalVariable &G) {
return false;
}
- // Don't instrument function pointers that are going into various init arrays
- // via `__attribute__((section(<foo>)))`:
- // https://github.com/llvm/llvm-project/issues/69939
- if (G.hasSection() &&
- (G.getSection() == ".init" || G.getSection() == ".fini" ||
- G.getSection() == ".init_array" || G.getSection() == ".fini_array" ||
- G.getSection() == ".ctors" || G.getSection() == ".dtors")) {
+ // Globals can be placed implicitly or explicitly in sections. There's two
+ // different types of globals that meet this criteria that cause problems:
+ // 1. Function pointers that are going into various init arrays (either
+ // explicitly through `__attribute__((section(<foo>)))` or implicitly
+ // through `__attribute__((constructor)))`, such as ".(pre)init(_array)",
+ // ".fini(_array)", ".ctors", and ".dtors". These function pointers end up
+ // overaligned and overpadded, making iterating over them problematic, and
+ // each function pointer is individually tagged (so the iteration over
+ // them causes SIGSEGV/MTE[AS]ERR).
+ // 2. Global variables put into an explicit section, where the section's name
+ // is a valid C-style identifier. The linker emits a `__start_<name>` and
+ // `__stop_<na,e>` symbol for the section, so that you can iterate over
+ // globals within this section. Unfortunately, again, these globals would
+ // be tagged and so iteration causes SIGSEGV/MTE[AS]ERR.
+ //
+ // To mitigate both these cases, and because specifying a section is rare
+ // outside of these two cases, disable MTE protection for globals in any
+ // section.
+ if (G.hasSection()) {
Meta.Memtag = false;
G.setSanitizerMetadata(Meta);
return false;