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