Skip to content

Commit c9f5b5c

Browse files
authored
[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.
1 parent cc38cff commit c9f5b5c

File tree

2 files changed

+27
-7
lines changed

2 files changed

+27
-7
lines changed

clang/test/CodeGen/memtag-globals-asm.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,10 @@ CONSTRUCTOR(".ctors") func_t func_ctors = func_constructor;
271271
CONSTRUCTOR(".dtors") func_t func_dtors = func_constructor;
272272
CONSTRUCTOR(".init_array") func_t func_init_array = func_constructor;
273273
CONSTRUCTOR(".fini_array") func_t func_fini_array = func_constructor;
274+
CONSTRUCTOR(".preinit_array") func_t preinit_array = func_constructor;
275+
CONSTRUCTOR("array_of_globals") int global1;
276+
CONSTRUCTOR("array_of_globals") int global2;
277+
CONSTRUCTOR("array_of_globals") int global_string;
274278

275279
// CHECK-NOT: .memtag func_constructor
276280
// CHECK-NOT: .memtag func_init
@@ -279,3 +283,7 @@ CONSTRUCTOR(".fini_array") func_t func_fini_array = func_constructor;
279283
// CHECK-NOT: .memtag func_dtors
280284
// CHECK-NOT: .memtag func_init_array
281285
// CHECK-NOT: .memtag func_fini_array
286+
// CHECK-NOT: .memtag preinit_array
287+
// CHECK-NOT: .memtag global1
288+
// CHECK-NOT: .memtag global2
289+
// CHECK-NOT: .memtag global_string

llvm/lib/Target/AArch64/AArch64GlobalsTagging.cpp

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,25 @@ static bool shouldTagGlobal(GlobalVariable &G) {
4343
return false;
4444
}
4545

46-
// Don't instrument function pointers that are going into various init arrays
47-
// via `__attribute__((section(<foo>)))`:
48-
// https://github.com/llvm/llvm-project/issues/69939
49-
if (G.hasSection() &&
50-
(G.getSection() == ".init" || G.getSection() == ".fini" ||
51-
G.getSection() == ".init_array" || G.getSection() == ".fini_array" ||
52-
G.getSection() == ".ctors" || G.getSection() == ".dtors")) {
46+
// Globals can be placed implicitly or explicitly in sections. There's two
47+
// different types of globals that meet this criteria that cause problems:
48+
// 1. Function pointers that are going into various init arrays (either
49+
// explicitly through `__attribute__((section(<foo>)))` or implicitly
50+
// through `__attribute__((constructor)))`, such as ".(pre)init(_array)",
51+
// ".fini(_array)", ".ctors", and ".dtors". These function pointers end up
52+
// overaligned and overpadded, making iterating over them problematic, and
53+
// each function pointer is individually tagged (so the iteration over
54+
// them causes SIGSEGV/MTE[AS]ERR).
55+
// 2. Global variables put into an explicit section, where the section's name
56+
// is a valid C-style identifier. The linker emits a `__start_<name>` and
57+
// `__stop_<na,e>` symbol for the section, so that you can iterate over
58+
// globals within this section. Unfortunately, again, these globals would
59+
// be tagged and so iteration causes SIGSEGV/MTE[AS]ERR.
60+
//
61+
// To mitigate both these cases, and because specifying a section is rare
62+
// outside of these two cases, disable MTE protection for globals in any
63+
// section.
64+
if (G.hasSection()) {
5365
Meta.Memtag = false;
5466
G.setSanitizerMetadata(Meta);
5567
return false;

0 commit comments

Comments
 (0)