[MTE] Add memtag_globals as a sanitizer target.
MTE globals needs four pieces:
1. (done) clang/llvm to produce objfiles with MTE globals metadata
2. (in flight, https://reviews.llvm.org/D152921) lld to process the metadata in the objfiles, and produce information in each DSO describing the global variables that need to be tagged (alongside some other stuff).
3. (this patch) android to handle the new sanitizer
4. (not yet sent) bionic's libc/linker to interpret the information in each DSO, and tag the global variables.
Because #2 will take some time to come through the toolchain rolls, and #3 and #4 can be landed asynchronously, we can land this ahead of time. Should make my life easier by preventing constant rebases.
Bug: N/A
Test: Build {libc, libm, libc++, libm, and libnetd} in internal master
with these patches and an experimental compiler with the lld support.
Also, `SANITIZE_TARGET=memtag_globals m` here with in-tree compiler
without lld support.
Change-Id: Ie7882d474d4d776232de3a3d571a82274df14bf0
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 6e732b6..2961666 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -99,6 +99,7 @@
Fuzzer
Memtag_heap
Memtag_stack
+ Memtag_globals
cfi // cfi is last to prevent it running before incompatible mutators
)
@@ -111,6 +112,7 @@
Fuzzer,
Memtag_heap,
Memtag_stack,
+ Memtag_globals,
cfi, // cfi is last to prevent it running before incompatible mutators
}
@@ -133,6 +135,8 @@
return "memtag_heap"
case Memtag_stack:
return "memtag_stack"
+ case Memtag_globals:
+ return "memtag_globals"
case Fuzzer:
return "fuzzer"
default:
@@ -151,6 +155,8 @@
return "memtag_heap"
case Memtag_stack:
return "memtag_stack"
+ case Memtag_globals:
+ return "memtag_globals"
case tsan:
return "thread"
case intOverflow:
@@ -172,7 +178,7 @@
sanitizer := &sanitizerSplitMutator{t}
ctx.TopDown(t.variationName()+"_markapexes", sanitizer.markSanitizableApexesMutator)
ctx.Transition(t.variationName(), sanitizer)
- case Memtag_heap, Memtag_stack, intOverflow:
+ case Memtag_heap, Memtag_stack, Memtag_globals, intOverflow:
// do nothing
default:
panic(fmt.Errorf("unknown SanitizerType %d", t))
@@ -213,6 +219,8 @@
return true
case Memtag_stack:
return true
+ case Memtag_globals:
+ return true
default:
return false
}
@@ -267,6 +275,9 @@
// Memory-tagging stack instrumentation, only available on arm64
// Adds instrumentation to detect stack buffer overflows and use-after-scope using MTE.
Memtag_stack *bool `android:"arch_variant"`
+ // Memory-tagging globals instrumentation, only available on arm64
+ // Adds instrumentation to detect global buffer overflows using MTE.
+ Memtag_globals *bool `android:"arch_variant"`
// A modifier for ASAN and HWASAN for write only instrumentation
Writeonly *bool `android:"arch_variant"`
@@ -342,6 +353,8 @@
Memtag_heap *bool `blueprint:"mutated"`
// Whether Memory-tagging stack instrumentation is enabled for this module
Memtag_stack *bool `blueprint:"mutated"`
+ // Whether Memory-tagging globals instrumentation is enabled for this module
+ Memtag_globals *bool `android:"arch_variant"`
// Whether a modifier for ASAN and HWASAN for write only instrumentation is enabled for this
// module
@@ -425,6 +438,7 @@
p.Integer_overflow = userProps.Integer_overflow
p.Memtag_heap = userProps.Memtag_heap
p.Memtag_stack = userProps.Memtag_stack
+ p.Memtag_globals = userProps.Memtag_globals
p.Safestack = userProps.Safestack
p.Scs = userProps.Scs
p.Scudo = userProps.Scudo
@@ -552,6 +566,10 @@
s.Memtag_stack = proptools.BoolPtr(true)
}
+ if found, globalSanitizers = removeFromList("memtag_globals", globalSanitizers); found && s.Memtag_globals == nil {
+ s.Memtag_globals = proptools.BoolPtr(true)
+ }
+
if len(globalSanitizers) > 0 {
ctx.ModuleErrorf("unknown global sanitizer option %s", globalSanitizers[0])
}
@@ -632,6 +650,7 @@
if ctx.Arch().ArchType != android.Arm64 || !ctx.toolchain().Bionic() || ctx.Host() {
s.Memtag_heap = nil
s.Memtag_stack = nil
+ s.Memtag_globals = nil
}
// Also disable CFI if ASAN is enabled.
@@ -641,6 +660,7 @@
// HWASAN and ASAN win against MTE.
s.Memtag_heap = nil
s.Memtag_stack = nil
+ s.Memtag_globals = nil
}
// Disable sanitizers that depend on the UBSan runtime for windows/darwin builds.
@@ -711,7 +731,8 @@
if ctx.Os() != android.Windows && (Bool(s.All_undefined) || Bool(s.Undefined) || Bool(s.Address) || Bool(s.Thread) ||
Bool(s.Fuzzer) || Bool(s.Safestack) || Bool(s.Cfi) || Bool(s.Integer_overflow) || len(s.Misc_undefined) > 0 ||
- Bool(s.Scudo) || Bool(s.Hwaddress) || Bool(s.Scs) || Bool(s.Memtag_heap) || Bool(s.Memtag_stack)) {
+ Bool(s.Scudo) || Bool(s.Hwaddress) || Bool(s.Scs) || Bool(s.Memtag_heap) || Bool(s.Memtag_stack) ||
+ Bool(s.Memtag_globals)) {
sanitize.Properties.SanitizerEnabled = true
}
@@ -887,7 +908,7 @@
flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--no-fatal-warnings")
}
- if (Bool(sanProps.Memtag_heap) || Bool(sanProps.Memtag_stack)) && ctx.binary() {
+ if (Bool(sanProps.Memtag_heap) || Bool(sanProps.Memtag_stack) || Bool(sanProps.Memtag_globals)) && ctx.binary() {
if Bool(sanProps.Diag.Memtag_heap) {
flags.Local.LdFlags = append(flags.Local.LdFlags, "-fsanitize-memtag-mode=sync")
} else {
@@ -1010,6 +1031,8 @@
return s.Properties.SanitizeMutated.Memtag_heap
case Memtag_stack:
return s.Properties.SanitizeMutated.Memtag_stack
+ case Memtag_globals:
+ return s.Properties.SanitizeMutated.Memtag_globals
case Fuzzer:
return s.Properties.SanitizeMutated.Fuzzer
default:
@@ -1026,6 +1049,7 @@
!sanitize.isSanitizerEnabled(scs) &&
!sanitize.isSanitizerEnabled(Memtag_heap) &&
!sanitize.isSanitizerEnabled(Memtag_stack) &&
+ !sanitize.isSanitizerEnabled(Memtag_globals) &&
!sanitize.isSanitizerEnabled(Fuzzer)
}
@@ -1047,10 +1071,12 @@
sanitize.Properties.SanitizeMutated.Address = bPtr
// For ASAN variant, we need to disable Memtag_stack
sanitize.Properties.SanitizeMutated.Memtag_stack = nil
+ sanitize.Properties.SanitizeMutated.Memtag_globals = nil
case Hwasan:
sanitize.Properties.SanitizeMutated.Hwaddress = bPtr
// For HWAsan variant, we need to disable Memtag_stack
sanitize.Properties.SanitizeMutated.Memtag_stack = nil
+ sanitize.Properties.SanitizeMutated.Memtag_globals = nil
case tsan:
sanitize.Properties.SanitizeMutated.Thread = bPtr
case intOverflow:
@@ -1064,6 +1090,8 @@
case Memtag_stack:
sanitize.Properties.SanitizeMutated.Memtag_stack = bPtr
// We do not need to disable ASAN or HWASan here, as there is no Memtag_stack variant.
+ case Memtag_globals:
+ sanitize.Properties.Sanitize.Memtag_globals = bPtr
case Fuzzer:
sanitize.Properties.SanitizeMutated.Fuzzer = bPtr
default:
@@ -1551,6 +1579,13 @@
sanitizers = append(sanitizers, "memtag-stack")
}
+ if Bool(sanProps.Memtag_globals) {
+ sanitizers = append(sanitizers, "memtag-globals")
+ // TODO(mitchp): For now, enable memtag-heap with memtag-globals because the linker
+ // isn't new enough (https://reviews.llvm.org/differential/changeset/?ref=4243566).
+ sanitizers = append(sanitizers, "memtag-heap")
+ }
+
if Bool(sanProps.Fuzzer) {
sanitizers = append(sanitizers, "fuzzer-no-link")
}