Loading cc/sanitize.go +48 −21 Original line number Diff line number Diff line Loading @@ -77,6 +77,7 @@ var ( "-fno-sanitize-recover=integer,undefined"} hwasanGlobalOptions = []string{"heap_history_size=1023", "stack_history_size=512", "export_memory_stats=0", "max_malloc_fill_size=4096", "malloc_fill_byte=0"} memtagStackCommonFlags = []string{"-march=armv8-a+memtag"} ) type SanitizerType int Loading @@ -89,6 +90,7 @@ const ( scs Fuzzer Memtag_heap Memtag_stack cfi // cfi is last to prevent it running before incompatible mutators ) Loading @@ -100,6 +102,7 @@ var Sanitizers = []SanitizerType{ scs, Fuzzer, Memtag_heap, Memtag_stack, cfi, // cfi is last to prevent it running before incompatible mutators } Loading @@ -120,6 +123,8 @@ func (t SanitizerType) variationName() string { return "scs" case Memtag_heap: return "memtag_heap" case Memtag_stack: return "memtag_stack" case Fuzzer: return "fuzzer" default: Loading @@ -136,6 +141,8 @@ func (t SanitizerType) name() string { return "hwaddress" case Memtag_heap: return "memtag_heap" case Memtag_stack: return "memtag_stack" case tsan: return "thread" case intOverflow: Loading @@ -157,7 +164,7 @@ func (t SanitizerType) registerMutators(ctx android.RegisterMutatorsContext) { sanitizer := &sanitizerSplitMutator{t} ctx.TopDown(t.variationName()+"_markapexes", sanitizer.markSanitizableApexesMutator) ctx.Transition(t.variationName(), sanitizer) case Memtag_heap, intOverflow: case Memtag_heap, Memtag_stack, intOverflow: // do nothing default: panic(fmt.Errorf("unknown SanitizerType %d", t)) Loading @@ -182,6 +189,8 @@ func (*Module) SanitizerSupported(t SanitizerType) bool { return true case Memtag_heap: return true case Memtag_stack: return true default: return false } Loading Loading @@ -233,6 +242,9 @@ type SanitizeUserProps struct { // Memory-tagging, only available on arm64 // if diag.memtag unset or false, enables async memory tagging Memtag_heap *bool `android:"arch_variant"` // 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"` // A modifier for ASAN and HWASAN for write only instrumentation Writeonly *bool `android:"arch_variant"` Loading Loading @@ -318,7 +330,7 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) { return } // cc_test targets default to SYNC MemTag unless explicitly set to ASYNC (via diag: {memtag_heap}). // cc_test targets default to SYNC MemTag unless explicitly set to ASYNC (via diag: {memtag_heap: false}). if ctx.testBinary() { if s.Memtag_heap == nil { s.Memtag_heap = proptools.BoolPtr(true) Loading Loading @@ -404,6 +416,10 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) { } } if found, globalSanitizers = removeFromList("memtag_stack", globalSanitizers); found && s.Memtag_stack == nil { s.Memtag_stack = proptools.BoolPtr(true) } if len(globalSanitizers) > 0 { ctx.ModuleErrorf("unknown global sanitizer option %s", globalSanitizers[0]) } Loading Loading @@ -472,12 +488,16 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) { // Memtag_heap is only implemented on AArch64. if ctx.Arch().ArchType != android.Arm64 || !ctx.toolchain().Bionic() { s.Memtag_heap = nil s.Memtag_stack = nil } // Also disable CFI if ASAN is enabled. if Bool(s.Address) || Bool(s.Hwaddress) { s.Cfi = nil s.Diag.Cfi = nil // HWASAN and ASAN win against MTE. s.Memtag_heap = nil s.Memtag_stack = nil } // Disable sanitizers that depend on the UBSan runtime for windows/darwin builds. Loading Loading @@ -534,7 +554,7 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) { 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.Scudo) || Bool(s.Hwaddress) || Bool(s.Scs) || Bool(s.Memtag_heap) || Bool(s.Memtag_stack)) { sanitize.Properties.SanitizerEnabled = true } Loading Loading @@ -691,6 +711,20 @@ func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags) Flags { } } if Bool(sanitize.Properties.Sanitize.Memtag_stack) { flags.Local.CFlags = append(flags.Local.CFlags, memtagStackCommonFlags...) flags.Local.AsFlags = append(flags.Local.AsFlags, memtagStackCommonFlags...) flags.Local.LdFlags = append(flags.Local.LdFlags, memtagStackCommonFlags...) } if (Bool(sanitize.Properties.Sanitize.Memtag_heap) || Bool(sanitize.Properties.Sanitize.Memtag_stack)) && ctx.binary() { if Bool(sanitize.Properties.Sanitize.Diag.Memtag_heap) { flags.Local.LdFlags = append(flags.Local.LdFlags, "-fsanitize-memtag-mode=sync") } else { flags.Local.LdFlags = append(flags.Local.LdFlags, "-fsanitize-memtag-mode=async") } } if Bool(sanitize.Properties.Sanitize.Integer_overflow) { flags.Local.CFlags = append(flags.Local.CFlags, intOverflowCflags...) } Loading Loading @@ -804,6 +838,8 @@ func (sanitize *sanitize) getSanitizerBoolPtr(t SanitizerType) *bool { return sanitize.Properties.Sanitize.Scs case Memtag_heap: return sanitize.Properties.Sanitize.Memtag_heap case Memtag_stack: return sanitize.Properties.Sanitize.Memtag_stack case Fuzzer: return sanitize.Properties.Sanitize.Fuzzer default: Loading @@ -819,6 +855,7 @@ func (sanitize *sanitize) isUnsanitizedVariant() bool { !sanitize.isSanitizerEnabled(cfi) && !sanitize.isSanitizerEnabled(scs) && !sanitize.isSanitizerEnabled(Memtag_heap) && !sanitize.isSanitizerEnabled(Memtag_stack) && !sanitize.isSanitizerEnabled(Fuzzer) } Loading Loading @@ -850,6 +887,8 @@ func (sanitize *sanitize) SetSanitizer(t SanitizerType, b bool) { sanitize.Properties.Sanitize.Scs = bPtr case Memtag_heap: sanitize.Properties.Sanitize.Memtag_heap = bPtr case Memtag_stack: sanitize.Properties.Sanitize.Memtag_stack = bPtr case Fuzzer: sanitize.Properties.Sanitize.Fuzzer = bPtr default: Loading Loading @@ -1311,23 +1350,11 @@ func sanitizerRuntimeMutator(mctx android.BottomUpMutatorContext) { } if Bool(c.sanitize.Properties.Sanitize.Memtag_heap) && c.Binary() { noteDep := "note_memtag_heap_async" if Bool(c.sanitize.Properties.Sanitize.Diag.Memtag_heap) { noteDep = "note_memtag_heap_sync" sanitizers = append(sanitizers, "memtag-heap") } // If we're using snapshots, redirect to snapshot whenever possible // TODO(b/178470649): clean manual snapshot redirections snapshot := mctx.Provider(SnapshotInfoProvider).(SnapshotInfo) if lib, ok := snapshot.StaticLibs[noteDep]; ok { noteDep = lib } depTag := StaticDepTag(true) variations := append(mctx.Target().Variations(), blueprint.Variation{Mutator: "link", Variation: "static"}) if c.Device() { variations = append(variations, c.ImageVariation()) } mctx.AddFarVariationDependencies(variations, depTag, noteDep) if Bool(c.sanitize.Properties.Sanitize.Memtag_stack) { sanitizers = append(sanitizers, "memtag-stack") } if Bool(c.sanitize.Properties.Sanitize.Fuzzer) { Loading cc/sanitize_test.go +5 −11 Original line number Diff line number Diff line Loading @@ -344,19 +344,13 @@ func (t MemtagNoteType) str() string { func checkHasMemtagNote(t *testing.T, m android.TestingModule, expected MemtagNoteType) { t.Helper() note_async := "note_memtag_heap_async" note_sync := "note_memtag_heap_sync" found := None implicits := m.Rule("ld").Implicits for _, lib := range implicits { if strings.Contains(lib.Rel(), note_async) { ldFlags := m.Rule("ld").Args["ldFlags"] if strings.Contains(ldFlags, "-fsanitize-memtag-mode=async") { found = Async break } else if strings.Contains(lib.Rel(), note_sync) { } else if strings.Contains(ldFlags, "-fsanitize-memtag-mode=sync") { found = Sync break } } if found != expected { Loading Loading
cc/sanitize.go +48 −21 Original line number Diff line number Diff line Loading @@ -77,6 +77,7 @@ var ( "-fno-sanitize-recover=integer,undefined"} hwasanGlobalOptions = []string{"heap_history_size=1023", "stack_history_size=512", "export_memory_stats=0", "max_malloc_fill_size=4096", "malloc_fill_byte=0"} memtagStackCommonFlags = []string{"-march=armv8-a+memtag"} ) type SanitizerType int Loading @@ -89,6 +90,7 @@ const ( scs Fuzzer Memtag_heap Memtag_stack cfi // cfi is last to prevent it running before incompatible mutators ) Loading @@ -100,6 +102,7 @@ var Sanitizers = []SanitizerType{ scs, Fuzzer, Memtag_heap, Memtag_stack, cfi, // cfi is last to prevent it running before incompatible mutators } Loading @@ -120,6 +123,8 @@ func (t SanitizerType) variationName() string { return "scs" case Memtag_heap: return "memtag_heap" case Memtag_stack: return "memtag_stack" case Fuzzer: return "fuzzer" default: Loading @@ -136,6 +141,8 @@ func (t SanitizerType) name() string { return "hwaddress" case Memtag_heap: return "memtag_heap" case Memtag_stack: return "memtag_stack" case tsan: return "thread" case intOverflow: Loading @@ -157,7 +164,7 @@ func (t SanitizerType) registerMutators(ctx android.RegisterMutatorsContext) { sanitizer := &sanitizerSplitMutator{t} ctx.TopDown(t.variationName()+"_markapexes", sanitizer.markSanitizableApexesMutator) ctx.Transition(t.variationName(), sanitizer) case Memtag_heap, intOverflow: case Memtag_heap, Memtag_stack, intOverflow: // do nothing default: panic(fmt.Errorf("unknown SanitizerType %d", t)) Loading @@ -182,6 +189,8 @@ func (*Module) SanitizerSupported(t SanitizerType) bool { return true case Memtag_heap: return true case Memtag_stack: return true default: return false } Loading Loading @@ -233,6 +242,9 @@ type SanitizeUserProps struct { // Memory-tagging, only available on arm64 // if diag.memtag unset or false, enables async memory tagging Memtag_heap *bool `android:"arch_variant"` // 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"` // A modifier for ASAN and HWASAN for write only instrumentation Writeonly *bool `android:"arch_variant"` Loading Loading @@ -318,7 +330,7 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) { return } // cc_test targets default to SYNC MemTag unless explicitly set to ASYNC (via diag: {memtag_heap}). // cc_test targets default to SYNC MemTag unless explicitly set to ASYNC (via diag: {memtag_heap: false}). if ctx.testBinary() { if s.Memtag_heap == nil { s.Memtag_heap = proptools.BoolPtr(true) Loading Loading @@ -404,6 +416,10 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) { } } if found, globalSanitizers = removeFromList("memtag_stack", globalSanitizers); found && s.Memtag_stack == nil { s.Memtag_stack = proptools.BoolPtr(true) } if len(globalSanitizers) > 0 { ctx.ModuleErrorf("unknown global sanitizer option %s", globalSanitizers[0]) } Loading Loading @@ -472,12 +488,16 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) { // Memtag_heap is only implemented on AArch64. if ctx.Arch().ArchType != android.Arm64 || !ctx.toolchain().Bionic() { s.Memtag_heap = nil s.Memtag_stack = nil } // Also disable CFI if ASAN is enabled. if Bool(s.Address) || Bool(s.Hwaddress) { s.Cfi = nil s.Diag.Cfi = nil // HWASAN and ASAN win against MTE. s.Memtag_heap = nil s.Memtag_stack = nil } // Disable sanitizers that depend on the UBSan runtime for windows/darwin builds. Loading Loading @@ -534,7 +554,7 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) { 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.Scudo) || Bool(s.Hwaddress) || Bool(s.Scs) || Bool(s.Memtag_heap) || Bool(s.Memtag_stack)) { sanitize.Properties.SanitizerEnabled = true } Loading Loading @@ -691,6 +711,20 @@ func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags) Flags { } } if Bool(sanitize.Properties.Sanitize.Memtag_stack) { flags.Local.CFlags = append(flags.Local.CFlags, memtagStackCommonFlags...) flags.Local.AsFlags = append(flags.Local.AsFlags, memtagStackCommonFlags...) flags.Local.LdFlags = append(flags.Local.LdFlags, memtagStackCommonFlags...) } if (Bool(sanitize.Properties.Sanitize.Memtag_heap) || Bool(sanitize.Properties.Sanitize.Memtag_stack)) && ctx.binary() { if Bool(sanitize.Properties.Sanitize.Diag.Memtag_heap) { flags.Local.LdFlags = append(flags.Local.LdFlags, "-fsanitize-memtag-mode=sync") } else { flags.Local.LdFlags = append(flags.Local.LdFlags, "-fsanitize-memtag-mode=async") } } if Bool(sanitize.Properties.Sanitize.Integer_overflow) { flags.Local.CFlags = append(flags.Local.CFlags, intOverflowCflags...) } Loading Loading @@ -804,6 +838,8 @@ func (sanitize *sanitize) getSanitizerBoolPtr(t SanitizerType) *bool { return sanitize.Properties.Sanitize.Scs case Memtag_heap: return sanitize.Properties.Sanitize.Memtag_heap case Memtag_stack: return sanitize.Properties.Sanitize.Memtag_stack case Fuzzer: return sanitize.Properties.Sanitize.Fuzzer default: Loading @@ -819,6 +855,7 @@ func (sanitize *sanitize) isUnsanitizedVariant() bool { !sanitize.isSanitizerEnabled(cfi) && !sanitize.isSanitizerEnabled(scs) && !sanitize.isSanitizerEnabled(Memtag_heap) && !sanitize.isSanitizerEnabled(Memtag_stack) && !sanitize.isSanitizerEnabled(Fuzzer) } Loading Loading @@ -850,6 +887,8 @@ func (sanitize *sanitize) SetSanitizer(t SanitizerType, b bool) { sanitize.Properties.Sanitize.Scs = bPtr case Memtag_heap: sanitize.Properties.Sanitize.Memtag_heap = bPtr case Memtag_stack: sanitize.Properties.Sanitize.Memtag_stack = bPtr case Fuzzer: sanitize.Properties.Sanitize.Fuzzer = bPtr default: Loading Loading @@ -1311,23 +1350,11 @@ func sanitizerRuntimeMutator(mctx android.BottomUpMutatorContext) { } if Bool(c.sanitize.Properties.Sanitize.Memtag_heap) && c.Binary() { noteDep := "note_memtag_heap_async" if Bool(c.sanitize.Properties.Sanitize.Diag.Memtag_heap) { noteDep = "note_memtag_heap_sync" sanitizers = append(sanitizers, "memtag-heap") } // If we're using snapshots, redirect to snapshot whenever possible // TODO(b/178470649): clean manual snapshot redirections snapshot := mctx.Provider(SnapshotInfoProvider).(SnapshotInfo) if lib, ok := snapshot.StaticLibs[noteDep]; ok { noteDep = lib } depTag := StaticDepTag(true) variations := append(mctx.Target().Variations(), blueprint.Variation{Mutator: "link", Variation: "static"}) if c.Device() { variations = append(variations, c.ImageVariation()) } mctx.AddFarVariationDependencies(variations, depTag, noteDep) if Bool(c.sanitize.Properties.Sanitize.Memtag_stack) { sanitizers = append(sanitizers, "memtag-stack") } if Bool(c.sanitize.Properties.Sanitize.Fuzzer) { Loading
cc/sanitize_test.go +5 −11 Original line number Diff line number Diff line Loading @@ -344,19 +344,13 @@ func (t MemtagNoteType) str() string { func checkHasMemtagNote(t *testing.T, m android.TestingModule, expected MemtagNoteType) { t.Helper() note_async := "note_memtag_heap_async" note_sync := "note_memtag_heap_sync" found := None implicits := m.Rule("ld").Implicits for _, lib := range implicits { if strings.Contains(lib.Rel(), note_async) { ldFlags := m.Rule("ld").Args["ldFlags"] if strings.Contains(ldFlags, "-fsanitize-memtag-mode=async") { found = Async break } else if strings.Contains(lib.Rel(), note_sync) { } else if strings.Contains(ldFlags, "-fsanitize-memtag-mode=sync") { found = Sync break } } if found != expected { Loading