diff options
| -rw-r--r-- | rust/androidmk.go | 5 | ||||
| -rw-r--r-- | rust/sanitize.go | 76 |
2 files changed, 74 insertions, 7 deletions
diff --git a/rust/androidmk.go b/rust/androidmk.go index b0e69677a..dea32a34d 100644 --- a/rust/androidmk.go +++ b/rust/androidmk.go @@ -70,6 +70,11 @@ func (mod *Module) AndroidMkEntries() []android.AndroidMkEntries { // If the compiler is disabled, this is a SourceProvider. mod.SubAndroidMk(&ret, mod.sourceProvider) } + + if mod.sanitize != nil { + mod.SubAndroidMk(&ret, mod.sanitize) + } + ret.SubName += mod.Properties.SubName return []android.AndroidMkEntries{ret} diff --git a/rust/sanitize.go b/rust/sanitize.go index 2498aa15c..394f4c536 100644 --- a/rust/sanitize.go +++ b/rust/sanitize.go @@ -23,11 +23,12 @@ import ( ) type SanitizeProperties struct { - // enable AddressSanitizer, ThreadSanitizer, or UndefinedBehaviorSanitizer + // enable AddressSanitizer, HWAddressSanitizer, and others. Sanitize struct { - Address *bool `android:"arch_variant"` - Fuzzer *bool `android:"arch_variant"` - Never *bool `android:"arch_variant"` + Address *bool `android:"arch_variant"` + Hwaddress *bool `android:"arch_variant"` + Fuzzer *bool `android:"arch_variant"` + Never *bool `android:"arch_variant"` } SanitizerEnabled bool `blueprint:"mutated"` SanitizeDep bool `blueprint:"mutated"` @@ -57,6 +58,11 @@ var asanFlags = []string{ "-Z sanitizer=address", } +var hwasanFlags = []string{ + "-Z sanitizer=hwaddress", + "-C target-feature=+tagged-globals", +} + func boolPtr(v bool) *bool { if v { return &v @@ -83,6 +89,15 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) { if ctx.Os() == android.Android && Bool(s.Address) { sanitize.Properties.SanitizerEnabled = true } + + // HWASan requires AArch64 hardware feature (top-byte-ignore). + if ctx.Arch().ArchType != android.Arm64 { + s.Hwaddress = nil + } + + if ctx.Os() == android.Android && Bool(s.Hwaddress) { + sanitize.Properties.SanitizerEnabled = true + } } type sanitize struct { @@ -99,6 +114,9 @@ func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags, deps PathDeps) ( if Bool(sanitize.Properties.Sanitize.Address) { flags.RustFlags = append(flags.RustFlags, asanFlags...) } + if Bool(sanitize.Properties.Sanitize.Hwaddress) { + flags.RustFlags = append(flags.RustFlags, hwasanFlags...) + } return flags, deps } @@ -111,11 +129,38 @@ func rustSanitizerRuntimeMutator(mctx android.BottomUpMutatorContext) { if !mod.Enabled() { return } + + variations := mctx.Target().Variations() + var depTag blueprint.DependencyTag + var deps []string + if Bool(mod.sanitize.Properties.Sanitize.Fuzzer) || Bool(mod.sanitize.Properties.Sanitize.Address) { - mctx.AddFarVariationDependencies(append(mctx.Target().Variations(), []blueprint.Variation{ - {Mutator: "link", Variation: "shared"}, - }...), cc.SharedDepTag(), config.LibclangRuntimeLibrary(mod.toolchain(mctx), "asan")) + variations = append(variations, + blueprint.Variation{Mutator: "link", Variation: "shared"}) + depTag = cc.SharedDepTag() + deps = []string{config.LibclangRuntimeLibrary(mod.toolchain(mctx), "asan")} + } else if mod.IsSanitizerEnabled(cc.Hwasan) { + // 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) { + 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")} + } } + + mctx.AddFarVariationDependencies(variations, depTag, deps...) } } @@ -128,6 +173,9 @@ func (sanitize *sanitize) SetSanitizer(t cc.SanitizerType, b bool) { case cc.Asan: sanitize.Properties.Sanitize.Address = boolPtr(b) sanitizerSet = true + case cc.Hwasan: + sanitize.Properties.Sanitize.Hwaddress = boolPtr(b) + sanitizerSet = true default: panic(fmt.Errorf("setting unsupported sanitizerType %d", t)) } @@ -169,11 +217,23 @@ func (sanitize *sanitize) getSanitizerBoolPtr(t cc.SanitizerType) *bool { return sanitize.Properties.Sanitize.Fuzzer case cc.Asan: return sanitize.Properties.Sanitize.Address + case cc.Hwasan: + return sanitize.Properties.Sanitize.Hwaddress default: return nil } } +func (sanitize *sanitize) AndroidMk(ctx AndroidMkContext, entries *android.AndroidMkEntries) { + // Add a suffix for hwasan rlib libraries to allow surfacing both the sanitized and + // non-sanitized variants to make without a name conflict. + if entries.Class == "RLIB_LIBRARIES" || entries.Class == "STATIC_LIBRARIES" { + if sanitize.isSanitizerEnabled(cc.Hwasan) { + entries.SubName += ".hwasan" + } + } +} + func (mod *Module) SanitizerSupported(t cc.SanitizerType) bool { if mod.Host() { return false @@ -183,6 +243,8 @@ func (mod *Module) SanitizerSupported(t cc.SanitizerType) bool { return true case cc.Asan: return true + case cc.Hwasan: + return true default: return false } |