sanitize.go 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141
  1. // Copyright 2016 Google Inc. All rights reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package cc
  15. import (
  16. "fmt"
  17. "sort"
  18. "strings"
  19. "sync"
  20. "github.com/google/blueprint"
  21. "android/soong/android"
  22. "android/soong/cc/config"
  23. )
  24. var (
  25. // Any C flags added by sanitizer which libTooling tools may not
  26. // understand also need to be added to ClangLibToolingUnknownCflags in
  27. // cc/config/clang.go
  28. asanCflags = []string{
  29. "-fno-omit-frame-pointer",
  30. "-fno-experimental-new-pass-manager",
  31. }
  32. asanLdflags = []string{"-Wl,-u,__asan_preinit"}
  33. hwasanCflags = []string{"-fno-omit-frame-pointer", "-Wno-frame-larger-than=",
  34. "-fsanitize-hwaddress-abi=platform",
  35. "-fno-experimental-new-pass-manager",
  36. // The following improves debug location information
  37. // availability at the cost of its accuracy. It increases
  38. // the likelihood of a stack variable's frame offset
  39. // to be recorded in the debug info, which is important
  40. // for the quality of hwasan reports. The downside is a
  41. // higher number of "optimized out" stack variables.
  42. // b/112437883.
  43. "-mllvm", "-instcombine-lower-dbg-declare=0",
  44. }
  45. cfiCflags = []string{"-flto", "-fsanitize-cfi-cross-dso",
  46. "-fsanitize-blacklist=external/compiler-rt/lib/cfi/cfi_blacklist.txt"}
  47. // -flto and -fvisibility are required by clang when -fsanitize=cfi is
  48. // used, but have no effect on assembly files
  49. cfiAsflags = []string{"-flto", "-fvisibility=default"}
  50. cfiLdflags = []string{"-flto", "-fsanitize-cfi-cross-dso", "-fsanitize=cfi",
  51. "-Wl,-plugin-opt,O1"}
  52. cfiExportsMapPath = "build/soong/cc/config/cfi_exports.map"
  53. cfiStaticLibsMutex sync.Mutex
  54. hwasanStaticLibsMutex sync.Mutex
  55. intOverflowCflags = []string{"-fsanitize-blacklist=build/soong/cc/config/integer_overflow_blacklist.txt"}
  56. minimalRuntimeFlags = []string{"-fsanitize-minimal-runtime", "-fno-sanitize-trap=integer,undefined",
  57. "-fno-sanitize-recover=integer,undefined"}
  58. hwasanGlobalOptions = []string{"heap_history_size=1023", "stack_history_size=512",
  59. "export_memory_stats=0", "max_malloc_fill_size=0"}
  60. )
  61. type sanitizerType int
  62. func boolPtr(v bool) *bool {
  63. if v {
  64. return &v
  65. } else {
  66. return nil
  67. }
  68. }
  69. const (
  70. asan sanitizerType = iota + 1
  71. hwasan
  72. tsan
  73. intOverflow
  74. cfi
  75. scs
  76. fuzzer
  77. )
  78. // Name of the sanitizer variation for this sanitizer type
  79. func (t sanitizerType) variationName() string {
  80. switch t {
  81. case asan:
  82. return "asan"
  83. case hwasan:
  84. return "hwasan"
  85. case tsan:
  86. return "tsan"
  87. case intOverflow:
  88. return "intOverflow"
  89. case cfi:
  90. return "cfi"
  91. case scs:
  92. return "scs"
  93. case fuzzer:
  94. return "fuzzer"
  95. default:
  96. panic(fmt.Errorf("unknown sanitizerType %d", t))
  97. }
  98. }
  99. // This is the sanitizer names in SANITIZE_[TARGET|HOST]
  100. func (t sanitizerType) name() string {
  101. switch t {
  102. case asan:
  103. return "address"
  104. case hwasan:
  105. return "hwaddress"
  106. case tsan:
  107. return "thread"
  108. case intOverflow:
  109. return "integer_overflow"
  110. case cfi:
  111. return "cfi"
  112. case scs:
  113. return "shadow-call-stack"
  114. case fuzzer:
  115. return "fuzzer"
  116. default:
  117. panic(fmt.Errorf("unknown sanitizerType %d", t))
  118. }
  119. }
  120. func (t sanitizerType) incompatibleWithCfi() bool {
  121. return t == asan || t == fuzzer || t == hwasan
  122. }
  123. type SanitizeProperties struct {
  124. // enable AddressSanitizer, ThreadSanitizer, or UndefinedBehaviorSanitizer
  125. Sanitize struct {
  126. Never *bool `android:"arch_variant"`
  127. // main sanitizers
  128. Address *bool `android:"arch_variant"`
  129. Thread *bool `android:"arch_variant"`
  130. Hwaddress *bool `android:"arch_variant"`
  131. // local sanitizers
  132. Undefined *bool `android:"arch_variant"`
  133. All_undefined *bool `android:"arch_variant"`
  134. Misc_undefined []string `android:"arch_variant"`
  135. Fuzzer *bool `android:"arch_variant"`
  136. Safestack *bool `android:"arch_variant"`
  137. Cfi *bool `android:"arch_variant"`
  138. Integer_overflow *bool `android:"arch_variant"`
  139. Scudo *bool `android:"arch_variant"`
  140. Scs *bool `android:"arch_variant"`
  141. // Sanitizers to run in the diagnostic mode (as opposed to the release mode).
  142. // Replaces abort() on error with a human-readable error message.
  143. // Address and Thread sanitizers always run in diagnostic mode.
  144. Diag struct {
  145. Undefined *bool `android:"arch_variant"`
  146. Cfi *bool `android:"arch_variant"`
  147. Integer_overflow *bool `android:"arch_variant"`
  148. Misc_undefined []string `android:"arch_variant"`
  149. No_recover []string
  150. }
  151. // value to pass to -fsanitize-recover=
  152. Recover []string
  153. // value to pass to -fsanitize-blacklist
  154. Blacklist *string
  155. } `android:"arch_variant"`
  156. SanitizerEnabled bool `blueprint:"mutated"`
  157. SanitizeDep bool `blueprint:"mutated"`
  158. MinimalRuntimeDep bool `blueprint:"mutated"`
  159. BuiltinsDep bool `blueprint:"mutated"`
  160. UbsanRuntimeDep bool `blueprint:"mutated"`
  161. InSanitizerDir bool `blueprint:"mutated"`
  162. Sanitizers []string `blueprint:"mutated"`
  163. DiagSanitizers []string `blueprint:"mutated"`
  164. }
  165. type sanitize struct {
  166. Properties SanitizeProperties
  167. }
  168. func init() {
  169. android.RegisterMakeVarsProvider(pctx, cfiMakeVarsProvider)
  170. android.RegisterMakeVarsProvider(pctx, hwasanMakeVarsProvider)
  171. }
  172. func (sanitize *sanitize) props() []interface{} {
  173. return []interface{}{&sanitize.Properties}
  174. }
  175. func (sanitize *sanitize) begin(ctx BaseModuleContext) {
  176. s := &sanitize.Properties.Sanitize
  177. // Don't apply sanitizers to NDK code.
  178. if ctx.useSdk() {
  179. s.Never = BoolPtr(true)
  180. }
  181. // Sanitizers do not work on Fuchsia yet.
  182. if ctx.Fuchsia() {
  183. s.Never = BoolPtr(true)
  184. }
  185. // Never always wins.
  186. if Bool(s.Never) {
  187. return
  188. }
  189. var globalSanitizers []string
  190. var globalSanitizersDiag []string
  191. if ctx.Host() {
  192. if !ctx.Windows() {
  193. globalSanitizers = ctx.Config().SanitizeHost()
  194. }
  195. } else {
  196. arches := ctx.Config().SanitizeDeviceArch()
  197. if len(arches) == 0 || inList(ctx.Arch().ArchType.Name, arches) {
  198. globalSanitizers = ctx.Config().SanitizeDevice()
  199. globalSanitizersDiag = ctx.Config().SanitizeDeviceDiag()
  200. }
  201. }
  202. if len(globalSanitizers) > 0 {
  203. var found bool
  204. if found, globalSanitizers = removeFromList("undefined", globalSanitizers); found && s.All_undefined == nil {
  205. s.All_undefined = boolPtr(true)
  206. }
  207. if found, globalSanitizers = removeFromList("default-ub", globalSanitizers); found && s.Undefined == nil {
  208. s.Undefined = boolPtr(true)
  209. }
  210. if found, globalSanitizers = removeFromList("address", globalSanitizers); found && s.Address == nil {
  211. s.Address = boolPtr(true)
  212. }
  213. if found, globalSanitizers = removeFromList("thread", globalSanitizers); found && s.Thread == nil {
  214. s.Thread = boolPtr(true)
  215. }
  216. if found, globalSanitizers = removeFromList("fuzzer", globalSanitizers); found && s.Fuzzer == nil {
  217. s.Fuzzer = boolPtr(true)
  218. }
  219. if found, globalSanitizers = removeFromList("safe-stack", globalSanitizers); found && s.Safestack == nil {
  220. s.Safestack = boolPtr(true)
  221. }
  222. if found, globalSanitizers = removeFromList("cfi", globalSanitizers); found && s.Cfi == nil {
  223. if !ctx.Config().CFIDisabledForPath(ctx.ModuleDir()) {
  224. s.Cfi = boolPtr(true)
  225. }
  226. }
  227. // Global integer_overflow builds do not support static libraries.
  228. if found, globalSanitizers = removeFromList("integer_overflow", globalSanitizers); found && s.Integer_overflow == nil {
  229. if !ctx.Config().IntegerOverflowDisabledForPath(ctx.ModuleDir()) && !ctx.static() {
  230. s.Integer_overflow = boolPtr(true)
  231. }
  232. }
  233. if found, globalSanitizers = removeFromList("scudo", globalSanitizers); found && s.Scudo == nil {
  234. s.Scudo = boolPtr(true)
  235. }
  236. if found, globalSanitizers = removeFromList("hwaddress", globalSanitizers); found && s.Hwaddress == nil {
  237. s.Hwaddress = boolPtr(true)
  238. }
  239. if len(globalSanitizers) > 0 {
  240. ctx.ModuleErrorf("unknown global sanitizer option %s", globalSanitizers[0])
  241. }
  242. // Global integer_overflow builds do not support static library diagnostics.
  243. if found, globalSanitizersDiag = removeFromList("integer_overflow", globalSanitizersDiag); found &&
  244. s.Diag.Integer_overflow == nil && Bool(s.Integer_overflow) && !ctx.static() {
  245. s.Diag.Integer_overflow = boolPtr(true)
  246. }
  247. if found, globalSanitizersDiag = removeFromList("cfi", globalSanitizersDiag); found &&
  248. s.Diag.Cfi == nil && Bool(s.Cfi) {
  249. s.Diag.Cfi = boolPtr(true)
  250. }
  251. if len(globalSanitizersDiag) > 0 {
  252. ctx.ModuleErrorf("unknown global sanitizer diagnostics option %s", globalSanitizersDiag[0])
  253. }
  254. }
  255. // Enable CFI for all components in the include paths (for Aarch64 only)
  256. if s.Cfi == nil && ctx.Config().CFIEnabledForPath(ctx.ModuleDir()) && ctx.Arch().ArchType == android.Arm64 {
  257. s.Cfi = boolPtr(true)
  258. if inList("cfi", ctx.Config().SanitizeDeviceDiag()) {
  259. s.Diag.Cfi = boolPtr(true)
  260. }
  261. }
  262. // Is CFI actually enabled?
  263. if !ctx.Config().EnableCFI() {
  264. s.Cfi = nil
  265. s.Diag.Cfi = nil
  266. }
  267. // Also disable CFI for arm32 until b/35157333 is fixed.
  268. if ctx.Arch().ArchType == android.Arm {
  269. s.Cfi = nil
  270. s.Diag.Cfi = nil
  271. }
  272. // HWASan requires AArch64 hardware feature (top-byte-ignore).
  273. if ctx.Arch().ArchType != android.Arm64 {
  274. s.Hwaddress = nil
  275. }
  276. // SCS is only implemented on AArch64.
  277. if ctx.Arch().ArchType != android.Arm64 {
  278. s.Scs = nil
  279. }
  280. // Also disable CFI if ASAN is enabled.
  281. if Bool(s.Address) || Bool(s.Hwaddress) {
  282. s.Cfi = nil
  283. s.Diag.Cfi = nil
  284. }
  285. // Disable sanitizers that depend on the UBSan runtime for windows/darwin builds.
  286. if !ctx.Os().Linux() {
  287. s.Cfi = nil
  288. s.Diag.Cfi = nil
  289. s.Misc_undefined = nil
  290. s.Undefined = nil
  291. s.All_undefined = nil
  292. s.Integer_overflow = nil
  293. }
  294. // Also disable CFI for VNDK variants of components
  295. if ctx.isVndk() && ctx.useVndk() {
  296. s.Cfi = nil
  297. s.Diag.Cfi = nil
  298. }
  299. // Also disable CFI if building against snapshot.
  300. vndkVersion := ctx.DeviceConfig().VndkVersion()
  301. if ctx.useVndk() && vndkVersion != "current" && vndkVersion != "" {
  302. s.Cfi = nil
  303. }
  304. // HWASan ramdisk (which is built from recovery) goes over some bootloader limit.
  305. // Keep libc instrumented so that ramdisk / recovery can run hwasan-instrumented code if necessary.
  306. if (ctx.inRamdisk() || ctx.inRecovery()) && !strings.HasPrefix(ctx.ModuleDir(), "bionic/libc") {
  307. s.Hwaddress = nil
  308. }
  309. if ctx.staticBinary() {
  310. s.Address = nil
  311. s.Fuzzer = nil
  312. s.Thread = nil
  313. }
  314. if Bool(s.All_undefined) {
  315. s.Undefined = nil
  316. }
  317. if !ctx.toolchain().Is64Bit() {
  318. // TSAN and SafeStack are not supported on 32-bit architectures
  319. s.Thread = nil
  320. s.Safestack = nil
  321. // TODO(ccross): error for compile_multilib = "32"?
  322. }
  323. if ctx.Os() != android.Windows && (Bool(s.All_undefined) || Bool(s.Undefined) || Bool(s.Address) || Bool(s.Thread) ||
  324. Bool(s.Fuzzer) || Bool(s.Safestack) || Bool(s.Cfi) || Bool(s.Integer_overflow) || len(s.Misc_undefined) > 0 ||
  325. Bool(s.Scudo) || Bool(s.Hwaddress) || Bool(s.Scs)) {
  326. sanitize.Properties.SanitizerEnabled = true
  327. }
  328. // Disable Scudo if ASan or TSan is enabled, or if it's disabled globally.
  329. if Bool(s.Address) || Bool(s.Thread) || Bool(s.Hwaddress) || ctx.Config().DisableScudo() {
  330. s.Scudo = nil
  331. }
  332. if Bool(s.Hwaddress) {
  333. s.Address = nil
  334. s.Thread = nil
  335. }
  336. // TODO(b/131771163): CFI transiently depends on LTO, and thus Fuzzer is
  337. // mutually incompatible.
  338. if Bool(s.Fuzzer) {
  339. s.Cfi = nil
  340. }
  341. }
  342. func (sanitize *sanitize) deps(ctx BaseModuleContext, deps Deps) Deps {
  343. if !sanitize.Properties.SanitizerEnabled { // || c.static() {
  344. return deps
  345. }
  346. if ctx.Device() {
  347. if Bool(sanitize.Properties.Sanitize.Address) {
  348. // Compiling asan and having libc_scudo in the same
  349. // executable will cause the executable to crash.
  350. // Remove libc_scudo since it is only used to override
  351. // allocation functions which asan already overrides.
  352. _, deps.SharedLibs = removeFromList("libc_scudo", deps.SharedLibs)
  353. }
  354. }
  355. return deps
  356. }
  357. func toDisableImplicitIntegerChange(flags []string) bool {
  358. // Returns true if any flag is fsanitize*integer, and there is
  359. // no explicit flag about sanitize=implicit-integer-sign-change.
  360. for _, f := range flags {
  361. if strings.Contains(f, "sanitize=implicit-integer-sign-change") {
  362. return false
  363. }
  364. }
  365. for _, f := range flags {
  366. if strings.HasPrefix(f, "-fsanitize") && strings.Contains(f, "integer") {
  367. return true
  368. }
  369. }
  370. return false
  371. }
  372. func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags) Flags {
  373. minimalRuntimeLib := config.UndefinedBehaviorSanitizerMinimalRuntimeLibrary(ctx.toolchain()) + ".a"
  374. minimalRuntimePath := "${config.ClangAsanLibDir}/" + minimalRuntimeLib
  375. builtinsRuntimeLib := config.BuiltinsRuntimeLibrary(ctx.toolchain()) + ".a"
  376. builtinsRuntimePath := "${config.ClangAsanLibDir}/" + builtinsRuntimeLib
  377. if sanitize.Properties.MinimalRuntimeDep {
  378. flags.Local.LdFlags = append(flags.Local.LdFlags,
  379. minimalRuntimePath,
  380. "-Wl,--exclude-libs,"+minimalRuntimeLib)
  381. }
  382. if sanitize.Properties.BuiltinsDep {
  383. flags.libFlags = append([]string{builtinsRuntimePath}, flags.libFlags...)
  384. }
  385. if !sanitize.Properties.SanitizerEnabled && !sanitize.Properties.UbsanRuntimeDep {
  386. return flags
  387. }
  388. if Bool(sanitize.Properties.Sanitize.Address) {
  389. if ctx.Arch().ArchType == android.Arm {
  390. // Frame pointer based unwinder in ASan requires ARM frame setup.
  391. // TODO: put in flags?
  392. flags.RequiredInstructionSet = "arm"
  393. }
  394. flags.Local.CFlags = append(flags.Local.CFlags, asanCflags...)
  395. flags.Local.LdFlags = append(flags.Local.LdFlags, asanLdflags...)
  396. if ctx.Host() {
  397. // -nodefaultlibs (provided with libc++) prevents the driver from linking
  398. // libraries needed with -fsanitize=address. http://b/18650275 (WAI)
  399. flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--no-as-needed")
  400. } else {
  401. flags.Local.CFlags = append(flags.Local.CFlags, "-mllvm", "-asan-globals=0")
  402. if ctx.bootstrap() {
  403. flags.DynamicLinker = "/system/bin/bootstrap/linker_asan"
  404. } else {
  405. flags.DynamicLinker = "/system/bin/linker_asan"
  406. }
  407. if flags.Toolchain.Is64Bit() {
  408. flags.DynamicLinker += "64"
  409. }
  410. }
  411. }
  412. if Bool(sanitize.Properties.Sanitize.Hwaddress) {
  413. flags.Local.CFlags = append(flags.Local.CFlags, hwasanCflags...)
  414. }
  415. if Bool(sanitize.Properties.Sanitize.Fuzzer) {
  416. flags.Local.CFlags = append(flags.Local.CFlags, "-fsanitize=fuzzer-no-link")
  417. // TODO(b/131771163): LTO and Fuzzer support is mutually incompatible.
  418. _, flags.Local.LdFlags = removeFromList("-flto", flags.Local.LdFlags)
  419. _, flags.Local.CFlags = removeFromList("-flto", flags.Local.CFlags)
  420. flags.Local.LdFlags = append(flags.Local.LdFlags, "-fno-lto")
  421. flags.Local.CFlags = append(flags.Local.CFlags, "-fno-lto")
  422. // TODO(b/142430592): Upstream linker scripts for sanitizer runtime libraries
  423. // discard the sancov_lowest_stack symbol, because it's emulated TLS (and thus
  424. // doesn't match the linker script due to the "__emutls_v." prefix).
  425. flags.Local.LdFlags = append(flags.Local.LdFlags, "-fno-sanitize-coverage=stack-depth")
  426. flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize-coverage=stack-depth")
  427. // TODO(b/133876586): Experimental PM breaks sanitizer coverage.
  428. flags.Local.CFlags = append(flags.Local.CFlags, "-fno-experimental-new-pass-manager")
  429. // Disable fortify for fuzzing builds. Generally, we'll be building with
  430. // UBSan or ASan here and the fortify checks pollute the stack traces.
  431. flags.Local.CFlags = append(flags.Local.CFlags, "-U_FORTIFY_SOURCE")
  432. // Build fuzzer-sanitized libraries with an $ORIGIN DT_RUNPATH. Android's
  433. // linker uses DT_RUNPATH, not DT_RPATH. When we deploy cc_fuzz targets and
  434. // their libraries to /data/fuzz/<arch>/lib, any transient shared library gets
  435. // the DT_RUNPATH from the shared library above it, and not the executable,
  436. // meaning that the lookup falls back to the system. Adding the $ORIGIN to the
  437. // DT_RUNPATH here means that transient shared libraries can be found
  438. // colocated with their parents.
  439. flags.Local.LdFlags = append(flags.Local.LdFlags, `-Wl,-rpath,\$$ORIGIN`)
  440. }
  441. if Bool(sanitize.Properties.Sanitize.Cfi) {
  442. if ctx.Arch().ArchType == android.Arm {
  443. // __cfi_check needs to be built as Thumb (see the code in linker_cfi.cpp). LLVM is not set up
  444. // to do this on a function basis, so force Thumb on the entire module.
  445. flags.RequiredInstructionSet = "thumb"
  446. }
  447. flags.Local.CFlags = append(flags.Local.CFlags, cfiCflags...)
  448. flags.Local.AsFlags = append(flags.Local.AsFlags, cfiAsflags...)
  449. // Only append the default visibility flag if -fvisibility has not already been set
  450. // to hidden.
  451. if !inList("-fvisibility=hidden", flags.Local.CFlags) {
  452. flags.Local.CFlags = append(flags.Local.CFlags, "-fvisibility=default")
  453. }
  454. flags.Local.LdFlags = append(flags.Local.LdFlags, cfiLdflags...)
  455. if ctx.staticBinary() {
  456. _, flags.Local.CFlags = removeFromList("-fsanitize-cfi-cross-dso", flags.Local.CFlags)
  457. _, flags.Local.LdFlags = removeFromList("-fsanitize-cfi-cross-dso", flags.Local.LdFlags)
  458. }
  459. }
  460. if Bool(sanitize.Properties.Sanitize.Integer_overflow) {
  461. flags.Local.CFlags = append(flags.Local.CFlags, intOverflowCflags...)
  462. }
  463. if len(sanitize.Properties.Sanitizers) > 0 {
  464. sanitizeArg := "-fsanitize=" + strings.Join(sanitize.Properties.Sanitizers, ",")
  465. flags.Local.CFlags = append(flags.Local.CFlags, sanitizeArg)
  466. flags.Local.AsFlags = append(flags.Local.AsFlags, sanitizeArg)
  467. if ctx.Host() {
  468. // Host sanitizers only link symbols in the final executable, so
  469. // there will always be undefined symbols in intermediate libraries.
  470. _, flags.Global.LdFlags = removeFromList("-Wl,--no-undefined", flags.Global.LdFlags)
  471. flags.Local.LdFlags = append(flags.Local.LdFlags, sanitizeArg)
  472. // non-Bionic toolchain prebuilts are missing UBSan's vptr and function sanitizers
  473. if !ctx.toolchain().Bionic() {
  474. flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize=vptr,function")
  475. }
  476. }
  477. if enableMinimalRuntime(sanitize) {
  478. flags.Local.CFlags = append(flags.Local.CFlags, strings.Join(minimalRuntimeFlags, " "))
  479. flags.libFlags = append([]string{minimalRuntimePath}, flags.libFlags...)
  480. flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--exclude-libs,"+minimalRuntimeLib)
  481. if !ctx.toolchain().Bionic() {
  482. flags.libFlags = append([]string{builtinsRuntimePath}, flags.libFlags...)
  483. }
  484. }
  485. if Bool(sanitize.Properties.Sanitize.Fuzzer) {
  486. // When fuzzing, we wish to crash with diagnostics on any bug.
  487. flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize-trap=all", "-fno-sanitize-recover=all")
  488. } else if ctx.Host() {
  489. flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize-recover=all")
  490. } else {
  491. flags.Local.CFlags = append(flags.Local.CFlags, "-fsanitize-trap=all", "-ftrap-function=abort")
  492. }
  493. // http://b/119329758, Android core does not boot up with this sanitizer yet.
  494. if toDisableImplicitIntegerChange(flags.Local.CFlags) {
  495. flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize=implicit-integer-sign-change")
  496. }
  497. }
  498. if len(sanitize.Properties.DiagSanitizers) > 0 {
  499. flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize-trap="+strings.Join(sanitize.Properties.DiagSanitizers, ","))
  500. }
  501. // FIXME: enable RTTI if diag + (cfi or vptr)
  502. if sanitize.Properties.Sanitize.Recover != nil {
  503. flags.Local.CFlags = append(flags.Local.CFlags, "-fsanitize-recover="+
  504. strings.Join(sanitize.Properties.Sanitize.Recover, ","))
  505. }
  506. if sanitize.Properties.Sanitize.Diag.No_recover != nil {
  507. flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize-recover="+
  508. strings.Join(sanitize.Properties.Sanitize.Diag.No_recover, ","))
  509. }
  510. blacklist := android.OptionalPathForModuleSrc(ctx, sanitize.Properties.Sanitize.Blacklist)
  511. if blacklist.Valid() {
  512. flags.Local.CFlags = append(flags.Local.CFlags, "-fsanitize-blacklist="+blacklist.String())
  513. flags.CFlagsDeps = append(flags.CFlagsDeps, blacklist.Path())
  514. }
  515. return flags
  516. }
  517. func (sanitize *sanitize) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
  518. // Add a suffix for cfi/hwasan/scs-enabled static/header libraries to allow surfacing
  519. // both the sanitized and non-sanitized variants to make without a name conflict.
  520. if entries.Class == "STATIC_LIBRARIES" || entries.Class == "HEADER_LIBRARIES" {
  521. if Bool(sanitize.Properties.Sanitize.Cfi) {
  522. entries.SubName += ".cfi"
  523. }
  524. if Bool(sanitize.Properties.Sanitize.Hwaddress) {
  525. entries.SubName += ".hwasan"
  526. }
  527. if Bool(sanitize.Properties.Sanitize.Scs) {
  528. entries.SubName += ".scs"
  529. }
  530. }
  531. }
  532. func (sanitize *sanitize) inSanitizerDir() bool {
  533. return sanitize.Properties.InSanitizerDir
  534. }
  535. func (sanitize *sanitize) getSanitizerBoolPtr(t sanitizerType) *bool {
  536. switch t {
  537. case asan:
  538. return sanitize.Properties.Sanitize.Address
  539. case hwasan:
  540. return sanitize.Properties.Sanitize.Hwaddress
  541. case tsan:
  542. return sanitize.Properties.Sanitize.Thread
  543. case intOverflow:
  544. return sanitize.Properties.Sanitize.Integer_overflow
  545. case cfi:
  546. return sanitize.Properties.Sanitize.Cfi
  547. case scs:
  548. return sanitize.Properties.Sanitize.Scs
  549. case fuzzer:
  550. return sanitize.Properties.Sanitize.Fuzzer
  551. default:
  552. panic(fmt.Errorf("unknown sanitizerType %d", t))
  553. }
  554. }
  555. func (sanitize *sanitize) isUnsanitizedVariant() bool {
  556. return !sanitize.isSanitizerEnabled(asan) &&
  557. !sanitize.isSanitizerEnabled(hwasan) &&
  558. !sanitize.isSanitizerEnabled(tsan) &&
  559. !sanitize.isSanitizerEnabled(cfi) &&
  560. !sanitize.isSanitizerEnabled(scs) &&
  561. !sanitize.isSanitizerEnabled(fuzzer)
  562. }
  563. func (sanitize *sanitize) isVariantOnProductionDevice() bool {
  564. return !sanitize.isSanitizerEnabled(asan) &&
  565. !sanitize.isSanitizerEnabled(hwasan) &&
  566. !sanitize.isSanitizerEnabled(tsan) &&
  567. !sanitize.isSanitizerEnabled(fuzzer)
  568. }
  569. func (sanitize *sanitize) SetSanitizer(t sanitizerType, b bool) {
  570. switch t {
  571. case asan:
  572. sanitize.Properties.Sanitize.Address = boolPtr(b)
  573. case hwasan:
  574. sanitize.Properties.Sanitize.Hwaddress = boolPtr(b)
  575. case tsan:
  576. sanitize.Properties.Sanitize.Thread = boolPtr(b)
  577. case intOverflow:
  578. sanitize.Properties.Sanitize.Integer_overflow = boolPtr(b)
  579. case cfi:
  580. sanitize.Properties.Sanitize.Cfi = boolPtr(b)
  581. case scs:
  582. sanitize.Properties.Sanitize.Scs = boolPtr(b)
  583. case fuzzer:
  584. sanitize.Properties.Sanitize.Fuzzer = boolPtr(b)
  585. default:
  586. panic(fmt.Errorf("unknown sanitizerType %d", t))
  587. }
  588. if b {
  589. sanitize.Properties.SanitizerEnabled = true
  590. }
  591. }
  592. // Check if the sanitizer is explicitly disabled (as opposed to nil by
  593. // virtue of not being set).
  594. func (sanitize *sanitize) isSanitizerExplicitlyDisabled(t sanitizerType) bool {
  595. if sanitize == nil {
  596. return false
  597. }
  598. sanitizerVal := sanitize.getSanitizerBoolPtr(t)
  599. return sanitizerVal != nil && *sanitizerVal == false
  600. }
  601. // There isn't an analog of the method above (ie:isSanitizerExplicitlyEnabled)
  602. // because enabling a sanitizer either directly (via the blueprint) or
  603. // indirectly (via a mutator) sets the bool ptr to true, and you can't
  604. // distinguish between the cases. It isn't needed though - both cases can be
  605. // treated identically.
  606. func (sanitize *sanitize) isSanitizerEnabled(t sanitizerType) bool {
  607. if sanitize == nil {
  608. return false
  609. }
  610. sanitizerVal := sanitize.getSanitizerBoolPtr(t)
  611. return sanitizerVal != nil && *sanitizerVal == true
  612. }
  613. func isSanitizableDependencyTag(tag blueprint.DependencyTag) bool {
  614. t, ok := tag.(DependencyTag)
  615. return ok && t.Library || t == reuseObjTag || t == objDepTag
  616. }
  617. // Propagate sanitizer requirements down from binaries
  618. func sanitizerDepsMutator(t sanitizerType) func(android.TopDownMutatorContext) {
  619. return func(mctx android.TopDownMutatorContext) {
  620. if c, ok := mctx.Module().(*Module); ok && c.sanitize.isSanitizerEnabled(t) {
  621. mctx.WalkDeps(func(child, parent android.Module) bool {
  622. if !isSanitizableDependencyTag(mctx.OtherModuleDependencyTag(child)) {
  623. return false
  624. }
  625. if d, ok := child.(*Module); ok && d.sanitize != nil &&
  626. !Bool(d.sanitize.Properties.Sanitize.Never) &&
  627. !d.sanitize.isSanitizerExplicitlyDisabled(t) {
  628. if t == cfi || t == hwasan || t == scs {
  629. if d.static() {
  630. d.sanitize.Properties.SanitizeDep = true
  631. }
  632. } else {
  633. d.sanitize.Properties.SanitizeDep = true
  634. }
  635. }
  636. return true
  637. })
  638. } else if sanitizeable, ok := mctx.Module().(Sanitizeable); ok {
  639. // If an APEX module includes a lib which is enabled for a sanitizer T, then
  640. // the APEX module is also enabled for the same sanitizer type.
  641. mctx.VisitDirectDeps(func(child android.Module) {
  642. if c, ok := child.(*Module); ok && c.sanitize.isSanitizerEnabled(t) {
  643. sanitizeable.EnableSanitizer(t.name())
  644. }
  645. })
  646. }
  647. }
  648. }
  649. // Propagate the ubsan minimal runtime dependency when there are integer overflow sanitized static dependencies.
  650. func sanitizerRuntimeDepsMutator(mctx android.TopDownMutatorContext) {
  651. if c, ok := mctx.Module().(*Module); ok && c.sanitize != nil {
  652. mctx.WalkDeps(func(child, parent android.Module) bool {
  653. if !isSanitizableDependencyTag(mctx.OtherModuleDependencyTag(child)) {
  654. return false
  655. }
  656. d, ok := child.(*Module)
  657. if !ok || !d.static() {
  658. return false
  659. }
  660. if d.sanitize != nil {
  661. if enableMinimalRuntime(d.sanitize) {
  662. // If a static dependency is built with the minimal runtime,
  663. // make sure we include the ubsan minimal runtime.
  664. c.sanitize.Properties.MinimalRuntimeDep = true
  665. } else if enableUbsanRuntime(d.sanitize) {
  666. // If a static dependency runs with full ubsan diagnostics,
  667. // make sure we include the ubsan runtime.
  668. c.sanitize.Properties.UbsanRuntimeDep = true
  669. }
  670. if c.sanitize.Properties.MinimalRuntimeDep &&
  671. c.sanitize.Properties.UbsanRuntimeDep {
  672. // both flags that this mutator might set are true, so don't bother recursing
  673. return false
  674. }
  675. if c.Os() == android.Linux {
  676. c.sanitize.Properties.BuiltinsDep = true
  677. }
  678. return true
  679. }
  680. if p, ok := d.linker.(*vendorSnapshotLibraryDecorator); ok {
  681. if Bool(p.properties.Sanitize_minimal_dep) {
  682. c.sanitize.Properties.MinimalRuntimeDep = true
  683. }
  684. if Bool(p.properties.Sanitize_ubsan_dep) {
  685. c.sanitize.Properties.UbsanRuntimeDep = true
  686. }
  687. }
  688. return false
  689. })
  690. }
  691. }
  692. // Add the dependency to the runtime library for each of the sanitizer variants
  693. func sanitizerRuntimeMutator(mctx android.BottomUpMutatorContext) {
  694. if c, ok := mctx.Module().(*Module); ok && c.sanitize != nil {
  695. if !c.Enabled() {
  696. return
  697. }
  698. var sanitizers []string
  699. var diagSanitizers []string
  700. if Bool(c.sanitize.Properties.Sanitize.All_undefined) {
  701. sanitizers = append(sanitizers, "undefined")
  702. } else {
  703. if Bool(c.sanitize.Properties.Sanitize.Undefined) {
  704. sanitizers = append(sanitizers,
  705. "bool",
  706. "integer-divide-by-zero",
  707. "return",
  708. "returns-nonnull-attribute",
  709. "shift-exponent",
  710. "unreachable",
  711. "vla-bound",
  712. // TODO(danalbert): The following checks currently have compiler performance issues.
  713. //"alignment",
  714. //"bounds",
  715. //"enum",
  716. //"float-cast-overflow",
  717. //"float-divide-by-zero",
  718. //"nonnull-attribute",
  719. //"null",
  720. //"shift-base",
  721. //"signed-integer-overflow",
  722. // TODO(danalbert): Fix UB in libc++'s __tree so we can turn this on.
  723. // https://llvm.org/PR19302
  724. // http://reviews.llvm.org/D6974
  725. // "object-size",
  726. )
  727. }
  728. sanitizers = append(sanitizers, c.sanitize.Properties.Sanitize.Misc_undefined...)
  729. }
  730. if Bool(c.sanitize.Properties.Sanitize.Diag.Undefined) {
  731. diagSanitizers = append(diagSanitizers, "undefined")
  732. }
  733. diagSanitizers = append(diagSanitizers, c.sanitize.Properties.Sanitize.Diag.Misc_undefined...)
  734. if Bool(c.sanitize.Properties.Sanitize.Address) {
  735. sanitizers = append(sanitizers, "address")
  736. diagSanitizers = append(diagSanitizers, "address")
  737. }
  738. if Bool(c.sanitize.Properties.Sanitize.Hwaddress) {
  739. sanitizers = append(sanitizers, "hwaddress")
  740. }
  741. if Bool(c.sanitize.Properties.Sanitize.Thread) {
  742. sanitizers = append(sanitizers, "thread")
  743. }
  744. if Bool(c.sanitize.Properties.Sanitize.Safestack) {
  745. sanitizers = append(sanitizers, "safe-stack")
  746. }
  747. if Bool(c.sanitize.Properties.Sanitize.Cfi) {
  748. sanitizers = append(sanitizers, "cfi")
  749. if Bool(c.sanitize.Properties.Sanitize.Diag.Cfi) {
  750. diagSanitizers = append(diagSanitizers, "cfi")
  751. }
  752. }
  753. if Bool(c.sanitize.Properties.Sanitize.Integer_overflow) {
  754. sanitizers = append(sanitizers, "unsigned-integer-overflow")
  755. sanitizers = append(sanitizers, "signed-integer-overflow")
  756. if Bool(c.sanitize.Properties.Sanitize.Diag.Integer_overflow) {
  757. diagSanitizers = append(diagSanitizers, "unsigned-integer-overflow")
  758. diagSanitizers = append(diagSanitizers, "signed-integer-overflow")
  759. }
  760. }
  761. if Bool(c.sanitize.Properties.Sanitize.Scudo) {
  762. sanitizers = append(sanitizers, "scudo")
  763. }
  764. if Bool(c.sanitize.Properties.Sanitize.Scs) {
  765. sanitizers = append(sanitizers, "shadow-call-stack")
  766. }
  767. if Bool(c.sanitize.Properties.Sanitize.Fuzzer) {
  768. sanitizers = append(sanitizers, "fuzzer-no-link")
  769. }
  770. // Save the list of sanitizers. These will be used again when generating
  771. // the build rules (for Cflags, etc.)
  772. c.sanitize.Properties.Sanitizers = sanitizers
  773. c.sanitize.Properties.DiagSanitizers = diagSanitizers
  774. // Determine the runtime library required
  775. runtimeLibrary := ""
  776. var extraStaticDeps []string
  777. toolchain := c.toolchain(mctx)
  778. if Bool(c.sanitize.Properties.Sanitize.Address) {
  779. runtimeLibrary = config.AddressSanitizerRuntimeLibrary(toolchain)
  780. } else if Bool(c.sanitize.Properties.Sanitize.Hwaddress) {
  781. if c.staticBinary() {
  782. runtimeLibrary = config.HWAddressSanitizerStaticLibrary(toolchain)
  783. extraStaticDeps = []string{"libdl"}
  784. } else {
  785. runtimeLibrary = config.HWAddressSanitizerRuntimeLibrary(toolchain)
  786. }
  787. } else if Bool(c.sanitize.Properties.Sanitize.Thread) {
  788. runtimeLibrary = config.ThreadSanitizerRuntimeLibrary(toolchain)
  789. } else if Bool(c.sanitize.Properties.Sanitize.Scudo) {
  790. if len(diagSanitizers) == 0 && !c.sanitize.Properties.UbsanRuntimeDep {
  791. runtimeLibrary = config.ScudoMinimalRuntimeLibrary(toolchain)
  792. } else {
  793. runtimeLibrary = config.ScudoRuntimeLibrary(toolchain)
  794. }
  795. } else if len(diagSanitizers) > 0 || c.sanitize.Properties.UbsanRuntimeDep ||
  796. Bool(c.sanitize.Properties.Sanitize.Fuzzer) ||
  797. Bool(c.sanitize.Properties.Sanitize.Undefined) ||
  798. Bool(c.sanitize.Properties.Sanitize.All_undefined) {
  799. runtimeLibrary = config.UndefinedBehaviorSanitizerRuntimeLibrary(toolchain)
  800. }
  801. if runtimeLibrary != "" && (toolchain.Bionic() || c.sanitize.Properties.UbsanRuntimeDep) {
  802. // UBSan is supported on non-bionic linux host builds as well
  803. if isLlndkLibrary(runtimeLibrary, mctx.Config()) && !c.static() && c.UseVndk() {
  804. runtimeLibrary = runtimeLibrary + llndkLibrarySuffix
  805. }
  806. // Adding dependency to the runtime library. We are using *FarVariation*
  807. // because the runtime libraries themselves are not mutated by sanitizer
  808. // mutators and thus don't have sanitizer variants whereas this module
  809. // has been already mutated.
  810. //
  811. // Note that by adding dependency with {static|shared}DepTag, the lib is
  812. // added to libFlags and LOCAL_SHARED_LIBRARIES by cc.Module
  813. if c.staticBinary() {
  814. deps := append(extraStaticDeps, runtimeLibrary)
  815. // If we're using snapshots and in vendor, redirect to snapshot whenever possible
  816. if c.VndkVersion() == mctx.DeviceConfig().VndkVersion() {
  817. snapshots := vendorSnapshotStaticLibs(mctx.Config())
  818. for idx, dep := range deps {
  819. if lib, ok := snapshots.get(dep, mctx.Arch().ArchType); ok {
  820. deps[idx] = lib
  821. }
  822. }
  823. }
  824. // static executable gets static runtime libs
  825. mctx.AddFarVariationDependencies(append(mctx.Target().Variations(), []blueprint.Variation{
  826. {Mutator: "link", Variation: "static"},
  827. c.ImageVariation(),
  828. }...), StaticDepTag, deps...)
  829. } else if !c.static() && !c.header() {
  830. // If we're using snapshots and in vendor, redirect to snapshot whenever possible
  831. if c.VndkVersion() == mctx.DeviceConfig().VndkVersion() {
  832. snapshots := vendorSnapshotSharedLibs(mctx.Config())
  833. if lib, ok := snapshots.get(runtimeLibrary, mctx.Arch().ArchType); ok {
  834. runtimeLibrary = lib
  835. }
  836. }
  837. // dynamic executable and shared libs get shared runtime libs
  838. mctx.AddFarVariationDependencies(append(mctx.Target().Variations(), []blueprint.Variation{
  839. {Mutator: "link", Variation: "shared"},
  840. c.ImageVariation(),
  841. }...), earlySharedDepTag, runtimeLibrary)
  842. }
  843. // static lib does not have dependency to the runtime library. The
  844. // dependency will be added to the executables or shared libs using
  845. // the static lib.
  846. }
  847. }
  848. }
  849. type Sanitizeable interface {
  850. android.Module
  851. IsSanitizerEnabled(ctx android.BaseModuleContext, sanitizerName string) bool
  852. EnableSanitizer(sanitizerName string)
  853. }
  854. // Create sanitized variants for modules that need them
  855. func sanitizerMutator(t sanitizerType) func(android.BottomUpMutatorContext) {
  856. return func(mctx android.BottomUpMutatorContext) {
  857. if c, ok := mctx.Module().(*Module); ok && c.sanitize != nil {
  858. if c.isDependencyRoot() && c.sanitize.isSanitizerEnabled(t) {
  859. modules := mctx.CreateVariations(t.variationName())
  860. modules[0].(*Module).sanitize.SetSanitizer(t, true)
  861. } else if c.sanitize.isSanitizerEnabled(t) || c.sanitize.Properties.SanitizeDep {
  862. isSanitizerEnabled := c.sanitize.isSanitizerEnabled(t)
  863. if mctx.Device() && t.incompatibleWithCfi() {
  864. // TODO: Make sure that cfi mutator runs "after" any of the sanitizers that
  865. // are incompatible with cfi
  866. c.sanitize.SetSanitizer(cfi, false)
  867. }
  868. if c.static() || c.header() || t == asan || t == fuzzer {
  869. // Static and header libs are split into non-sanitized and sanitized variants.
  870. // Shared libs are not split. However, for asan and fuzzer, we split even for shared
  871. // libs because a library sanitized for asan/fuzzer can't be linked from a library
  872. // that isn't sanitized for asan/fuzzer.
  873. //
  874. // Note for defaultVariation: since we don't split for shared libs but for static/header
  875. // libs, it is possible for the sanitized variant of a static/header lib to depend
  876. // on non-sanitized variant of a shared lib. Such unfulfilled variation causes an
  877. // error when the module is split. defaultVariation is the name of the variation that
  878. // will be used when such a dangling dependency occurs during the split of the current
  879. // module. By setting it to the name of the sanitized variation, the dangling dependency
  880. // is redirected to the sanitized variant of the dependent module.
  881. defaultVariation := t.variationName()
  882. mctx.SetDefaultDependencyVariation(&defaultVariation)
  883. modules := mctx.CreateVariations("", t.variationName())
  884. modules[0].(*Module).sanitize.SetSanitizer(t, false)
  885. modules[1].(*Module).sanitize.SetSanitizer(t, true)
  886. modules[0].(*Module).sanitize.Properties.SanitizeDep = false
  887. modules[1].(*Module).sanitize.Properties.SanitizeDep = false
  888. // For cfi/scs/hwasan, we can export both sanitized and un-sanitized variants
  889. // to Make, because the sanitized version has a different suffix in name.
  890. // For other types of sanitizers, suppress the variation that is disabled.
  891. if t != cfi && t != scs && t != hwasan {
  892. if isSanitizerEnabled {
  893. modules[0].(*Module).Properties.PreventInstall = true
  894. modules[0].(*Module).Properties.HideFromMake = true
  895. } else {
  896. modules[1].(*Module).Properties.PreventInstall = true
  897. modules[1].(*Module).Properties.HideFromMake = true
  898. }
  899. }
  900. // Export the static lib name to make
  901. if c.static() {
  902. if t == cfi {
  903. appendStringSync(c.Name(), cfiStaticLibs(mctx.Config()), &cfiStaticLibsMutex)
  904. } else if t == hwasan {
  905. if c.UseVndk() {
  906. appendStringSync(c.Name(), hwasanVendorStaticLibs(mctx.Config()),
  907. &hwasanStaticLibsMutex)
  908. } else {
  909. appendStringSync(c.Name(), hwasanStaticLibs(mctx.Config()),
  910. &hwasanStaticLibsMutex)
  911. }
  912. }
  913. }
  914. } else {
  915. // Shared libs are not split. Only the sanitized variant is created.
  916. modules := mctx.CreateVariations(t.variationName())
  917. modules[0].(*Module).sanitize.SetSanitizer(t, true)
  918. modules[0].(*Module).sanitize.Properties.SanitizeDep = false
  919. // locate the asan libraries under /data/asan
  920. if mctx.Device() && t == asan && isSanitizerEnabled {
  921. modules[0].(*Module).sanitize.Properties.InSanitizerDir = true
  922. }
  923. }
  924. }
  925. c.sanitize.Properties.SanitizeDep = false
  926. } else if sanitizeable, ok := mctx.Module().(Sanitizeable); ok && sanitizeable.IsSanitizerEnabled(mctx, t.name()) {
  927. // APEX modules fall here
  928. mctx.CreateVariations(t.variationName())
  929. }
  930. }
  931. }
  932. var cfiStaticLibsKey = android.NewOnceKey("cfiStaticLibs")
  933. func cfiStaticLibs(config android.Config) *[]string {
  934. return config.Once(cfiStaticLibsKey, func() interface{} {
  935. return &[]string{}
  936. }).(*[]string)
  937. }
  938. var hwasanStaticLibsKey = android.NewOnceKey("hwasanStaticLibs")
  939. func hwasanStaticLibs(config android.Config) *[]string {
  940. return config.Once(hwasanStaticLibsKey, func() interface{} {
  941. return &[]string{}
  942. }).(*[]string)
  943. }
  944. var hwasanVendorStaticLibsKey = android.NewOnceKey("hwasanVendorStaticLibs")
  945. func hwasanVendorStaticLibs(config android.Config) *[]string {
  946. return config.Once(hwasanVendorStaticLibsKey, func() interface{} {
  947. return &[]string{}
  948. }).(*[]string)
  949. }
  950. func appendStringSync(item string, list *[]string, mutex *sync.Mutex) {
  951. mutex.Lock()
  952. *list = append(*list, item)
  953. mutex.Unlock()
  954. }
  955. func enableMinimalRuntime(sanitize *sanitize) bool {
  956. if !Bool(sanitize.Properties.Sanitize.Address) &&
  957. !Bool(sanitize.Properties.Sanitize.Hwaddress) &&
  958. !Bool(sanitize.Properties.Sanitize.Fuzzer) &&
  959. (Bool(sanitize.Properties.Sanitize.Integer_overflow) ||
  960. len(sanitize.Properties.Sanitize.Misc_undefined) > 0 ||
  961. Bool(sanitize.Properties.Sanitize.Undefined) ||
  962. Bool(sanitize.Properties.Sanitize.All_undefined)) &&
  963. !(Bool(sanitize.Properties.Sanitize.Diag.Integer_overflow) ||
  964. Bool(sanitize.Properties.Sanitize.Diag.Cfi) ||
  965. Bool(sanitize.Properties.Sanitize.Diag.Undefined) ||
  966. len(sanitize.Properties.Sanitize.Diag.Misc_undefined) > 0) {
  967. return true
  968. }
  969. return false
  970. }
  971. func enableUbsanRuntime(sanitize *sanitize) bool {
  972. return Bool(sanitize.Properties.Sanitize.Diag.Integer_overflow) ||
  973. Bool(sanitize.Properties.Sanitize.Diag.Undefined) ||
  974. len(sanitize.Properties.Sanitize.Diag.Misc_undefined) > 0
  975. }
  976. func cfiMakeVarsProvider(ctx android.MakeVarsContext) {
  977. cfiStaticLibs := cfiStaticLibs(ctx.Config())
  978. sort.Strings(*cfiStaticLibs)
  979. ctx.Strict("SOONG_CFI_STATIC_LIBRARIES", strings.Join(*cfiStaticLibs, " "))
  980. }
  981. func hwasanMakeVarsProvider(ctx android.MakeVarsContext) {
  982. hwasanStaticLibs := hwasanStaticLibs(ctx.Config())
  983. sort.Strings(*hwasanStaticLibs)
  984. ctx.Strict("SOONG_HWASAN_STATIC_LIBRARIES", strings.Join(*hwasanStaticLibs, " "))
  985. hwasanVendorStaticLibs := hwasanVendorStaticLibs(ctx.Config())
  986. sort.Strings(*hwasanVendorStaticLibs)
  987. ctx.Strict("SOONG_HWASAN_VENDOR_STATIC_LIBRARIES", strings.Join(*hwasanVendorStaticLibs, " "))
  988. }