1*333d2b36SAndroid Build Coastguard Worker// Copyright 2020 The Android Open Source Project 2*333d2b36SAndroid Build Coastguard Worker// 3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License"); 4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License. 5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at 6*333d2b36SAndroid Build Coastguard Worker// 7*333d2b36SAndroid Build Coastguard Worker// http://www.apache.org/licenses/LICENSE-2.0 8*333d2b36SAndroid Build Coastguard Worker// 9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software 10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS, 11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and 13*333d2b36SAndroid Build Coastguard Worker// limitations under the License. 14*333d2b36SAndroid Build Coastguard Worker 15*333d2b36SAndroid Build Coastguard Workerpackage rust 16*333d2b36SAndroid Build Coastguard Worker 17*333d2b36SAndroid Build Coastguard Workerimport ( 18*333d2b36SAndroid Build Coastguard Worker "fmt" 19*333d2b36SAndroid Build Coastguard Worker "strings" 20*333d2b36SAndroid Build Coastguard Worker 21*333d2b36SAndroid Build Coastguard Worker "github.com/google/blueprint" 22*333d2b36SAndroid Build Coastguard Worker "github.com/google/blueprint/proptools" 23*333d2b36SAndroid Build Coastguard Worker 24*333d2b36SAndroid Build Coastguard Worker "android/soong/android" 25*333d2b36SAndroid Build Coastguard Worker "android/soong/cc" 26*333d2b36SAndroid Build Coastguard Worker "android/soong/rust/config" 27*333d2b36SAndroid Build Coastguard Worker) 28*333d2b36SAndroid Build Coastguard Worker 29*333d2b36SAndroid Build Coastguard Worker// TODO: When Rust has sanitizer-parity with CC, deduplicate this struct 30*333d2b36SAndroid Build Coastguard Workertype SanitizeProperties struct { 31*333d2b36SAndroid Build Coastguard Worker // enable AddressSanitizer, HWAddressSanitizer, and others. 32*333d2b36SAndroid Build Coastguard Worker Sanitize struct { 33*333d2b36SAndroid Build Coastguard Worker Address *bool `android:"arch_variant"` 34*333d2b36SAndroid Build Coastguard Worker Hwaddress *bool `android:"arch_variant"` 35*333d2b36SAndroid Build Coastguard Worker 36*333d2b36SAndroid Build Coastguard Worker // Memory-tagging, only available on arm64 37*333d2b36SAndroid Build Coastguard Worker // if diag.memtag unset or false, enables async memory tagging 38*333d2b36SAndroid Build Coastguard Worker Memtag_heap *bool `android:"arch_variant"` 39*333d2b36SAndroid Build Coastguard Worker Fuzzer *bool `android:"arch_variant"` 40*333d2b36SAndroid Build Coastguard Worker Never *bool `android:"arch_variant"` 41*333d2b36SAndroid Build Coastguard Worker 42*333d2b36SAndroid Build Coastguard Worker // Sanitizers to run in the diagnostic mode (as opposed to the release mode). 43*333d2b36SAndroid Build Coastguard Worker // Replaces abort() on error with a human-readable error message. 44*333d2b36SAndroid Build Coastguard Worker // Address and Thread sanitizers always run in diagnostic mode. 45*333d2b36SAndroid Build Coastguard Worker Diag struct { 46*333d2b36SAndroid Build Coastguard Worker // Memory-tagging, only available on arm64 47*333d2b36SAndroid Build Coastguard Worker // requires sanitizer.memtag: true 48*333d2b36SAndroid Build Coastguard Worker // if set, enables sync memory tagging 49*333d2b36SAndroid Build Coastguard Worker Memtag_heap *bool `android:"arch_variant"` 50*333d2b36SAndroid Build Coastguard Worker } 51*333d2b36SAndroid Build Coastguard Worker } 52*333d2b36SAndroid Build Coastguard Worker SanitizerEnabled bool `blueprint:"mutated"` 53*333d2b36SAndroid Build Coastguard Worker 54*333d2b36SAndroid Build Coastguard Worker // Used when we need to place libraries in their own directory, such as ASAN. 55*333d2b36SAndroid Build Coastguard Worker InSanitizerDir bool `blueprint:"mutated"` 56*333d2b36SAndroid Build Coastguard Worker} 57*333d2b36SAndroid Build Coastguard Worker 58*333d2b36SAndroid Build Coastguard Workervar fuzzerFlags = []string{ 59*333d2b36SAndroid Build Coastguard Worker "-Z external-clangrt=true", 60*333d2b36SAndroid Build Coastguard Worker 61*333d2b36SAndroid Build Coastguard Worker "-C passes='sancov-module'", 62*333d2b36SAndroid Build Coastguard Worker 63*333d2b36SAndroid Build Coastguard Worker "--cfg fuzzing", 64*333d2b36SAndroid Build Coastguard Worker "-C llvm-args=-sanitizer-coverage-level=3", 65*333d2b36SAndroid Build Coastguard Worker "-C llvm-args=-sanitizer-coverage-trace-compares", 66*333d2b36SAndroid Build Coastguard Worker "-C llvm-args=-sanitizer-coverage-inline-8bit-counters", 67*333d2b36SAndroid Build Coastguard Worker "-C llvm-args=-sanitizer-coverage-pc-table", 68*333d2b36SAndroid Build Coastguard Worker 69*333d2b36SAndroid Build Coastguard Worker // See https://github.com/rust-fuzz/cargo-fuzz/pull/193 70*333d2b36SAndroid Build Coastguard Worker "-C link-dead-code", 71*333d2b36SAndroid Build Coastguard Worker 72*333d2b36SAndroid Build Coastguard Worker // Sancov breaks with lto 73*333d2b36SAndroid Build Coastguard Worker // TODO: Remove when https://bugs.llvm.org/show_bug.cgi?id=41734 is resolved and sancov-module works with LTO 74*333d2b36SAndroid Build Coastguard Worker "-C lto=no", 75*333d2b36SAndroid Build Coastguard Worker} 76*333d2b36SAndroid Build Coastguard Worker 77*333d2b36SAndroid Build Coastguard Workervar asanFlags = []string{ 78*333d2b36SAndroid Build Coastguard Worker "-Z external-clangrt=true", 79*333d2b36SAndroid Build Coastguard Worker "-Z sanitizer=address", 80*333d2b36SAndroid Build Coastguard Worker} 81*333d2b36SAndroid Build Coastguard Worker 82*333d2b36SAndroid Build Coastguard Worker// See cc/sanitize.go's hwasanGlobalOptions for global hwasan options. 83*333d2b36SAndroid Build Coastguard Workervar hwasanFlags = []string{ 84*333d2b36SAndroid Build Coastguard Worker "-Z external-clangrt=true", 85*333d2b36SAndroid Build Coastguard Worker "-Z sanitizer=hwaddress", 86*333d2b36SAndroid Build Coastguard Worker "-C target-feature=+tagged-globals", 87*333d2b36SAndroid Build Coastguard Worker 88*333d2b36SAndroid Build Coastguard Worker // Flags from cc/sanitize.go hwasanFlags 89*333d2b36SAndroid Build Coastguard Worker "-C llvm-args=--aarch64-enable-global-isel-at-O=-1", 90*333d2b36SAndroid Build Coastguard Worker "-C llvm-args=-fast-isel=false", 91*333d2b36SAndroid Build Coastguard Worker "-C llvm-args=-instcombine-lower-dbg-declare=0", 92*333d2b36SAndroid Build Coastguard Worker 93*333d2b36SAndroid Build Coastguard Worker // Additional flags for HWASAN-ified Rust/C interop 94*333d2b36SAndroid Build Coastguard Worker "-C llvm-args=--hwasan-with-ifunc", 95*333d2b36SAndroid Build Coastguard Worker} 96*333d2b36SAndroid Build Coastguard Worker 97*333d2b36SAndroid Build Coastguard Workerfunc init() { 98*333d2b36SAndroid Build Coastguard Worker} 99*333d2b36SAndroid Build Coastguard Workerfunc (sanitize *sanitize) props() []interface{} { 100*333d2b36SAndroid Build Coastguard Worker return []interface{}{&sanitize.Properties} 101*333d2b36SAndroid Build Coastguard Worker} 102*333d2b36SAndroid Build Coastguard Worker 103*333d2b36SAndroid Build Coastguard Workerfunc (sanitize *sanitize) begin(ctx BaseModuleContext) { 104*333d2b36SAndroid Build Coastguard Worker s := &sanitize.Properties.Sanitize 105*333d2b36SAndroid Build Coastguard Worker 106*333d2b36SAndroid Build Coastguard Worker // Disable sanitizers for musl x86 modules, rustc does not support any sanitizers. 107*333d2b36SAndroid Build Coastguard Worker if ctx.Os() == android.LinuxMusl && ctx.Arch().ArchType == android.X86 { 108*333d2b36SAndroid Build Coastguard Worker s.Never = proptools.BoolPtr(true) 109*333d2b36SAndroid Build Coastguard Worker } 110*333d2b36SAndroid Build Coastguard Worker 111*333d2b36SAndroid Build Coastguard Worker // Never always wins. 112*333d2b36SAndroid Build Coastguard Worker if Bool(s.Never) { 113*333d2b36SAndroid Build Coastguard Worker return 114*333d2b36SAndroid Build Coastguard Worker } 115*333d2b36SAndroid Build Coastguard Worker 116*333d2b36SAndroid Build Coastguard Worker // rust_test targets default to SYNC MemTag unless explicitly set to ASYNC (via diag: {Memtag_heap}). 117*333d2b36SAndroid Build Coastguard Worker if binary, ok := ctx.RustModule().compiler.(binaryInterface); ok && binary.testBinary() { 118*333d2b36SAndroid Build Coastguard Worker if s.Memtag_heap == nil { 119*333d2b36SAndroid Build Coastguard Worker s.Memtag_heap = proptools.BoolPtr(true) 120*333d2b36SAndroid Build Coastguard Worker } 121*333d2b36SAndroid Build Coastguard Worker if s.Diag.Memtag_heap == nil { 122*333d2b36SAndroid Build Coastguard Worker s.Diag.Memtag_heap = proptools.BoolPtr(true) 123*333d2b36SAndroid Build Coastguard Worker } 124*333d2b36SAndroid Build Coastguard Worker } 125*333d2b36SAndroid Build Coastguard Worker 126*333d2b36SAndroid Build Coastguard Worker var globalSanitizers []string 127*333d2b36SAndroid Build Coastguard Worker var globalSanitizersDiag []string 128*333d2b36SAndroid Build Coastguard Worker 129*333d2b36SAndroid Build Coastguard Worker if ctx.Host() { 130*333d2b36SAndroid Build Coastguard Worker if !ctx.Windows() { 131*333d2b36SAndroid Build Coastguard Worker globalSanitizers = ctx.Config().SanitizeHost() 132*333d2b36SAndroid Build Coastguard Worker } 133*333d2b36SAndroid Build Coastguard Worker } else { 134*333d2b36SAndroid Build Coastguard Worker arches := ctx.Config().SanitizeDeviceArch() 135*333d2b36SAndroid Build Coastguard Worker if len(arches) == 0 || android.InList(ctx.Arch().ArchType.Name, arches) { 136*333d2b36SAndroid Build Coastguard Worker globalSanitizers = ctx.Config().SanitizeDevice() 137*333d2b36SAndroid Build Coastguard Worker globalSanitizersDiag = ctx.Config().SanitizeDeviceDiag() 138*333d2b36SAndroid Build Coastguard Worker } 139*333d2b36SAndroid Build Coastguard Worker } 140*333d2b36SAndroid Build Coastguard Worker 141*333d2b36SAndroid Build Coastguard Worker if len(globalSanitizers) > 0 { 142*333d2b36SAndroid Build Coastguard Worker var found bool 143*333d2b36SAndroid Build Coastguard Worker 144*333d2b36SAndroid Build Coastguard Worker // Global Sanitizers 145*333d2b36SAndroid Build Coastguard Worker if found, globalSanitizers = android.RemoveFromList("hwaddress", globalSanitizers); found && s.Hwaddress == nil { 146*333d2b36SAndroid Build Coastguard Worker // TODO(b/204776996): HWASan for static Rust binaries isn't supported yet. 147*333d2b36SAndroid Build Coastguard Worker if !ctx.RustModule().StaticExecutable() { 148*333d2b36SAndroid Build Coastguard Worker s.Hwaddress = proptools.BoolPtr(true) 149*333d2b36SAndroid Build Coastguard Worker } 150*333d2b36SAndroid Build Coastguard Worker } 151*333d2b36SAndroid Build Coastguard Worker 152*333d2b36SAndroid Build Coastguard Worker if found, globalSanitizers = android.RemoveFromList("memtag_heap", globalSanitizers); found && s.Memtag_heap == nil { 153*333d2b36SAndroid Build Coastguard Worker if !ctx.Config().MemtagHeapDisabledForPath(ctx.ModuleDir()) { 154*333d2b36SAndroid Build Coastguard Worker s.Memtag_heap = proptools.BoolPtr(true) 155*333d2b36SAndroid Build Coastguard Worker } 156*333d2b36SAndroid Build Coastguard Worker } 157*333d2b36SAndroid Build Coastguard Worker 158*333d2b36SAndroid Build Coastguard Worker if found, globalSanitizers = android.RemoveFromList("address", globalSanitizers); found && s.Address == nil { 159*333d2b36SAndroid Build Coastguard Worker s.Address = proptools.BoolPtr(true) 160*333d2b36SAndroid Build Coastguard Worker } 161*333d2b36SAndroid Build Coastguard Worker 162*333d2b36SAndroid Build Coastguard Worker if found, globalSanitizers = android.RemoveFromList("fuzzer", globalSanitizers); found && s.Fuzzer == nil { 163*333d2b36SAndroid Build Coastguard Worker // TODO(b/204776996): HWASan for static Rust binaries isn't supported yet, and fuzzer enables HWAsan 164*333d2b36SAndroid Build Coastguard Worker if !ctx.RustModule().StaticExecutable() { 165*333d2b36SAndroid Build Coastguard Worker s.Fuzzer = proptools.BoolPtr(true) 166*333d2b36SAndroid Build Coastguard Worker } 167*333d2b36SAndroid Build Coastguard Worker } 168*333d2b36SAndroid Build Coastguard Worker 169*333d2b36SAndroid Build Coastguard Worker // Global Diag Sanitizers 170*333d2b36SAndroid Build Coastguard Worker if found, globalSanitizersDiag = android.RemoveFromList("memtag_heap", globalSanitizersDiag); found && 171*333d2b36SAndroid Build Coastguard Worker s.Diag.Memtag_heap == nil && Bool(s.Memtag_heap) { 172*333d2b36SAndroid Build Coastguard Worker s.Diag.Memtag_heap = proptools.BoolPtr(true) 173*333d2b36SAndroid Build Coastguard Worker } 174*333d2b36SAndroid Build Coastguard Worker } 175*333d2b36SAndroid Build Coastguard Worker 176*333d2b36SAndroid Build Coastguard Worker // Enable Memtag for all components in the include paths (for Aarch64 only) 177*333d2b36SAndroid Build Coastguard Worker if ctx.Arch().ArchType == android.Arm64 && ctx.Os().Bionic() { 178*333d2b36SAndroid Build Coastguard Worker if ctx.Config().MemtagHeapSyncEnabledForPath(ctx.ModuleDir()) { 179*333d2b36SAndroid Build Coastguard Worker if s.Memtag_heap == nil { 180*333d2b36SAndroid Build Coastguard Worker s.Memtag_heap = proptools.BoolPtr(true) 181*333d2b36SAndroid Build Coastguard Worker } 182*333d2b36SAndroid Build Coastguard Worker if s.Diag.Memtag_heap == nil { 183*333d2b36SAndroid Build Coastguard Worker s.Diag.Memtag_heap = proptools.BoolPtr(true) 184*333d2b36SAndroid Build Coastguard Worker } 185*333d2b36SAndroid Build Coastguard Worker } else if ctx.Config().MemtagHeapAsyncEnabledForPath(ctx.ModuleDir()) { 186*333d2b36SAndroid Build Coastguard Worker if s.Memtag_heap == nil { 187*333d2b36SAndroid Build Coastguard Worker s.Memtag_heap = proptools.BoolPtr(true) 188*333d2b36SAndroid Build Coastguard Worker } 189*333d2b36SAndroid Build Coastguard Worker } 190*333d2b36SAndroid Build Coastguard Worker } 191*333d2b36SAndroid Build Coastguard Worker 192*333d2b36SAndroid Build Coastguard Worker // HWASan requires AArch64 hardware feature (top-byte-ignore). 193*333d2b36SAndroid Build Coastguard Worker if ctx.Arch().ArchType != android.Arm64 || !ctx.Os().Bionic() { 194*333d2b36SAndroid Build Coastguard Worker s.Hwaddress = nil 195*333d2b36SAndroid Build Coastguard Worker } 196*333d2b36SAndroid Build Coastguard Worker 197*333d2b36SAndroid Build Coastguard Worker // HWASan ramdisk (which is built from recovery) goes over some bootloader limit. 198*333d2b36SAndroid Build Coastguard Worker // Keep libc instrumented so that ramdisk / vendor_ramdisk / recovery can run hwasan-instrumented code if necessary. 199*333d2b36SAndroid Build Coastguard Worker if (ctx.RustModule().InRamdisk() || ctx.RustModule().InVendorRamdisk() || ctx.RustModule().InRecovery()) && !strings.HasPrefix(ctx.ModuleDir(), "bionic/libc") { 200*333d2b36SAndroid Build Coastguard Worker s.Hwaddress = nil 201*333d2b36SAndroid Build Coastguard Worker } 202*333d2b36SAndroid Build Coastguard Worker 203*333d2b36SAndroid Build Coastguard Worker if Bool(s.Hwaddress) { 204*333d2b36SAndroid Build Coastguard Worker s.Address = nil 205*333d2b36SAndroid Build Coastguard Worker } 206*333d2b36SAndroid Build Coastguard Worker 207*333d2b36SAndroid Build Coastguard Worker // Memtag_heap is only implemented on AArch64. 208*333d2b36SAndroid Build Coastguard Worker if ctx.Arch().ArchType != android.Arm64 || !ctx.Os().Bionic() { 209*333d2b36SAndroid Build Coastguard Worker s.Memtag_heap = nil 210*333d2b36SAndroid Build Coastguard Worker } 211*333d2b36SAndroid Build Coastguard Worker 212*333d2b36SAndroid Build Coastguard Worker // TODO:(b/178369775) 213*333d2b36SAndroid Build Coastguard Worker // For now sanitizing is only supported on non-windows targets 214*333d2b36SAndroid Build Coastguard Worker if ctx.Os() != android.Windows && (Bool(s.Hwaddress) || Bool(s.Address) || Bool(s.Memtag_heap) || Bool(s.Fuzzer)) { 215*333d2b36SAndroid Build Coastguard Worker sanitize.Properties.SanitizerEnabled = true 216*333d2b36SAndroid Build Coastguard Worker } 217*333d2b36SAndroid Build Coastguard Worker} 218*333d2b36SAndroid Build Coastguard Worker 219*333d2b36SAndroid Build Coastguard Workertype sanitize struct { 220*333d2b36SAndroid Build Coastguard Worker Properties SanitizeProperties 221*333d2b36SAndroid Build Coastguard Worker} 222*333d2b36SAndroid Build Coastguard Worker 223*333d2b36SAndroid Build Coastguard Workerfunc (sanitize *sanitize) flags(ctx ModuleContext, flags Flags, deps PathDeps) (Flags, PathDeps) { 224*333d2b36SAndroid Build Coastguard Worker if !sanitize.Properties.SanitizerEnabled { 225*333d2b36SAndroid Build Coastguard Worker return flags, deps 226*333d2b36SAndroid Build Coastguard Worker } 227*333d2b36SAndroid Build Coastguard Worker 228*333d2b36SAndroid Build Coastguard Worker if Bool(sanitize.Properties.Sanitize.Fuzzer) { 229*333d2b36SAndroid Build Coastguard Worker flags.RustFlags = append(flags.RustFlags, fuzzerFlags...) 230*333d2b36SAndroid Build Coastguard Worker } 231*333d2b36SAndroid Build Coastguard Worker 232*333d2b36SAndroid Build Coastguard Worker if Bool(sanitize.Properties.Sanitize.Hwaddress) { 233*333d2b36SAndroid Build Coastguard Worker flags.RustFlags = append(flags.RustFlags, hwasanFlags...) 234*333d2b36SAndroid Build Coastguard Worker } 235*333d2b36SAndroid Build Coastguard Worker 236*333d2b36SAndroid Build Coastguard Worker if Bool(sanitize.Properties.Sanitize.Address) { 237*333d2b36SAndroid Build Coastguard Worker flags.RustFlags = append(flags.RustFlags, asanFlags...) 238*333d2b36SAndroid Build Coastguard Worker if ctx.Host() { 239*333d2b36SAndroid Build Coastguard Worker // -nodefaultlibs (provided with libc++) prevents the driver from linking 240*333d2b36SAndroid Build Coastguard Worker // libraries needed with -fsanitize=address. http://b/18650275 (WAI) 241*333d2b36SAndroid Build Coastguard Worker flags.LinkFlags = append(flags.LinkFlags, []string{"-Wl,--no-as-needed"}...) 242*333d2b36SAndroid Build Coastguard Worker } 243*333d2b36SAndroid Build Coastguard Worker } 244*333d2b36SAndroid Build Coastguard Worker return flags, deps 245*333d2b36SAndroid Build Coastguard Worker} 246*333d2b36SAndroid Build Coastguard Worker 247*333d2b36SAndroid Build Coastguard Workerfunc (sanitize *sanitize) deps(ctx BaseModuleContext, deps Deps) Deps { 248*333d2b36SAndroid Build Coastguard Worker return deps 249*333d2b36SAndroid Build Coastguard Worker} 250*333d2b36SAndroid Build Coastguard Worker 251*333d2b36SAndroid Build Coastguard Workerfunc rustSanitizerRuntimeMutator(mctx android.BottomUpMutatorContext) { 252*333d2b36SAndroid Build Coastguard Worker if mod, ok := mctx.Module().(*Module); ok && mod.sanitize != nil { 253*333d2b36SAndroid Build Coastguard Worker if !mod.Enabled(mctx) { 254*333d2b36SAndroid Build Coastguard Worker return 255*333d2b36SAndroid Build Coastguard Worker } 256*333d2b36SAndroid Build Coastguard Worker 257*333d2b36SAndroid Build Coastguard Worker if Bool(mod.sanitize.Properties.Sanitize.Memtag_heap) && mod.Binary() { 258*333d2b36SAndroid Build Coastguard Worker noteDep := "note_memtag_heap_async" 259*333d2b36SAndroid Build Coastguard Worker if Bool(mod.sanitize.Properties.Sanitize.Diag.Memtag_heap) { 260*333d2b36SAndroid Build Coastguard Worker noteDep = "note_memtag_heap_sync" 261*333d2b36SAndroid Build Coastguard Worker } 262*333d2b36SAndroid Build Coastguard Worker depTag := cc.StaticDepTag(true) 263*333d2b36SAndroid Build Coastguard Worker variations := append(mctx.Target().Variations(), 264*333d2b36SAndroid Build Coastguard Worker blueprint.Variation{Mutator: "link", Variation: "static"}) 265*333d2b36SAndroid Build Coastguard Worker if mod.Device() { 266*333d2b36SAndroid Build Coastguard Worker variations = append(variations, mod.ImageVariation()) 267*333d2b36SAndroid Build Coastguard Worker } 268*333d2b36SAndroid Build Coastguard Worker mctx.AddFarVariationDependencies(variations, depTag, noteDep) 269*333d2b36SAndroid Build Coastguard Worker } 270*333d2b36SAndroid Build Coastguard Worker 271*333d2b36SAndroid Build Coastguard Worker variations := mctx.Target().Variations() 272*333d2b36SAndroid Build Coastguard Worker var depTag blueprint.DependencyTag 273*333d2b36SAndroid Build Coastguard Worker var deps []string 274*333d2b36SAndroid Build Coastguard Worker 275*333d2b36SAndroid Build Coastguard Worker if mod.IsSanitizerEnabled(cc.Asan) { 276*333d2b36SAndroid Build Coastguard Worker if mod.Host() { 277*333d2b36SAndroid Build Coastguard Worker variations = append(variations, 278*333d2b36SAndroid Build Coastguard Worker blueprint.Variation{Mutator: "link", Variation: "static"}) 279*333d2b36SAndroid Build Coastguard Worker depTag = cc.StaticDepTag(false) 280*333d2b36SAndroid Build Coastguard Worker deps = []string{config.LibclangRuntimeLibrary(mod.toolchain(mctx), "asan.static")} 281*333d2b36SAndroid Build Coastguard Worker } else { 282*333d2b36SAndroid Build Coastguard Worker variations = append(variations, 283*333d2b36SAndroid Build Coastguard Worker blueprint.Variation{Mutator: "link", Variation: "shared"}) 284*333d2b36SAndroid Build Coastguard Worker depTag = cc.SharedDepTag() 285*333d2b36SAndroid Build Coastguard Worker deps = []string{config.LibclangRuntimeLibrary(mod.toolchain(mctx), "asan")} 286*333d2b36SAndroid Build Coastguard Worker } 287*333d2b36SAndroid Build Coastguard Worker } else if mod.IsSanitizerEnabled(cc.Hwasan) { 288*333d2b36SAndroid Build Coastguard Worker // TODO(b/204776996): HWASan for static Rust binaries isn't supported yet. 289*333d2b36SAndroid Build Coastguard Worker if binary, ok := mod.compiler.(binaryInterface); ok { 290*333d2b36SAndroid Build Coastguard Worker if binary.staticallyLinked() { 291*333d2b36SAndroid Build Coastguard Worker mctx.ModuleErrorf("HWASan is not supported for static Rust executables yet.") 292*333d2b36SAndroid Build Coastguard Worker } 293*333d2b36SAndroid Build Coastguard Worker } 294*333d2b36SAndroid Build Coastguard Worker 295*333d2b36SAndroid Build Coastguard Worker // Always link against the shared library -- static binaries will pull in the static 296*333d2b36SAndroid Build Coastguard Worker // library during final link if necessary 297*333d2b36SAndroid Build Coastguard Worker variations = append(variations, 298*333d2b36SAndroid Build Coastguard Worker blueprint.Variation{Mutator: "link", Variation: "shared"}) 299*333d2b36SAndroid Build Coastguard Worker depTag = cc.SharedDepTag() 300*333d2b36SAndroid Build Coastguard Worker deps = []string{config.LibclangRuntimeLibrary(mod.toolchain(mctx), "hwasan")} 301*333d2b36SAndroid Build Coastguard Worker } 302*333d2b36SAndroid Build Coastguard Worker 303*333d2b36SAndroid Build Coastguard Worker if len(deps) > 0 { 304*333d2b36SAndroid Build Coastguard Worker mctx.AddFarVariationDependencies(variations, depTag, deps...) 305*333d2b36SAndroid Build Coastguard Worker } 306*333d2b36SAndroid Build Coastguard Worker } 307*333d2b36SAndroid Build Coastguard Worker} 308*333d2b36SAndroid Build Coastguard Worker 309*333d2b36SAndroid Build Coastguard Workerfunc (sanitize *sanitize) SetSanitizer(t cc.SanitizerType, b bool) { 310*333d2b36SAndroid Build Coastguard Worker sanitizerSet := false 311*333d2b36SAndroid Build Coastguard Worker switch t { 312*333d2b36SAndroid Build Coastguard Worker case cc.Fuzzer: 313*333d2b36SAndroid Build Coastguard Worker sanitize.Properties.Sanitize.Fuzzer = proptools.BoolPtr(b) 314*333d2b36SAndroid Build Coastguard Worker sanitizerSet = true 315*333d2b36SAndroid Build Coastguard Worker case cc.Asan: 316*333d2b36SAndroid Build Coastguard Worker sanitize.Properties.Sanitize.Address = proptools.BoolPtr(b) 317*333d2b36SAndroid Build Coastguard Worker sanitizerSet = true 318*333d2b36SAndroid Build Coastguard Worker case cc.Hwasan: 319*333d2b36SAndroid Build Coastguard Worker sanitize.Properties.Sanitize.Hwaddress = proptools.BoolPtr(b) 320*333d2b36SAndroid Build Coastguard Worker sanitizerSet = true 321*333d2b36SAndroid Build Coastguard Worker case cc.Memtag_heap: 322*333d2b36SAndroid Build Coastguard Worker sanitize.Properties.Sanitize.Memtag_heap = proptools.BoolPtr(b) 323*333d2b36SAndroid Build Coastguard Worker sanitizerSet = true 324*333d2b36SAndroid Build Coastguard Worker default: 325*333d2b36SAndroid Build Coastguard Worker panic(fmt.Errorf("setting unsupported sanitizerType %d", t)) 326*333d2b36SAndroid Build Coastguard Worker } 327*333d2b36SAndroid Build Coastguard Worker if b && sanitizerSet { 328*333d2b36SAndroid Build Coastguard Worker sanitize.Properties.SanitizerEnabled = true 329*333d2b36SAndroid Build Coastguard Worker } 330*333d2b36SAndroid Build Coastguard Worker} 331*333d2b36SAndroid Build Coastguard Worker 332*333d2b36SAndroid Build Coastguard Workerfunc (m *Module) UbsanRuntimeNeeded() bool { 333*333d2b36SAndroid Build Coastguard Worker return false 334*333d2b36SAndroid Build Coastguard Worker} 335*333d2b36SAndroid Build Coastguard Worker 336*333d2b36SAndroid Build Coastguard Workerfunc (m *Module) MinimalRuntimeNeeded() bool { 337*333d2b36SAndroid Build Coastguard Worker return false 338*333d2b36SAndroid Build Coastguard Worker} 339*333d2b36SAndroid Build Coastguard Worker 340*333d2b36SAndroid Build Coastguard Workerfunc (m *Module) UbsanRuntimeDep() bool { 341*333d2b36SAndroid Build Coastguard Worker return false 342*333d2b36SAndroid Build Coastguard Worker} 343*333d2b36SAndroid Build Coastguard Worker 344*333d2b36SAndroid Build Coastguard Workerfunc (m *Module) MinimalRuntimeDep() bool { 345*333d2b36SAndroid Build Coastguard Worker return false 346*333d2b36SAndroid Build Coastguard Worker} 347*333d2b36SAndroid Build Coastguard Worker 348*333d2b36SAndroid Build Coastguard Worker// Check if the sanitizer is explicitly disabled (as opposed to nil by 349*333d2b36SAndroid Build Coastguard Worker// virtue of not being set). 350*333d2b36SAndroid Build Coastguard Workerfunc (sanitize *sanitize) isSanitizerExplicitlyDisabled(t cc.SanitizerType) bool { 351*333d2b36SAndroid Build Coastguard Worker if sanitize == nil { 352*333d2b36SAndroid Build Coastguard Worker return false 353*333d2b36SAndroid Build Coastguard Worker } 354*333d2b36SAndroid Build Coastguard Worker if Bool(sanitize.Properties.Sanitize.Never) { 355*333d2b36SAndroid Build Coastguard Worker return true 356*333d2b36SAndroid Build Coastguard Worker } 357*333d2b36SAndroid Build Coastguard Worker sanitizerVal := sanitize.getSanitizerBoolPtr(t) 358*333d2b36SAndroid Build Coastguard Worker return sanitizerVal != nil && *sanitizerVal == false 359*333d2b36SAndroid Build Coastguard Worker} 360*333d2b36SAndroid Build Coastguard Worker 361*333d2b36SAndroid Build Coastguard Worker// There isn't an analog of the method above (ie:isSanitizerExplicitlyEnabled) 362*333d2b36SAndroid Build Coastguard Worker// because enabling a sanitizer either directly (via the blueprint) or 363*333d2b36SAndroid Build Coastguard Worker// indirectly (via a mutator) sets the bool ptr to true, and you can't 364*333d2b36SAndroid Build Coastguard Worker// distinguish between the cases. It isn't needed though - both cases can be 365*333d2b36SAndroid Build Coastguard Worker// treated identically. 366*333d2b36SAndroid Build Coastguard Workerfunc (sanitize *sanitize) isSanitizerEnabled(t cc.SanitizerType) bool { 367*333d2b36SAndroid Build Coastguard Worker if sanitize == nil || !sanitize.Properties.SanitizerEnabled { 368*333d2b36SAndroid Build Coastguard Worker return false 369*333d2b36SAndroid Build Coastguard Worker } 370*333d2b36SAndroid Build Coastguard Worker 371*333d2b36SAndroid Build Coastguard Worker sanitizerVal := sanitize.getSanitizerBoolPtr(t) 372*333d2b36SAndroid Build Coastguard Worker return sanitizerVal != nil && *sanitizerVal == true 373*333d2b36SAndroid Build Coastguard Worker} 374*333d2b36SAndroid Build Coastguard Worker 375*333d2b36SAndroid Build Coastguard Workerfunc (sanitize *sanitize) getSanitizerBoolPtr(t cc.SanitizerType) *bool { 376*333d2b36SAndroid Build Coastguard Worker switch t { 377*333d2b36SAndroid Build Coastguard Worker case cc.Fuzzer: 378*333d2b36SAndroid Build Coastguard Worker return sanitize.Properties.Sanitize.Fuzzer 379*333d2b36SAndroid Build Coastguard Worker case cc.Asan: 380*333d2b36SAndroid Build Coastguard Worker return sanitize.Properties.Sanitize.Address 381*333d2b36SAndroid Build Coastguard Worker case cc.Hwasan: 382*333d2b36SAndroid Build Coastguard Worker return sanitize.Properties.Sanitize.Hwaddress 383*333d2b36SAndroid Build Coastguard Worker case cc.Memtag_heap: 384*333d2b36SAndroid Build Coastguard Worker return sanitize.Properties.Sanitize.Memtag_heap 385*333d2b36SAndroid Build Coastguard Worker default: 386*333d2b36SAndroid Build Coastguard Worker return nil 387*333d2b36SAndroid Build Coastguard Worker } 388*333d2b36SAndroid Build Coastguard Worker} 389*333d2b36SAndroid Build Coastguard Worker 390*333d2b36SAndroid Build Coastguard Workerfunc (sanitize *sanitize) AndroidMk(ctx AndroidMkContext, entries *android.AndroidMkEntries) { 391*333d2b36SAndroid Build Coastguard Worker // Add a suffix for hwasan rlib libraries to allow surfacing both the sanitized and 392*333d2b36SAndroid Build Coastguard Worker // non-sanitized variants to make without a name conflict. 393*333d2b36SAndroid Build Coastguard Worker if entries.Class == "RLIB_LIBRARIES" || entries.Class == "STATIC_LIBRARIES" { 394*333d2b36SAndroid Build Coastguard Worker if sanitize.isSanitizerEnabled(cc.Hwasan) { 395*333d2b36SAndroid Build Coastguard Worker entries.SubName += ".hwasan" 396*333d2b36SAndroid Build Coastguard Worker } 397*333d2b36SAndroid Build Coastguard Worker } 398*333d2b36SAndroid Build Coastguard Worker} 399*333d2b36SAndroid Build Coastguard Worker 400*333d2b36SAndroid Build Coastguard Workerfunc (mod *Module) SanitizerSupported(t cc.SanitizerType) bool { 401*333d2b36SAndroid Build Coastguard Worker // Sanitizers are not supported on Windows targets. 402*333d2b36SAndroid Build Coastguard Worker if mod.Os() == android.Windows { 403*333d2b36SAndroid Build Coastguard Worker return false 404*333d2b36SAndroid Build Coastguard Worker } 405*333d2b36SAndroid Build Coastguard Worker switch t { 406*333d2b36SAndroid Build Coastguard Worker case cc.Fuzzer: 407*333d2b36SAndroid Build Coastguard Worker return true 408*333d2b36SAndroid Build Coastguard Worker case cc.Asan: 409*333d2b36SAndroid Build Coastguard Worker return true 410*333d2b36SAndroid Build Coastguard Worker case cc.Hwasan: 411*333d2b36SAndroid Build Coastguard Worker // TODO(b/180495975): HWASan for static Rust binaries isn't supported yet. 412*333d2b36SAndroid Build Coastguard Worker if mod.StaticExecutable() { 413*333d2b36SAndroid Build Coastguard Worker return false 414*333d2b36SAndroid Build Coastguard Worker } 415*333d2b36SAndroid Build Coastguard Worker return true 416*333d2b36SAndroid Build Coastguard Worker case cc.Memtag_heap: 417*333d2b36SAndroid Build Coastguard Worker return true 418*333d2b36SAndroid Build Coastguard Worker default: 419*333d2b36SAndroid Build Coastguard Worker return false 420*333d2b36SAndroid Build Coastguard Worker } 421*333d2b36SAndroid Build Coastguard Worker} 422*333d2b36SAndroid Build Coastguard Worker 423*333d2b36SAndroid Build Coastguard Workerfunc (mod *Module) IsSanitizerEnabled(t cc.SanitizerType) bool { 424*333d2b36SAndroid Build Coastguard Worker return mod.sanitize.isSanitizerEnabled(t) 425*333d2b36SAndroid Build Coastguard Worker} 426*333d2b36SAndroid Build Coastguard Worker 427*333d2b36SAndroid Build Coastguard Workerfunc (mod *Module) IsSanitizerExplicitlyDisabled(t cc.SanitizerType) bool { 428*333d2b36SAndroid Build Coastguard Worker // Sanitizers are not supported on Windows targets. 429*333d2b36SAndroid Build Coastguard Worker if mod.Os() == android.Windows { 430*333d2b36SAndroid Build Coastguard Worker return true 431*333d2b36SAndroid Build Coastguard Worker } 432*333d2b36SAndroid Build Coastguard Worker 433*333d2b36SAndroid Build Coastguard Worker return mod.sanitize.isSanitizerExplicitlyDisabled(t) 434*333d2b36SAndroid Build Coastguard Worker} 435*333d2b36SAndroid Build Coastguard Worker 436*333d2b36SAndroid Build Coastguard Workerfunc (mod *Module) SetSanitizer(t cc.SanitizerType, b bool) { 437*333d2b36SAndroid Build Coastguard Worker if !Bool(mod.sanitize.Properties.Sanitize.Never) { 438*333d2b36SAndroid Build Coastguard Worker mod.sanitize.SetSanitizer(t, b) 439*333d2b36SAndroid Build Coastguard Worker } 440*333d2b36SAndroid Build Coastguard Worker} 441*333d2b36SAndroid Build Coastguard Worker 442*333d2b36SAndroid Build Coastguard Workerfunc (mod *Module) StaticallyLinked() bool { 443*333d2b36SAndroid Build Coastguard Worker if lib, ok := mod.compiler.(libraryInterface); ok { 444*333d2b36SAndroid Build Coastguard Worker return lib.rlib() || lib.static() 445*333d2b36SAndroid Build Coastguard Worker } else if binary, ok := mod.compiler.(binaryInterface); ok { 446*333d2b36SAndroid Build Coastguard Worker return binary.staticallyLinked() 447*333d2b36SAndroid Build Coastguard Worker } 448*333d2b36SAndroid Build Coastguard Worker return false 449*333d2b36SAndroid Build Coastguard Worker} 450*333d2b36SAndroid Build Coastguard Worker 451*333d2b36SAndroid Build Coastguard Workerfunc (mod *Module) SetInSanitizerDir() { 452*333d2b36SAndroid Build Coastguard Worker mod.sanitize.Properties.InSanitizerDir = true 453*333d2b36SAndroid Build Coastguard Worker} 454*333d2b36SAndroid Build Coastguard Worker 455*333d2b36SAndroid Build Coastguard Workerfunc (mod *Module) SanitizeNever() bool { 456*333d2b36SAndroid Build Coastguard Worker return Bool(mod.sanitize.Properties.Sanitize.Never) 457*333d2b36SAndroid Build Coastguard Worker} 458*333d2b36SAndroid Build Coastguard Worker 459*333d2b36SAndroid Build Coastguard Workervar _ cc.PlatformSanitizeable = (*Module)(nil) 460*333d2b36SAndroid Build Coastguard Worker 461*333d2b36SAndroid Build Coastguard Workerfunc IsSanitizableDependencyTag(tag blueprint.DependencyTag) bool { 462*333d2b36SAndroid Build Coastguard Worker switch t := tag.(type) { 463*333d2b36SAndroid Build Coastguard Worker case dependencyTag: 464*333d2b36SAndroid Build Coastguard Worker return t.library 465*333d2b36SAndroid Build Coastguard Worker default: 466*333d2b36SAndroid Build Coastguard Worker return cc.IsSanitizableDependencyTag(tag) 467*333d2b36SAndroid Build Coastguard Worker } 468*333d2b36SAndroid Build Coastguard Worker} 469*333d2b36SAndroid Build Coastguard Worker 470*333d2b36SAndroid Build Coastguard Workerfunc (m *Module) SanitizableDepTagChecker() cc.SantizableDependencyTagChecker { 471*333d2b36SAndroid Build Coastguard Worker return IsSanitizableDependencyTag 472*333d2b36SAndroid Build Coastguard Worker} 473