diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-07-07 04:46:16 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-07-07 04:46:16 +0000 |
commit | 2ce6e8be8e2dd5dbed108e6d5387e4bd21c3d04c (patch) | |
tree | 77dc031614745bb406dbd90cea9a082a1b5cdd54 /compiler_wrapper/sanitizer_flags.go | |
parent | 904b3e949a93a8953db41e41b256a5b27debeed4 (diff) | |
parent | 40214b48188358a80b7478bfff21d4814dd9177c (diff) | |
download | toolchain-utils-android14-mainline-art-release.tar.gz |
Snap for 10453563 from 40214b48188358a80b7478bfff21d4814dd9177c to mainline-art-releaseaml_art_341711000aml_art_341615020aml_art_341514450aml_art_341514410aml_art_341411300aml_art_341311100aml_art_341110110aml_art_341110060aml_art_341010050aml_art_340915060android14-mainline-art-release
Change-Id: Ic798bced996e8800fcd5f3f45be364c0b6d53417
Diffstat (limited to 'compiler_wrapper/sanitizer_flags.go')
-rw-r--r-- | compiler_wrapper/sanitizer_flags.go | 93 |
1 files changed, 69 insertions, 24 deletions
diff --git a/compiler_wrapper/sanitizer_flags.go b/compiler_wrapper/sanitizer_flags.go index da0a64b3..58312cc4 100644 --- a/compiler_wrapper/sanitizer_flags.go +++ b/compiler_wrapper/sanitizer_flags.go @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium OS Authors. All rights reserved. +// Copyright 2019 The ChromiumOS Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -8,34 +8,79 @@ import ( "strings" ) +// Returns whether the flag turns on 'invasive' sanitizers. These are sanitizers incompatible with +// things like FORTIFY, since they require meaningful runtime support, intercept libc calls, etc. +func isInvasiveSanitizerFlag(flag string) bool { + // There are a few valid spellings here: + // -fsanitize=${sanitizer_list}, which enables the given sanitizers + // -fsanitize-trap=${sanitizer_list}, which specifies sanitizer behavior _if_ these + // sanitizers are already enabled. + // -fsanitize-recover=${sanitizer_list}, which also specifies sanitizer behavior _if_ + // these sanitizers are already enabled. + // -fsanitize-ignorelist=/path/to/file, which designates a config file for sanitizers. + // + // All we care about is the first one, since that's what actually enables sanitizers. Clang + // does not accept a `-fsanitize ${sanitizer_list}` spelling of this flag. + fsanitize := "-fsanitize=" + if !strings.HasPrefix(flag, fsanitize) { + return false + } + + sanitizers := flag[len(fsanitize):] + if sanitizers == "" { + return false + } + + for _, sanitizer := range strings.Split(sanitizers, ",") { + // Keep an allowlist of sanitizers known to not cause issues. + switch sanitizer { + case "alignment", "array-bounds", "bool", "bounds", "builtin", "enum", + "float-cast-overflow", "integer-divide-by-zero", "local-bounds", + "nullability", "nullability-arg", "nullability-assign", + "nullability-return", "null", "return", "returns-nonnull-attribute", + "shift-base", "shift-exponent", "shift", "unreachable", "vla-bound": + // These sanitizers are lightweight. Ignore them. + default: + return true + } + } + return false +} + func processSanitizerFlags(builder *commandBuilder) { hasSanitizeFlags := false + // TODO: This doesn't take -fno-sanitize flags into account. This doesn't seem to be an + // issue in practice. for _, arg := range builder.args { - // TODO: This should probably be -fsanitize= to not match on - // e.g. -fsanitize-blocklist - if arg.fromUser { - if strings.HasPrefix(arg.value, "-fsanitize") { - hasSanitizeFlags = true - } + if arg.fromUser && isInvasiveSanitizerFlag(arg.value) { + hasSanitizeFlags = true + break } } - if hasSanitizeFlags { - // Flags not supported by sanitizers (ASan etc.) - unsupportedSanitizerFlags := map[string]bool{ - "-D_FORTIFY_SOURCE=1": true, - "-D_FORTIFY_SOURCE=2": true, - "-Wl,--no-undefined": true, - "-Wl,-z,defs": true, - } - builder.transformArgs(func(arg builderArg) string { - // TODO: This is a bug in the old wrapper to not filter - // non user args for gcc. Fix this once we don't compare to the old wrapper anymore. - if (builder.target.compilerType != gccType || arg.fromUser) && - unsupportedSanitizerFlags[arg.value] { - return "" - } - return arg.value - }) + if !hasSanitizeFlags { + return + } + + // Flags not supported by sanitizers (ASan etc.) + unsupportedSanitizerFlags := map[string]bool{ + "-D_FORTIFY_SOURCE=1": true, + "-D_FORTIFY_SOURCE=2": true, + "-Wl,--no-undefined": true, + "-Wl,-z,defs": true, } + + builder.transformArgs(func(arg builderArg) string { + // TODO: This is a bug in the old wrapper to not filter + // non user args for gcc. Fix this once we don't compare to the old wrapper anymore. + if (builder.target.compilerType != gccType || arg.fromUser) && + unsupportedSanitizerFlags[arg.value] { + return "" + } + return arg.value + }) + + builder.filterArgPairs(func(arg1, arg2 builderArg) bool { + return !(arg1.value == "-Wl,-z" && arg2.value == "-Wl,defs") + }) } |