@@ -34,6 +34,37 @@ static SanitizerMask expandKernelSanitizerMasks(SanitizerMask Mask) {
3434 return Mask;
3535}
3636
37+ static bool shouldTagGlobal (const llvm::GlobalVariable &G) {
38+ // For now, don't instrument constant data, as it'll be in .rodata anyway. It
39+ // may be worth instrumenting these in future to stop them from being used as
40+ // gadgets.
41+ if (G.getName ().starts_with (" llvm." ) || G.isThreadLocal () || G.isConstant ())
42+ return false ;
43+
44+ // Globals can be placed implicitly or explicitly in sections. There's two
45+ // different types of globals that meet this criteria that cause problems:
46+ // 1. Function pointers that are going into various init arrays (either
47+ // explicitly through `__attribute__((section(<foo>)))` or implicitly
48+ // through `__attribute__((constructor)))`, such as ".(pre)init(_array)",
49+ // ".fini(_array)", ".ctors", and ".dtors". These function pointers end up
50+ // overaligned and overpadded, making iterating over them problematic, and
51+ // each function pointer is individually tagged (so the iteration over
52+ // them causes SIGSEGV/MTE[AS]ERR).
53+ // 2. Global variables put into an explicit section, where the section's name
54+ // is a valid C-style identifier. The linker emits a `__start_<name>` and
55+ // `__stop_<name>` symbol for the section, so that you can iterate over
56+ // globals within this section. Unfortunately, again, these globals would
57+ // be tagged and so iteration causes SIGSEGV/MTE[AS]ERR.
58+ //
59+ // To mitigate both these cases, and because specifying a section is rare
60+ // outside of these two cases, disable MTE protection for globals in any
61+ // section.
62+ if (G.hasSection ())
63+ return false ;
64+
65+ return true ;
66+ }
67+
3768void SanitizerMetadata::reportGlobal (llvm::GlobalVariable *GV,
3869 SourceLocation Loc, StringRef Name,
3970 QualType Ty,
@@ -60,11 +91,15 @@ void SanitizerMetadata::reportGlobal(llvm::GlobalVariable *GV,
6091 Meta.NoHWAddress |= CGM.isInNoSanitizeList (
6192 FsanitizeArgument.Mask & SanitizerKind::HWAddress, GV, Loc, Ty);
6293
63- Meta.Memtag |=
64- static_cast <bool >(FsanitizeArgument.Mask & SanitizerKind::MemtagGlobals);
65- Meta.Memtag &= !NoSanitizeAttrSet.hasOneOf (SanitizerKind::MemTag);
66- Meta.Memtag &= !CGM.isInNoSanitizeList (
67- FsanitizeArgument.Mask & SanitizerKind::MemTag, GV, Loc, Ty);
94+ if (shouldTagGlobal (*GV)) {
95+ Meta.Memtag |=
96+ static_cast <bool >(FsanitizeArgument.Mask & SanitizerKind::MemtagGlobals);
97+ Meta.Memtag &= !NoSanitizeAttrSet.hasOneOf (SanitizerKind::MemTag);
98+ Meta.Memtag &= !CGM.isInNoSanitizeList (
99+ FsanitizeArgument.Mask & SanitizerKind::MemTag, GV, Loc, Ty);
100+ } else {
101+ Meta.Memtag = false ;
102+ }
68103
69104 Meta.IsDynInit = IsDynInit && !Meta.NoAddress &&
70105 FsanitizeArgument.has (SanitizerKind::Address) &&
0 commit comments