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:
@@ -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
|
||||
|
Reference in New Issue
Block a user