From 75b9b40a562d8711fb6afaf321e532b097b7de6f Mon Sep 17 00:00:00 2001 From: Liz Kammer Date: Fri, 25 Jun 2021 15:19:27 -0400 Subject: [PATCH 1/4] Add comments to sanitizer properties. Test: n/a Change-Id: If71bb4683a4ae969670235c51b3f1b3af2073f91 --- cc/sanitize.go | 80 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 56 insertions(+), 24 deletions(-) diff --git a/cc/sanitize.go b/cc/sanitize.go index e95a9354d..0199897d4 100644 --- a/cc/sanitize.go +++ b/cc/sanitize.go @@ -160,24 +160,46 @@ func (t SanitizerType) incompatibleWithCfi() bool { } type SanitizeUserProps struct { + // Prevent use of any sanitizers on this module Never *bool `android:"arch_variant"` - // main sanitizers - Address *bool `android:"arch_variant"` - Thread *bool `android:"arch_variant"` + // ASan (Address sanitizer), incompatible with static binaries. + // Always runs in a diagnostic mode. + // Use of address sanitizer disables cfi sanitizer. + // Hwaddress sanitizer takes precedence over this sanitizer. + Address *bool `android:"arch_variant"` + // TSan (Thread sanitizer), incompatible with static binaries and 32 bit architectures. + // Always runs in a diagnostic mode. + // Use of thread sanitizer disables cfi and scudo sanitizers. + // Hwaddress sanitizer takes precedence over this sanitizer. + Thread *bool `android:"arch_variant"` + // HWASan (Hardware Address sanitizer). + // Use of hwasan sanitizer disables cfi, address, thread, and scudo sanitizers. Hwaddress *bool `android:"arch_variant"` - // local sanitizers - Undefined *bool `android:"arch_variant"` - All_undefined *bool `android:"arch_variant"` - Misc_undefined []string `android:"arch_variant"` - Fuzzer *bool `android:"arch_variant"` - Safestack *bool `android:"arch_variant"` - Cfi *bool `android:"arch_variant"` - Integer_overflow *bool `android:"arch_variant"` - Scudo *bool `android:"arch_variant"` - Scs *bool `android:"arch_variant"` - Memtag_heap *bool `android:"arch_variant"` + // Undefined behavior sanitizer + All_undefined *bool `android:"arch_variant"` + // Subset of undefined behavior sanitizer + Undefined *bool `android:"arch_variant"` + // List of specific undefined behavior sanitizers to enable + Misc_undefined []string `android:"arch_variant"` + // Fuzzer, incompatible with static binaries. + Fuzzer *bool `android:"arch_variant"` + // safe-stack sanitizer, incompatible with 32-bit architectures. + Safestack *bool `android:"arch_variant"` + // cfi sanitizer, incompatible with asan, hwasan, fuzzer, or Darwin + Cfi *bool `android:"arch_variant"` + // signed/unsigned integer overflow sanitizer, incompatible with Darwin. + Integer_overflow *bool `android:"arch_variant"` + // scudo sanitizer, incompatible with asan, hwasan, tsan + // This should not be used in Android 11+ : https://source.android.com/devices/tech/debug/scudo + // deprecated + Scudo *bool `android:"arch_variant"` + // shadow-call-stack sanitizer, only available on arm64 + Scs *bool `android:"arch_variant"` + // Memory-tagging, only available on arm64 + // if diag.memtag unset or false, enables async memory tagging + Memtag_heap *bool `android:"arch_variant"` // A modifier for ASAN and HWASAN for write only instrumentation Writeonly *bool `android:"arch_variant"` @@ -186,12 +208,22 @@ type SanitizeUserProps struct { // Replaces abort() on error with a human-readable error message. // Address and Thread sanitizers always run in diagnostic mode. Diag struct { - Undefined *bool `android:"arch_variant"` - Cfi *bool `android:"arch_variant"` - Integer_overflow *bool `android:"arch_variant"` - Memtag_heap *bool `android:"arch_variant"` - Misc_undefined []string `android:"arch_variant"` - No_recover []string `android:"arch_variant"` + // Undefined behavior sanitizer, diagnostic mode + Undefined *bool `android:"arch_variant"` + // cfi sanitizer, diagnostic mode, incompatible with asan, hwasan, fuzzer, or Darwin + Cfi *bool `android:"arch_variant"` + // signed/unsigned integer overflow sanitizer, diagnostic mode, incompatible with Darwin. + Integer_overflow *bool `android:"arch_variant"` + // Memory-tagging, only available on arm64 + // requires sanitizer.memtag: true + // if set, enables sync memory tagging + Memtag_heap *bool `android:"arch_variant"` + // List of specific undefined behavior sanitizers to enable in diagnostic mode + Misc_undefined []string `android:"arch_variant"` + // List of sanitizers to pass to -fno-sanitize-recover + // results in only the first detected error for these sanitizers being reported and program then + // exits with a non-zero exit code. + No_recover []string `android:"arch_variant"` } `android:"arch_variant"` // Sanitizers to run with flag configuration specified @@ -200,7 +232,9 @@ type SanitizeUserProps struct { Cfi_assembly_support *bool `android:"arch_variant"` } `android:"arch_variant"` - // value to pass to -fsanitize-recover= + // List of sanitizers to pass to -fsanitize-recover + // allows execution to continue for these sanitizers to detect multiple errors rather than only + // the first one Recover []string // value to pass to -fsanitize-blacklist @@ -208,9 +242,7 @@ type SanitizeUserProps struct { } type SanitizeProperties struct { - // Enable AddressSanitizer, ThreadSanitizer, UndefinedBehaviorSanitizer, and - // others. Please see SanitizerUserProps in build/soong/cc/sanitize.go for - // details. + // Sanitizers are not supported for Fuchsia. Sanitize SanitizeUserProps `android:"arch_variant"` SanitizerEnabled bool `blueprint:"mutated"` SanitizeDep bool `blueprint:"mutated"` From d56ddb5482c94c31abfef83d3c9c70355aaf63cf Mon Sep 17 00:00:00 2001 From: Liz Kammer Date: Mon, 21 Jun 2021 17:37:39 -0400 Subject: [PATCH 2/4] Reorganize memtag tests for clarity. Test: go test soong tests Change-Id: Id861a62bd0ff2b6a5a4354fbda939e9ebb13a2a5 --- cc/sanitize_test.go | 340 +++++++++++++++++++++++++------------------- 1 file changed, 196 insertions(+), 144 deletions(-) diff --git a/cc/sanitize_test.go b/cc/sanitize_test.go index 4430fc38f..c43547ccd 100644 --- a/cc/sanitize_test.go +++ b/cc/sanitize_test.go @@ -222,11 +222,12 @@ func (t MemtagNoteType) str() string { case Async: return "async" default: - panic("invalid note type") + panic("type_note_invalid") } } func checkHasMemtagNote(t *testing.T, m android.TestingModule, expected MemtagNoteType) { + t.Helper() note_async := "note_memtag_heap_async" note_sync := "note_memtag_heap_sync" @@ -251,75 +252,86 @@ var prepareForTestWithMemtagHeap = android.GroupFixturePreparers( android.FixtureModifyMockFS(func(fs android.MockFS) { templateBp := ` cc_test { - name: "%[1]s_test", + name: "unset_test_%[1]s", gtest: false, } cc_test { - name: "%[1]s_test_false", + name: "no_memtag_test_%[1]s", gtest: false, sanitize: { memtag_heap: false }, } cc_test { - name: "%[1]s_test_true", + name: "set_memtag_test_%[1]s", gtest: false, sanitize: { memtag_heap: true }, } cc_test { - name: "%[1]s_test_true_nodiag", + name: "set_memtag_set_async_test_%[1]s", gtest: false, sanitize: { memtag_heap: true, diag: { memtag_heap: false } }, } cc_test { - name: "%[1]s_test_true_diag", + name: "set_memtag_set_sync_test_%[1]s", gtest: false, sanitize: { memtag_heap: true, diag: { memtag_heap: true } }, } - cc_binary { - name: "%[1]s_binary", + cc_test { + name: "unset_memtag_set_sync_test_%[1]s", + gtest: false, + sanitize: { diag: { memtag_heap: true } }, } cc_binary { - name: "%[1]s_binary_false", + name: "unset_binary_%[1]s", + } + + cc_binary { + name: "no_memtag_binary_%[1]s", sanitize: { memtag_heap: false }, } cc_binary { - name: "%[1]s_binary_true", + name: "set_memtag_binary_%[1]s", sanitize: { memtag_heap: true }, } cc_binary { - name: "%[1]s_binary_true_nodiag", + name: "set_memtag_set_async_binary_%[1]s", sanitize: { memtag_heap: true, diag: { memtag_heap: false } }, } cc_binary { - name: "%[1]s_binary_true_diag", + name: "set_memtag_set_sync_binary_%[1]s", sanitize: { memtag_heap: true, diag: { memtag_heap: true } }, } + + cc_binary { + name: "unset_memtag_set_sync_binary_%[1]s", + sanitize: { diag: { memtag_heap: true } }, + } ` - subdirDefaultBp := fmt.Sprintf(templateBp, "default") - subdirExcludeBp := fmt.Sprintf(templateBp, "exclude") - subdirSyncBp := fmt.Sprintf(templateBp, "sync") - subdirAsyncBp := fmt.Sprintf(templateBp, "async") + subdirNoOverrideBp := fmt.Sprintf(templateBp, "no_override") + subdirOverrideDefaultDisableBp := fmt.Sprintf(templateBp, "override_default_disable") + subdirSyncBp := fmt.Sprintf(templateBp, "override_default_sync") + subdirAsyncBp := fmt.Sprintf(templateBp, "override_default_async") fs.Merge(android.MockFS{ - "subdir_default/Android.bp": []byte(subdirDefaultBp), - "subdir_exclude/Android.bp": []byte(subdirExcludeBp), - "subdir_sync/Android.bp": []byte(subdirSyncBp), - "subdir_async/Android.bp": []byte(subdirAsyncBp), + "subdir_no_override/Android.bp": []byte(subdirNoOverrideBp), + "subdir_override_default_disable/Android.bp": []byte(subdirOverrideDefaultDisableBp), + "subdir_sync/Android.bp": []byte(subdirSyncBp), + "subdir_async/Android.bp": []byte(subdirAsyncBp), }) }), android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { - variables.MemtagHeapExcludePaths = []string{"subdir_exclude"} - // "subdir_exclude" is covered by both include and exclude paths. Exclude wins. - variables.MemtagHeapSyncIncludePaths = []string{"subdir_sync", "subdir_exclude"} - variables.MemtagHeapAsyncIncludePaths = []string{"subdir_async", "subdir_exclude"} + variables.MemtagHeapExcludePaths = []string{"subdir_override_default_disable"} + // "subdir_override_default_disable" is covered by both include and override_default_disable paths. override_default_disable wins. + variables.MemtagHeapSyncIncludePaths = []string{"subdir_sync", "subdir_override_default_disable"} + variables.MemtagHeapAsyncIncludePaths = []string{"subdir_async", "subdir_override_default_disable"} }), ) @@ -332,53 +344,67 @@ func TestSanitizeMemtagHeap(t *testing.T) { ).RunTest(t) ctx := result.TestContext - checkHasMemtagNote(t, ctx.ModuleForTests("default_test", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("default_test_false", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true_nodiag", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true_diag", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_no_override", variant), None) + checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_async", variant), None) + checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_disable", variant), None) + checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_sync", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("default_binary", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_false", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true_nodiag", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true_diag", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_no_override", variant), None) + checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_async", variant), None) + checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_disable", variant), None) + checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_sync", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_false", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true_nodiag", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true_diag", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_no_override", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_async", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_disable", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_sync", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_false", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true_nodiag", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true_diag", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_no_override", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_async", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_disable", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_sync", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("async_test", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("async_test_false", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true_nodiag", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true_diag", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_no_override", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_async", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_disable", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_sync", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("async_binary", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_false", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true_nodiag", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true_diag", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_no_override", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_async", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_disable", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_sync", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("sync_test", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_false", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true_nodiag", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true_diag", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_no_override", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_async", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_disable", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_sync", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_false", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true_nodiag", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true_diag", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_no_override", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_async", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_disable", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_sync", variant), Sync) + + // should sanitize: { diag: { memtag: true } } result in Sync instead of None here? + checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_no_override", variant), None) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_async", variant), Sync) + // should sanitize: { diag: { memtag: true } } result in Sync instead of None here? + checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_disable", variant), None) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_sync", variant), Sync) + + checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_no_override", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_async", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_disable", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_sync", variant), Sync) + + checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_no_override", variant), None) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_async", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_disable", variant), None) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_sync", variant), Sync) + + checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_no_override", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_async", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_disable", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_sync", variant), Sync) } func TestSanitizeMemtagHeapWithSanitizeDevice(t *testing.T) { @@ -393,53 +419,66 @@ func TestSanitizeMemtagHeapWithSanitizeDevice(t *testing.T) { ).RunTest(t) ctx := result.TestContext - checkHasMemtagNote(t, ctx.ModuleForTests("default_test", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("default_test_false", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true_nodiag", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true_diag", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_no_override", variant), None) + checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_async", variant), None) + checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_disable", variant), None) + checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_sync", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("default_binary", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_false", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true_nodiag", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true_diag", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_no_override", variant), None) + checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_async", variant), None) + checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_disable", variant), None) + checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_sync", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_false", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true_nodiag", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true_diag", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_no_override", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_async", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_disable", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_sync", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_false", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true_nodiag", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true_diag", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_no_override", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_async", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_disable", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_sync", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("async_test", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("async_test_false", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true_nodiag", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true_diag", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_no_override", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_async", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_disable", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_sync", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("async_binary", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_false", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true_nodiag", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true_diag", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_no_override", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_async", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_disable", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_sync", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("sync_test", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_false", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true_nodiag", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true_diag", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_no_override", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_async", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_disable", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_sync", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_false", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true_nodiag", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true_diag", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_no_override", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_async", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_disable", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_sync", variant), Sync) + + checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_no_override", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_async", variant), Sync) + // should sanitize: { diag: { memtag: true } } result in Sync instead of None here? + checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_disable", variant), None) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_sync", variant), Sync) + + checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_no_override", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_async", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_disable", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_sync", variant), Sync) + + checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_no_override", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_async", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_disable", variant), None) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_sync", variant), Sync) + + checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_no_override", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_async", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_disable", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_sync", variant), Sync) } func TestSanitizeMemtagHeapWithSanitizeDeviceDiag(t *testing.T) { @@ -455,51 +494,64 @@ func TestSanitizeMemtagHeapWithSanitizeDeviceDiag(t *testing.T) { ).RunTest(t) ctx := result.TestContext - checkHasMemtagNote(t, ctx.ModuleForTests("default_test", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("default_test_false", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true_nodiag", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true_diag", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_no_override", variant), None) + checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_async", variant), None) + checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_disable", variant), None) + checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_sync", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("default_binary", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_false", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true_nodiag", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true_diag", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_no_override", variant), None) + checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_async", variant), None) + checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_disable", variant), None) + checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_sync", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_false", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true_nodiag", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true_diag", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_no_override", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_async", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_disable", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_sync", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_false", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true_nodiag", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true_diag", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_no_override", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_async", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_disable", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_sync", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("async_test", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("async_test_false", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true_nodiag", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true_diag", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_no_override", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_async", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_disable", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_sync", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("async_binary", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_false", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true_nodiag", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true_diag", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_no_override", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_async", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_disable", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_sync", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("sync_test", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_false", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true_nodiag", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true_diag", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_no_override", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_async", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_disable", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_sync", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_false", variant), None) - checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true_nodiag", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true_diag", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_no_override", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_async", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_disable", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_sync", variant), Sync) + + checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_no_override", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_async", variant), Sync) + // should sanitize: { diag: { memtag: true } } result in Sync instead of None here? + checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_disable", variant), None) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_sync", variant), Sync) + + checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_no_override", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_async", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_disable", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_sync", variant), Sync) + + checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_no_override", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_async", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_disable", variant), None) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_sync", variant), Sync) + + checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_no_override", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_async", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_disable", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_sync", variant), Sync) } From 7b920b4057cb6097898a5ec0292d31b096bd05b2 Mon Sep 17 00:00:00 2001 From: Liz Kammer Date: Tue, 22 Jun 2021 16:57:27 -0400 Subject: [PATCH 3/4] Update memtag code behavior to match comment. Test: go test soong tests Change-Id: I630c06f01c90256b1990c37b9236e8967a5fa316 --- cc/sanitize.go | 10 +++++++--- cc/sanitize_test.go | 12 ++++++------ 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/cc/sanitize.go b/cc/sanitize.go index 0199897d4..0ed0d47c5 100644 --- a/cc/sanitize.go +++ b/cc/sanitize.go @@ -293,9 +293,13 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) { } // cc_test targets default to SYNC MemTag unless explicitly set to ASYNC (via diag: {memtag_heap}). - if ctx.testBinary() && s.Memtag_heap == nil { - s.Memtag_heap = proptools.BoolPtr(true) - s.Diag.Memtag_heap = proptools.BoolPtr(true) + if ctx.testBinary() { + if s.Memtag_heap == nil { + s.Memtag_heap = proptools.BoolPtr(true) + } + if s.Diag.Memtag_heap == nil { + s.Diag.Memtag_heap = proptools.BoolPtr(true) + } } var globalSanitizers []string diff --git a/cc/sanitize_test.go b/cc/sanitize_test.go index c43547ccd..0070e4026 100644 --- a/cc/sanitize_test.go +++ b/cc/sanitize_test.go @@ -359,9 +359,9 @@ func TestSanitizeMemtagHeap(t *testing.T) { checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_disable", variant), Async) checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_sync", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_no_override", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_async", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_disable", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_no_override", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_async", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_disable", variant), Sync) checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_sync", variant), Sync) checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_no_override", variant), Async) @@ -434,9 +434,9 @@ func TestSanitizeMemtagHeapWithSanitizeDevice(t *testing.T) { checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_disable", variant), Async) checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_sync", variant), Sync) - checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_no_override", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_async", variant), Async) - checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_disable", variant), Async) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_no_override", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_async", variant), Sync) + checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_disable", variant), Sync) checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_sync", variant), Sync) checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_no_override", variant), Async) From 75db931843ce0b6a6f7657929ad6ee29a56c58f3 Mon Sep 17 00:00:00 2001 From: Liz Kammer Date: Wed, 7 Jul 2021 16:41:50 -0400 Subject: [PATCH 4/4] Iterate over sanitizers Test: go test soong tests Change-Id: If89b7d0b04cad79b42a08504d4fcff36e914b7a4 --- cc/cc.go | 22 +++------------------- cc/sanitize.go | 25 ++++++++++++++++++++++++- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/cc/cc.go b/cc/cc.go index ca889137e..90c023701 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -53,25 +53,9 @@ func RegisterCCBuildComponents(ctx android.RegistrationContext) { }) ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) { - ctx.TopDown("asan_deps", sanitizerDepsMutator(Asan)) - ctx.BottomUp("asan", sanitizerMutator(Asan)).Parallel() - - ctx.TopDown("hwasan_deps", sanitizerDepsMutator(Hwasan)) - ctx.BottomUp("hwasan", sanitizerMutator(Hwasan)).Parallel() - - ctx.TopDown("fuzzer_deps", sanitizerDepsMutator(Fuzzer)) - ctx.BottomUp("fuzzer", sanitizerMutator(Fuzzer)).Parallel() - - // cfi mutator shouldn't run before sanitizers that return true for - // incompatibleWithCfi() - ctx.TopDown("cfi_deps", sanitizerDepsMutator(cfi)) - ctx.BottomUp("cfi", sanitizerMutator(cfi)).Parallel() - - ctx.TopDown("scs_deps", sanitizerDepsMutator(scs)) - ctx.BottomUp("scs", sanitizerMutator(scs)).Parallel() - - ctx.TopDown("tsan_deps", sanitizerDepsMutator(tsan)) - ctx.BottomUp("tsan", sanitizerMutator(tsan)).Parallel() + for _, san := range Sanitizers { + san.registerMutators(ctx) + } ctx.TopDown("sanitize_runtime_deps", sanitizerRuntimeDepsMutator).Parallel() ctx.BottomUp("sanitize_runtime", sanitizerRuntimeMutator).Parallel() diff --git a/cc/sanitize.go b/cc/sanitize.go index 0ed0d47c5..defe8fde1 100644 --- a/cc/sanitize.go +++ b/cc/sanitize.go @@ -79,12 +79,23 @@ const ( Hwasan tsan intOverflow - cfi scs Fuzzer memtag_heap + cfi // cfi is last to prevent it running before incompatible mutators ) +var Sanitizers = []SanitizerType{ + Asan, + Hwasan, + tsan, + intOverflow, + scs, + Fuzzer, + memtag_heap, + cfi, // cfi is last to prevent it running before incompatible mutators +} + // Name of the sanitizer variation for this sanitizer type func (t SanitizerType) variationName() string { switch t { @@ -133,6 +144,18 @@ func (t SanitizerType) name() string { } } +func (t SanitizerType) registerMutators(ctx android.RegisterMutatorsContext) { + switch t { + case Asan, Hwasan, Fuzzer, scs, tsan, cfi: + ctx.TopDown(t.variationName()+"_deps", sanitizerDepsMutator(t)) + ctx.BottomUp(t.variationName(), sanitizerMutator(t)) + case memtag_heap, intOverflow: + // do nothing + default: + panic(fmt.Errorf("unknown SanitizerType %d", t)) + } +} + func (*Module) SanitizerSupported(t SanitizerType) bool { switch t { case Asan: