rust: Support global sanitizers
This CL adds Rust support for the SANITIZE_TARGET options. This CL includes a couple small fixes to related to HWASAN, ASAN, ensuring that the Never sanitize property is respected. Notably, additional llvm-args are passed to ensure that HWASAN-ified Rust/C interop works correctly. Bug: 170672854 Bug: 204915322 Test: SANITIZE_TARGET globally applies hwasan to Rust targets Change-Id: Ia904d07b4618f72cdc95c51f88961905c240ac53
This commit is contained in:
@@ -1303,6 +1303,10 @@ var _ PlatformSanitizeable = (*Module)(nil)
|
||||
func sanitizerMutator(t SanitizerType) func(android.BottomUpMutatorContext) {
|
||||
return func(mctx android.BottomUpMutatorContext) {
|
||||
if c, ok := mctx.Module().(PlatformSanitizeable); ok && c.SanitizePropDefined() {
|
||||
|
||||
// Make sure we're not setting CFI to any value if it's not supported.
|
||||
cfiSupported := mctx.Module().(PlatformSanitizeable).SanitizerSupported(cfi)
|
||||
|
||||
if c.Binary() && c.IsSanitizerEnabled(t) {
|
||||
modules := mctx.CreateVariations(t.variationName())
|
||||
modules[0].(PlatformSanitizeable).SetSanitizer(t, true)
|
||||
@@ -1323,7 +1327,6 @@ func sanitizerMutator(t SanitizerType) func(android.BottomUpMutatorContext) {
|
||||
// is redirected to the sanitized variant of the dependent module.
|
||||
defaultVariation := t.variationName()
|
||||
// Not all PlatformSanitizeable modules support the CFI sanitizer
|
||||
cfiSupported := mctx.Module().(PlatformSanitizeable).SanitizerSupported(cfi)
|
||||
mctx.SetDefaultDependencyVariation(&defaultVariation)
|
||||
|
||||
modules := mctx.CreateVariations("", t.variationName())
|
||||
@@ -1370,7 +1373,7 @@ func sanitizerMutator(t SanitizerType) func(android.BottomUpMutatorContext) {
|
||||
modules[0].(PlatformSanitizeable).SetInSanitizerDir()
|
||||
}
|
||||
|
||||
if mctx.Device() && t.incompatibleWithCfi() {
|
||||
if mctx.Device() && t.incompatibleWithCfi() && cfiSupported {
|
||||
// TODO: Make sure that cfi mutator runs "after" any of the sanitizers that
|
||||
// are incompatible with cfi
|
||||
modules[0].(PlatformSanitizeable).SetSanitizer(cfi, false)
|
||||
|
@@ -36,7 +36,7 @@ type fuzzDecorator struct {
|
||||
fuzzPackagedModule fuzz.FuzzPackagedModule
|
||||
}
|
||||
|
||||
var _ compiler = (*binaryDecorator)(nil)
|
||||
var _ compiler = (*fuzzDecorator)(nil)
|
||||
|
||||
// rust_binary produces a binary that is runnable on a device.
|
||||
func RustFuzzFactory() android.Module {
|
||||
|
@@ -15,11 +15,15 @@
|
||||
package rust
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/google/blueprint"
|
||||
"github.com/google/blueprint/proptools"
|
||||
|
||||
"android/soong/android"
|
||||
"android/soong/cc"
|
||||
"android/soong/rust/config"
|
||||
"fmt"
|
||||
"github.com/google/blueprint"
|
||||
)
|
||||
|
||||
type SanitizeProperties struct {
|
||||
@@ -59,9 +63,18 @@ var asanFlags = []string{
|
||||
"-Z sanitizer=address",
|
||||
}
|
||||
|
||||
// See cc/sanitize.go's hwasanGlobalOptions for global hwasan options.
|
||||
var hwasanFlags = []string{
|
||||
"-Z sanitizer=hwaddress",
|
||||
"-C target-feature=+tagged-globals",
|
||||
|
||||
// Flags from cc/sanitize.go hwasanFlags
|
||||
"-C llvm-args=--aarch64-enable-global-isel-at-O=-1",
|
||||
"-C llvm-args=-fast-isel=false",
|
||||
"-C llvm-args=-instcombine-lower-dbg-declare=0",
|
||||
|
||||
// Additional flags for HWASAN-ified Rust/C interop
|
||||
"-C llvm-args=--hwasan-with-ifunc",
|
||||
}
|
||||
|
||||
func boolPtr(v bool) *bool {
|
||||
@@ -79,7 +92,46 @@ func (sanitize *sanitize) props() []interface{} {
|
||||
}
|
||||
|
||||
func (sanitize *sanitize) begin(ctx BaseModuleContext) {
|
||||
s := sanitize.Properties.Sanitize
|
||||
s := &sanitize.Properties.Sanitize
|
||||
|
||||
// Never always wins.
|
||||
if Bool(s.Never) {
|
||||
return
|
||||
}
|
||||
|
||||
var globalSanitizers []string
|
||||
|
||||
if ctx.Host() {
|
||||
if !ctx.Windows() {
|
||||
globalSanitizers = ctx.Config().SanitizeHost()
|
||||
}
|
||||
} else {
|
||||
arches := ctx.Config().SanitizeDeviceArch()
|
||||
if len(arches) == 0 || android.InList(ctx.Arch().ArchType.Name, arches) {
|
||||
globalSanitizers = ctx.Config().SanitizeDevice()
|
||||
}
|
||||
}
|
||||
|
||||
if len(globalSanitizers) > 0 {
|
||||
var found bool
|
||||
|
||||
// Global Sanitizers
|
||||
if found, globalSanitizers = android.RemoveFromList("hwaddress", globalSanitizers); found && s.Hwaddress == nil {
|
||||
// TODO(b/180495975): HWASan for static Rust binaries isn't supported yet.
|
||||
if !ctx.RustModule().StaticExecutable() {
|
||||
s.Hwaddress = proptools.BoolPtr(true)
|
||||
}
|
||||
}
|
||||
|
||||
if found, globalSanitizers = android.RemoveFromList("address", globalSanitizers); found && s.Address == nil {
|
||||
s.Address = proptools.BoolPtr(true)
|
||||
}
|
||||
|
||||
if found, globalSanitizers = android.RemoveFromList("fuzzer", globalSanitizers); found && s.Fuzzer == nil {
|
||||
s.Fuzzer = proptools.BoolPtr(true)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// TODO:(b/178369775)
|
||||
// For now sanitizing is only supported on devices
|
||||
@@ -96,7 +148,17 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) {
|
||||
s.Hwaddress = nil
|
||||
}
|
||||
|
||||
if ctx.Os() == android.Android && Bool(s.Hwaddress) {
|
||||
// HWASan ramdisk (which is built from recovery) goes over some bootloader limit.
|
||||
// Keep libc instrumented so that ramdisk / vendor_ramdisk / recovery can run hwasan-instrumented code if necessary.
|
||||
if (ctx.RustModule().InRamdisk() || ctx.RustModule().InVendorRamdisk() || ctx.RustModule().InRecovery()) && !strings.HasPrefix(ctx.ModuleDir(), "bionic/libc") {
|
||||
s.Hwaddress = nil
|
||||
}
|
||||
|
||||
if Bool(s.Hwaddress) {
|
||||
s.Address = nil
|
||||
}
|
||||
|
||||
if ctx.Os() == android.Android && (Bool(s.Hwaddress) || Bool(s.Address)) {
|
||||
sanitize.Properties.SanitizerEnabled = true
|
||||
}
|
||||
}
|
||||
@@ -149,23 +211,18 @@ func rustSanitizerRuntimeMutator(mctx android.BottomUpMutatorContext) {
|
||||
} else if mod.IsSanitizerEnabled(cc.Hwasan) ||
|
||||
(mod.IsSanitizerEnabled(cc.Fuzzer) && mctx.Arch().ArchType == android.Arm64) {
|
||||
// TODO(b/180495975): HWASan for static Rust binaries isn't supported yet.
|
||||
if binary, ok := mod.compiler.(*binaryDecorator); ok {
|
||||
if Bool(binary.Properties.Static_executable) {
|
||||
if binary, ok := mod.compiler.(binaryInterface); ok {
|
||||
if binary.staticallyLinked() {
|
||||
mctx.ModuleErrorf("HWASan is not supported for static Rust executables yet.")
|
||||
}
|
||||
}
|
||||
|
||||
if mod.StaticallyLinked() {
|
||||
variations = append(variations,
|
||||
blueprint.Variation{Mutator: "link", Variation: "static"})
|
||||
depTag = cc.StaticDepTag(false)
|
||||
deps = []string{config.LibclangRuntimeLibrary(mod.toolchain(mctx), "hwasan_static")}
|
||||
} else {
|
||||
variations = append(variations,
|
||||
blueprint.Variation{Mutator: "link", Variation: "shared"})
|
||||
depTag = cc.SharedDepTag()
|
||||
deps = []string{config.LibclangRuntimeLibrary(mod.toolchain(mctx), "hwasan")}
|
||||
}
|
||||
// Always link against the shared library -- static binaries will pull in the static
|
||||
// library during final link if necessary
|
||||
variations = append(variations,
|
||||
blueprint.Variation{Mutator: "link", Variation: "shared"})
|
||||
depTag = cc.SharedDepTag()
|
||||
deps = []string{config.LibclangRuntimeLibrary(mod.toolchain(mctx), "hwasan")}
|
||||
}
|
||||
|
||||
mctx.AddFarVariationDependencies(variations, depTag, deps...)
|
||||
@@ -268,6 +325,10 @@ func (mod *Module) SanitizerSupported(t cc.SanitizerType) bool {
|
||||
case cc.Asan:
|
||||
return true
|
||||
case cc.Hwasan:
|
||||
// TODO(b/180495975): HWASan for static Rust binaries isn't supported yet.
|
||||
if mod.StaticExecutable() {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
|
@@ -151,7 +151,12 @@ func GatherRequiredDepsForTest() string {
|
||||
no_libcrt: true,
|
||||
nocrt: true,
|
||||
system_shared_libs: [],
|
||||
export_include_dirs: ["libprotobuf-cpp-full-includes"],
|
||||
}
|
||||
cc_library {
|
||||
name: "libclang_rt.hwasan_static-aarch64-android",
|
||||
no_libcrt: true,
|
||||
nocrt: true,
|
||||
system_shared_libs: [],
|
||||
}
|
||||
rust_library {
|
||||
name: "libstd",
|
||||
@@ -246,5 +251,8 @@ func registerRequiredBuildComponentsForTest(ctx android.RegistrationContext) {
|
||||
ctx.BottomUp("rust_begin", BeginMutator).Parallel()
|
||||
})
|
||||
ctx.RegisterSingletonType("rust_project_generator", rustProjectGeneratorSingleton)
|
||||
ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
|
||||
ctx.BottomUp("rust_sanitizers", rustSanitizerRuntimeMutator).Parallel()
|
||||
})
|
||||
registerRustSnapshotModules(ctx)
|
||||
}
|
||||
|
Reference in New Issue
Block a user