sanitize.go 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540
  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. "github.com/google/blueprint/proptools"
  22. "android/soong/android"
  23. "android/soong/cc/config"
  24. "android/soong/snapshot"
  25. )
  26. var (
  27. // Any C flags added by sanitizer which libTooling tools may not
  28. // understand also need to be added to ClangLibToolingUnknownCflags in
  29. // cc/config/clang.go
  30. asanCflags = []string{
  31. "-fno-omit-frame-pointer",
  32. }
  33. asanLdflags = []string{"-Wl,-u,__asan_preinit"}
  34. hwasanCflags = []string{
  35. "-fno-omit-frame-pointer",
  36. "-Wno-frame-larger-than=",
  37. "-fsanitize-hwaddress-abi=platform",
  38. }
  39. // ThinLTO performs codegen during link time, thus these flags need to
  40. // passed to both CFLAGS and LDFLAGS.
  41. hwasanCommonflags = []string{
  42. // The following improves debug location information
  43. // availability at the cost of its accuracy. It increases
  44. // the likelihood of a stack variable's frame offset
  45. // to be recorded in the debug info, which is important
  46. // for the quality of hwasan reports. The downside is a
  47. // higher number of "optimized out" stack variables.
  48. // b/112437883.
  49. "-instcombine-lower-dbg-declare=0",
  50. // TODO(b/159343917): HWASan and GlobalISel don't play nicely, and
  51. // GlobalISel is the default at -O0 on aarch64.
  52. "--aarch64-enable-global-isel-at-O=-1",
  53. "-fast-isel=false",
  54. }
  55. cfiCflags = []string{"-flto", "-fsanitize-cfi-cross-dso",
  56. "-fsanitize-ignorelist=external/compiler-rt/lib/cfi/cfi_blocklist.txt"}
  57. // -flto and -fvisibility are required by clang when -fsanitize=cfi is
  58. // used, but have no effect on assembly files
  59. cfiAsflags = []string{"-flto", "-fvisibility=default"}
  60. cfiLdflags = []string{"-flto", "-fsanitize-cfi-cross-dso", "-fsanitize=cfi",
  61. "-Wl,-plugin-opt,O1"}
  62. cfiExportsMapPath = "build/soong/cc/config/cfi_exports.map"
  63. intOverflowCflags = []string{"-fsanitize-ignorelist=build/soong/cc/config/integer_overflow_blocklist.txt"}
  64. minimalRuntimeFlags = []string{"-fsanitize-minimal-runtime", "-fno-sanitize-trap=integer,undefined",
  65. "-fno-sanitize-recover=integer,undefined"}
  66. hwasanGlobalOptions = []string{"heap_history_size=1023", "stack_history_size=512",
  67. "export_memory_stats=0", "max_malloc_fill_size=0"}
  68. )
  69. type SanitizerType int
  70. const (
  71. Asan SanitizerType = iota + 1
  72. Hwasan
  73. tsan
  74. intOverflow
  75. scs
  76. Fuzzer
  77. Memtag_heap
  78. cfi // cfi is last to prevent it running before incompatible mutators
  79. )
  80. var Sanitizers = []SanitizerType{
  81. Asan,
  82. Hwasan,
  83. tsan,
  84. intOverflow,
  85. scs,
  86. Fuzzer,
  87. Memtag_heap,
  88. cfi, // cfi is last to prevent it running before incompatible mutators
  89. }
  90. // Name of the sanitizer variation for this sanitizer type
  91. func (t SanitizerType) variationName() string {
  92. switch t {
  93. case Asan:
  94. return "asan"
  95. case Hwasan:
  96. return "hwasan"
  97. case tsan:
  98. return "tsan"
  99. case intOverflow:
  100. return "intOverflow"
  101. case cfi:
  102. return "cfi"
  103. case scs:
  104. return "scs"
  105. case Memtag_heap:
  106. return "memtag_heap"
  107. case Fuzzer:
  108. return "fuzzer"
  109. default:
  110. panic(fmt.Errorf("unknown SanitizerType %d", t))
  111. }
  112. }
  113. // This is the sanitizer names in SANITIZE_[TARGET|HOST]
  114. func (t SanitizerType) name() string {
  115. switch t {
  116. case Asan:
  117. return "address"
  118. case Hwasan:
  119. return "hwaddress"
  120. case Memtag_heap:
  121. return "memtag_heap"
  122. case tsan:
  123. return "thread"
  124. case intOverflow:
  125. return "integer_overflow"
  126. case cfi:
  127. return "cfi"
  128. case scs:
  129. return "shadow-call-stack"
  130. case Fuzzer:
  131. return "fuzzer"
  132. default:
  133. panic(fmt.Errorf("unknown SanitizerType %d", t))
  134. }
  135. }
  136. func (t SanitizerType) registerMutators(ctx android.RegisterMutatorsContext) {
  137. switch t {
  138. case Asan, Hwasan, Fuzzer, scs, tsan, cfi:
  139. ctx.TopDown(t.variationName()+"_deps", sanitizerDepsMutator(t))
  140. ctx.BottomUp(t.variationName(), sanitizerMutator(t))
  141. case Memtag_heap, intOverflow:
  142. // do nothing
  143. default:
  144. panic(fmt.Errorf("unknown SanitizerType %d", t))
  145. }
  146. }
  147. func (*Module) SanitizerSupported(t SanitizerType) bool {
  148. switch t {
  149. case Asan:
  150. return true
  151. case Hwasan:
  152. return true
  153. case tsan:
  154. return true
  155. case intOverflow:
  156. return true
  157. case cfi:
  158. return true
  159. case scs:
  160. return true
  161. case Fuzzer:
  162. return true
  163. case Memtag_heap:
  164. return true
  165. default:
  166. return false
  167. }
  168. }
  169. // incompatibleWithCfi returns true if a sanitizer is incompatible with CFI.
  170. func (t SanitizerType) incompatibleWithCfi() bool {
  171. return t == Asan || t == Fuzzer || t == Hwasan
  172. }
  173. type SanitizeUserProps struct {
  174. // Prevent use of any sanitizers on this module
  175. Never *bool `android:"arch_variant"`
  176. // ASan (Address sanitizer), incompatible with static binaries.
  177. // Always runs in a diagnostic mode.
  178. // Use of address sanitizer disables cfi sanitizer.
  179. // Hwaddress sanitizer takes precedence over this sanitizer.
  180. Address *bool `android:"arch_variant"`
  181. // TSan (Thread sanitizer), incompatible with static binaries and 32 bit architectures.
  182. // Always runs in a diagnostic mode.
  183. // Use of thread sanitizer disables cfi and scudo sanitizers.
  184. // Hwaddress sanitizer takes precedence over this sanitizer.
  185. Thread *bool `android:"arch_variant"`
  186. // HWASan (Hardware Address sanitizer).
  187. // Use of hwasan sanitizer disables cfi, address, thread, and scudo sanitizers.
  188. Hwaddress *bool `android:"arch_variant"`
  189. // Undefined behavior sanitizer
  190. All_undefined *bool `android:"arch_variant"`
  191. // Subset of undefined behavior sanitizer
  192. Undefined *bool `android:"arch_variant"`
  193. // List of specific undefined behavior sanitizers to enable
  194. Misc_undefined []string `android:"arch_variant"`
  195. // Fuzzer, incompatible with static binaries.
  196. Fuzzer *bool `android:"arch_variant"`
  197. // safe-stack sanitizer, incompatible with 32-bit architectures.
  198. Safestack *bool `android:"arch_variant"`
  199. // cfi sanitizer, incompatible with asan, hwasan, fuzzer, or Darwin
  200. Cfi *bool `android:"arch_variant"`
  201. // signed/unsigned integer overflow sanitizer, incompatible with Darwin.
  202. Integer_overflow *bool `android:"arch_variant"`
  203. // scudo sanitizer, incompatible with asan, hwasan, tsan
  204. // This should not be used in Android 11+ : https://source.android.com/devices/tech/debug/scudo
  205. // deprecated
  206. Scudo *bool `android:"arch_variant"`
  207. // shadow-call-stack sanitizer, only available on arm64
  208. Scs *bool `android:"arch_variant"`
  209. // Memory-tagging, only available on arm64
  210. // if diag.memtag unset or false, enables async memory tagging
  211. Memtag_heap *bool `android:"arch_variant"`
  212. // A modifier for ASAN and HWASAN for write only instrumentation
  213. Writeonly *bool `android:"arch_variant"`
  214. // Sanitizers to run in the diagnostic mode (as opposed to the release mode).
  215. // Replaces abort() on error with a human-readable error message.
  216. // Address and Thread sanitizers always run in diagnostic mode.
  217. Diag struct {
  218. // Undefined behavior sanitizer, diagnostic mode
  219. Undefined *bool `android:"arch_variant"`
  220. // cfi sanitizer, diagnostic mode, incompatible with asan, hwasan, fuzzer, or Darwin
  221. Cfi *bool `android:"arch_variant"`
  222. // signed/unsigned integer overflow sanitizer, diagnostic mode, incompatible with Darwin.
  223. Integer_overflow *bool `android:"arch_variant"`
  224. // Memory-tagging, only available on arm64
  225. // requires sanitizer.memtag: true
  226. // if set, enables sync memory tagging
  227. Memtag_heap *bool `android:"arch_variant"`
  228. // List of specific undefined behavior sanitizers to enable in diagnostic mode
  229. Misc_undefined []string `android:"arch_variant"`
  230. // List of sanitizers to pass to -fno-sanitize-recover
  231. // results in only the first detected error for these sanitizers being reported and program then
  232. // exits with a non-zero exit code.
  233. No_recover []string `android:"arch_variant"`
  234. } `android:"arch_variant"`
  235. // Sanitizers to run with flag configuration specified
  236. Config struct {
  237. // Enables CFI support flags for assembly-heavy libraries
  238. Cfi_assembly_support *bool `android:"arch_variant"`
  239. } `android:"arch_variant"`
  240. // List of sanitizers to pass to -fsanitize-recover
  241. // allows execution to continue for these sanitizers to detect multiple errors rather than only
  242. // the first one
  243. Recover []string
  244. // value to pass to -fsanitize-ignorelist
  245. Blocklist *string
  246. }
  247. type SanitizeProperties struct {
  248. Sanitize SanitizeUserProps `android:"arch_variant"`
  249. SanitizerEnabled bool `blueprint:"mutated"`
  250. SanitizeDep bool `blueprint:"mutated"`
  251. MinimalRuntimeDep bool `blueprint:"mutated"`
  252. BuiltinsDep bool `blueprint:"mutated"`
  253. UbsanRuntimeDep bool `blueprint:"mutated"`
  254. InSanitizerDir bool `blueprint:"mutated"`
  255. Sanitizers []string `blueprint:"mutated"`
  256. DiagSanitizers []string `blueprint:"mutated"`
  257. }
  258. type sanitize struct {
  259. Properties SanitizeProperties
  260. }
  261. // Mark this tag with a check to see if apex dependency check should be skipped
  262. func (t libraryDependencyTag) SkipApexAllowedDependenciesCheck() bool {
  263. return t.skipApexAllowedDependenciesCheck
  264. }
  265. var _ android.SkipApexAllowedDependenciesCheck = (*libraryDependencyTag)(nil)
  266. func init() {
  267. android.RegisterMakeVarsProvider(pctx, cfiMakeVarsProvider)
  268. android.RegisterMakeVarsProvider(pctx, hwasanMakeVarsProvider)
  269. }
  270. func (sanitize *sanitize) props() []interface{} {
  271. return []interface{}{&sanitize.Properties}
  272. }
  273. func (sanitize *sanitize) begin(ctx BaseModuleContext) {
  274. s := &sanitize.Properties.Sanitize
  275. // Don't apply sanitizers to NDK code.
  276. if ctx.useSdk() {
  277. s.Never = BoolPtr(true)
  278. }
  279. // Never always wins.
  280. if Bool(s.Never) {
  281. return
  282. }
  283. // cc_test targets default to SYNC MemTag unless explicitly set to ASYNC (via diag: {memtag_heap}).
  284. if ctx.testBinary() {
  285. if s.Memtag_heap == nil {
  286. s.Memtag_heap = proptools.BoolPtr(true)
  287. }
  288. if s.Diag.Memtag_heap == nil {
  289. s.Diag.Memtag_heap = proptools.BoolPtr(true)
  290. }
  291. }
  292. var globalSanitizers []string
  293. var globalSanitizersDiag []string
  294. if ctx.Host() {
  295. if !ctx.Windows() {
  296. globalSanitizers = ctx.Config().SanitizeHost()
  297. }
  298. } else {
  299. arches := ctx.Config().SanitizeDeviceArch()
  300. if len(arches) == 0 || inList(ctx.Arch().ArchType.Name, arches) {
  301. globalSanitizers = ctx.Config().SanitizeDevice()
  302. globalSanitizersDiag = ctx.Config().SanitizeDeviceDiag()
  303. }
  304. }
  305. if len(globalSanitizers) > 0 {
  306. var found bool
  307. if found, globalSanitizers = removeFromList("undefined", globalSanitizers); found && s.All_undefined == nil {
  308. s.All_undefined = proptools.BoolPtr(true)
  309. }
  310. if found, globalSanitizers = removeFromList("default-ub", globalSanitizers); found && s.Undefined == nil {
  311. s.Undefined = proptools.BoolPtr(true)
  312. }
  313. if found, globalSanitizers = removeFromList("address", globalSanitizers); found && s.Address == nil {
  314. s.Address = proptools.BoolPtr(true)
  315. }
  316. if found, globalSanitizers = removeFromList("thread", globalSanitizers); found && s.Thread == nil {
  317. s.Thread = proptools.BoolPtr(true)
  318. }
  319. if found, globalSanitizers = removeFromList("fuzzer", globalSanitizers); found && s.Fuzzer == nil {
  320. s.Fuzzer = proptools.BoolPtr(true)
  321. }
  322. if found, globalSanitizers = removeFromList("safe-stack", globalSanitizers); found && s.Safestack == nil {
  323. s.Safestack = proptools.BoolPtr(true)
  324. }
  325. if found, globalSanitizers = removeFromList("cfi", globalSanitizers); found && s.Cfi == nil {
  326. if !ctx.Config().CFIDisabledForPath(ctx.ModuleDir()) {
  327. s.Cfi = proptools.BoolPtr(true)
  328. }
  329. }
  330. // Global integer_overflow builds do not support static libraries.
  331. if found, globalSanitizers = removeFromList("integer_overflow", globalSanitizers); found && s.Integer_overflow == nil {
  332. if !ctx.Config().IntegerOverflowDisabledForPath(ctx.ModuleDir()) && !ctx.static() {
  333. s.Integer_overflow = proptools.BoolPtr(true)
  334. }
  335. }
  336. if found, globalSanitizers = removeFromList("scudo", globalSanitizers); found && s.Scudo == nil {
  337. s.Scudo = proptools.BoolPtr(true)
  338. }
  339. if found, globalSanitizers = removeFromList("hwaddress", globalSanitizers); found && s.Hwaddress == nil {
  340. s.Hwaddress = proptools.BoolPtr(true)
  341. }
  342. if found, globalSanitizers = removeFromList("writeonly", globalSanitizers); found && s.Writeonly == nil {
  343. // Hwaddress and Address are set before, so we can check them here
  344. // If they aren't explicitly set in the blueprint/SANITIZE_(HOST|TARGET), they would be nil instead of false
  345. if s.Address == nil && s.Hwaddress == nil {
  346. ctx.ModuleErrorf("writeonly modifier cannot be used without 'address' or 'hwaddress'")
  347. }
  348. s.Writeonly = proptools.BoolPtr(true)
  349. }
  350. if found, globalSanitizers = removeFromList("memtag_heap", globalSanitizers); found && s.Memtag_heap == nil {
  351. if !ctx.Config().MemtagHeapDisabledForPath(ctx.ModuleDir()) {
  352. s.Memtag_heap = proptools.BoolPtr(true)
  353. }
  354. }
  355. if len(globalSanitizers) > 0 {
  356. ctx.ModuleErrorf("unknown global sanitizer option %s", globalSanitizers[0])
  357. }
  358. // Global integer_overflow builds do not support static library diagnostics.
  359. if found, globalSanitizersDiag = removeFromList("integer_overflow", globalSanitizersDiag); found &&
  360. s.Diag.Integer_overflow == nil && Bool(s.Integer_overflow) && !ctx.static() {
  361. s.Diag.Integer_overflow = proptools.BoolPtr(true)
  362. }
  363. if found, globalSanitizersDiag = removeFromList("cfi", globalSanitizersDiag); found &&
  364. s.Diag.Cfi == nil && Bool(s.Cfi) {
  365. s.Diag.Cfi = proptools.BoolPtr(true)
  366. }
  367. if found, globalSanitizersDiag = removeFromList("memtag_heap", globalSanitizersDiag); found &&
  368. s.Diag.Memtag_heap == nil && Bool(s.Memtag_heap) {
  369. s.Diag.Memtag_heap = proptools.BoolPtr(true)
  370. }
  371. if len(globalSanitizersDiag) > 0 {
  372. ctx.ModuleErrorf("unknown global sanitizer diagnostics option %s", globalSanitizersDiag[0])
  373. }
  374. }
  375. // Enable Memtag for all components in the include paths (for Aarch64 only)
  376. if ctx.Arch().ArchType == android.Arm64 {
  377. if ctx.Config().MemtagHeapSyncEnabledForPath(ctx.ModuleDir()) {
  378. if s.Memtag_heap == nil {
  379. s.Memtag_heap = proptools.BoolPtr(true)
  380. }
  381. if s.Diag.Memtag_heap == nil {
  382. s.Diag.Memtag_heap = proptools.BoolPtr(true)
  383. }
  384. } else if ctx.Config().MemtagHeapAsyncEnabledForPath(ctx.ModuleDir()) {
  385. if s.Memtag_heap == nil {
  386. s.Memtag_heap = proptools.BoolPtr(true)
  387. }
  388. }
  389. }
  390. // Enable CFI for non-host components in the include paths
  391. if s.Cfi == nil && ctx.Config().CFIEnabledForPath(ctx.ModuleDir()) && !ctx.Host() {
  392. s.Cfi = proptools.BoolPtr(true)
  393. if inList("cfi", ctx.Config().SanitizeDeviceDiag()) {
  394. s.Diag.Cfi = proptools.BoolPtr(true)
  395. }
  396. }
  397. // Is CFI actually enabled?
  398. if !ctx.Config().EnableCFI() {
  399. s.Cfi = nil
  400. s.Diag.Cfi = nil
  401. }
  402. // HWASan requires AArch64 hardware feature (top-byte-ignore).
  403. if ctx.Arch().ArchType != android.Arm64 {
  404. s.Hwaddress = nil
  405. }
  406. // SCS is only implemented on AArch64.
  407. if ctx.Arch().ArchType != android.Arm64 {
  408. s.Scs = nil
  409. }
  410. // Memtag_heap is only implemented on AArch64.
  411. if ctx.Arch().ArchType != android.Arm64 {
  412. s.Memtag_heap = nil
  413. }
  414. // Also disable CFI if ASAN is enabled.
  415. if Bool(s.Address) || Bool(s.Hwaddress) {
  416. s.Cfi = nil
  417. s.Diag.Cfi = nil
  418. }
  419. // Disable sanitizers that depend on the UBSan runtime for windows/darwin/musl builds.
  420. if !ctx.Os().Linux() || ctx.Os() == android.LinuxMusl {
  421. s.Cfi = nil
  422. s.Diag.Cfi = nil
  423. s.Misc_undefined = nil
  424. s.Undefined = nil
  425. s.All_undefined = nil
  426. s.Integer_overflow = nil
  427. }
  428. // Also disable CFI for VNDK variants of components
  429. if ctx.isVndk() && ctx.useVndk() {
  430. if ctx.static() {
  431. // Cfi variant for static vndk should be captured as vendor snapshot,
  432. // so don't strictly disable Cfi.
  433. s.Cfi = nil
  434. s.Diag.Cfi = nil
  435. } else {
  436. s.Cfi = nil
  437. s.Diag.Cfi = nil
  438. }
  439. }
  440. // HWASan ramdisk (which is built from recovery) goes over some bootloader limit.
  441. // Keep libc instrumented so that ramdisk / vendor_ramdisk / recovery can run hwasan-instrumented code if necessary.
  442. if (ctx.inRamdisk() || ctx.inVendorRamdisk() || ctx.inRecovery()) && !strings.HasPrefix(ctx.ModuleDir(), "bionic/libc") {
  443. s.Hwaddress = nil
  444. }
  445. if ctx.staticBinary() {
  446. s.Address = nil
  447. s.Fuzzer = nil
  448. s.Thread = nil
  449. }
  450. if Bool(s.All_undefined) {
  451. s.Undefined = nil
  452. }
  453. if !ctx.toolchain().Is64Bit() {
  454. // TSAN and SafeStack are not supported on 32-bit architectures
  455. s.Thread = nil
  456. s.Safestack = nil
  457. // TODO(ccross): error for compile_multilib = "32"?
  458. }
  459. if ctx.Os() != android.Windows && (Bool(s.All_undefined) || Bool(s.Undefined) || Bool(s.Address) || Bool(s.Thread) ||
  460. Bool(s.Fuzzer) || Bool(s.Safestack) || Bool(s.Cfi) || Bool(s.Integer_overflow) || len(s.Misc_undefined) > 0 ||
  461. Bool(s.Scudo) || Bool(s.Hwaddress) || Bool(s.Scs) || Bool(s.Memtag_heap)) {
  462. sanitize.Properties.SanitizerEnabled = true
  463. }
  464. // Disable Scudo if ASan or TSan is enabled, or if it's disabled globally.
  465. if Bool(s.Address) || Bool(s.Thread) || Bool(s.Hwaddress) || ctx.Config().DisableScudo() {
  466. s.Scudo = nil
  467. }
  468. if Bool(s.Hwaddress) {
  469. s.Address = nil
  470. s.Thread = nil
  471. }
  472. // TODO(b/131771163): CFI transiently depends on LTO, and thus Fuzzer is
  473. // mutually incompatible.
  474. if Bool(s.Fuzzer) {
  475. s.Cfi = nil
  476. }
  477. }
  478. func toDisableImplicitIntegerChange(flags []string) bool {
  479. // Returns true if any flag is fsanitize*integer, and there is
  480. // no explicit flag about sanitize=implicit-integer-sign-change.
  481. for _, f := range flags {
  482. if strings.Contains(f, "sanitize=implicit-integer-sign-change") {
  483. return false
  484. }
  485. }
  486. for _, f := range flags {
  487. if strings.HasPrefix(f, "-fsanitize") && strings.Contains(f, "integer") {
  488. return true
  489. }
  490. }
  491. return false
  492. }
  493. func toDisableUnsignedShiftBaseChange(flags []string) bool {
  494. // Returns true if any flag is fsanitize*integer, and there is
  495. // no explicit flag about sanitize=unsigned-shift-base.
  496. for _, f := range flags {
  497. if strings.Contains(f, "sanitize=unsigned-shift-base") {
  498. return false
  499. }
  500. }
  501. for _, f := range flags {
  502. if strings.HasPrefix(f, "-fsanitize") && strings.Contains(f, "integer") {
  503. return true
  504. }
  505. }
  506. return false
  507. }
  508. func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags) Flags {
  509. minimalRuntimeLib := config.UndefinedBehaviorSanitizerMinimalRuntimeLibrary(ctx.toolchain()) + ".a"
  510. if sanitize.Properties.MinimalRuntimeDep {
  511. flags.Local.LdFlags = append(flags.Local.LdFlags,
  512. "-Wl,--exclude-libs,"+minimalRuntimeLib)
  513. }
  514. if !sanitize.Properties.SanitizerEnabled && !sanitize.Properties.UbsanRuntimeDep {
  515. return flags
  516. }
  517. if Bool(sanitize.Properties.Sanitize.Address) {
  518. if ctx.Arch().ArchType == android.Arm {
  519. // Frame pointer based unwinder in ASan requires ARM frame setup.
  520. // TODO: put in flags?
  521. flags.RequiredInstructionSet = "arm"
  522. }
  523. flags.Local.CFlags = append(flags.Local.CFlags, asanCflags...)
  524. flags.Local.LdFlags = append(flags.Local.LdFlags, asanLdflags...)
  525. if Bool(sanitize.Properties.Sanitize.Writeonly) {
  526. flags.Local.CFlags = append(flags.Local.CFlags, "-mllvm", "-asan-instrument-reads=0")
  527. }
  528. if ctx.Host() {
  529. // -nodefaultlibs (provided with libc++) prevents the driver from linking
  530. // libraries needed with -fsanitize=address. http://b/18650275 (WAI)
  531. flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--no-as-needed")
  532. } else {
  533. flags.Local.CFlags = append(flags.Local.CFlags, "-mllvm", "-asan-globals=0")
  534. if ctx.bootstrap() {
  535. flags.DynamicLinker = "/system/bin/bootstrap/linker_asan"
  536. } else {
  537. flags.DynamicLinker = "/system/bin/linker_asan"
  538. }
  539. if flags.Toolchain.Is64Bit() {
  540. flags.DynamicLinker += "64"
  541. }
  542. }
  543. }
  544. if Bool(sanitize.Properties.Sanitize.Hwaddress) {
  545. flags.Local.CFlags = append(flags.Local.CFlags, hwasanCflags...)
  546. for _, flag := range hwasanCommonflags {
  547. flags.Local.CFlags = append(flags.Local.CFlags, "-mllvm", flag)
  548. }
  549. for _, flag := range hwasanCommonflags {
  550. flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-mllvm,"+flag)
  551. }
  552. if Bool(sanitize.Properties.Sanitize.Writeonly) {
  553. flags.Local.CFlags = append(flags.Local.CFlags, "-mllvm", "-hwasan-instrument-reads=0")
  554. }
  555. }
  556. if Bool(sanitize.Properties.Sanitize.Fuzzer) {
  557. flags.Local.CFlags = append(flags.Local.CFlags, "-fsanitize=fuzzer-no-link")
  558. // TODO(b/131771163): LTO and Fuzzer support is mutually incompatible.
  559. _, flags.Local.LdFlags = removeFromList("-flto", flags.Local.LdFlags)
  560. _, flags.Local.CFlags = removeFromList("-flto", flags.Local.CFlags)
  561. flags.Local.LdFlags = append(flags.Local.LdFlags, "-fno-lto")
  562. flags.Local.CFlags = append(flags.Local.CFlags, "-fno-lto")
  563. // TODO(b/142430592): Upstream linker scripts for sanitizer runtime libraries
  564. // discard the sancov_lowest_stack symbol, because it's emulated TLS (and thus
  565. // doesn't match the linker script due to the "__emutls_v." prefix).
  566. flags.Local.LdFlags = append(flags.Local.LdFlags, "-fno-sanitize-coverage=stack-depth")
  567. flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize-coverage=stack-depth")
  568. // Disable fortify for fuzzing builds. Generally, we'll be building with
  569. // UBSan or ASan here and the fortify checks pollute the stack traces.
  570. flags.Local.CFlags = append(flags.Local.CFlags, "-U_FORTIFY_SOURCE")
  571. // Build fuzzer-sanitized libraries with an $ORIGIN DT_RUNPATH. Android's
  572. // linker uses DT_RUNPATH, not DT_RPATH. When we deploy cc_fuzz targets and
  573. // their libraries to /data/fuzz/<arch>/lib, any transient shared library gets
  574. // the DT_RUNPATH from the shared library above it, and not the executable,
  575. // meaning that the lookup falls back to the system. Adding the $ORIGIN to the
  576. // DT_RUNPATH here means that transient shared libraries can be found
  577. // colocated with their parents.
  578. flags.Local.LdFlags = append(flags.Local.LdFlags, `-Wl,-rpath,\$$ORIGIN`)
  579. }
  580. if Bool(sanitize.Properties.Sanitize.Cfi) {
  581. if ctx.Arch().ArchType == android.Arm {
  582. // __cfi_check needs to be built as Thumb (see the code in linker_cfi.cpp). LLVM is not set up
  583. // to do this on a function basis, so force Thumb on the entire module.
  584. flags.RequiredInstructionSet = "thumb"
  585. }
  586. flags.Local.CFlags = append(flags.Local.CFlags, cfiCflags...)
  587. flags.Local.AsFlags = append(flags.Local.AsFlags, cfiAsflags...)
  588. if Bool(sanitize.Properties.Sanitize.Config.Cfi_assembly_support) {
  589. flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize-cfi-canonical-jump-tables")
  590. }
  591. // Only append the default visibility flag if -fvisibility has not already been set
  592. // to hidden.
  593. if !inList("-fvisibility=hidden", flags.Local.CFlags) {
  594. flags.Local.CFlags = append(flags.Local.CFlags, "-fvisibility=default")
  595. }
  596. flags.Local.LdFlags = append(flags.Local.LdFlags, cfiLdflags...)
  597. if ctx.staticBinary() {
  598. _, flags.Local.CFlags = removeFromList("-fsanitize-cfi-cross-dso", flags.Local.CFlags)
  599. _, flags.Local.LdFlags = removeFromList("-fsanitize-cfi-cross-dso", flags.Local.LdFlags)
  600. }
  601. }
  602. if Bool(sanitize.Properties.Sanitize.Integer_overflow) {
  603. flags.Local.CFlags = append(flags.Local.CFlags, intOverflowCflags...)
  604. }
  605. if len(sanitize.Properties.Sanitizers) > 0 {
  606. sanitizeArg := "-fsanitize=" + strings.Join(sanitize.Properties.Sanitizers, ",")
  607. flags.Local.CFlags = append(flags.Local.CFlags, sanitizeArg)
  608. flags.Local.AsFlags = append(flags.Local.AsFlags, sanitizeArg)
  609. flags.Local.LdFlags = append(flags.Local.LdFlags, sanitizeArg)
  610. if ctx.toolchain().Bionic() {
  611. // Bionic sanitizer runtimes have already been added as dependencies so that
  612. // the right variant of the runtime will be used (with the "-android"
  613. // suffix), so don't let clang the runtime library.
  614. flags.Local.LdFlags = append(flags.Local.LdFlags, "-fno-sanitize-link-runtime")
  615. } else {
  616. // Host sanitizers only link symbols in the final executable, so
  617. // there will always be undefined symbols in intermediate libraries.
  618. _, flags.Global.LdFlags = removeFromList("-Wl,--no-undefined", flags.Global.LdFlags)
  619. // non-Bionic toolchain prebuilts are missing UBSan's vptr and function san
  620. flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize=vptr,function")
  621. }
  622. if enableMinimalRuntime(sanitize) {
  623. flags.Local.CFlags = append(flags.Local.CFlags, strings.Join(minimalRuntimeFlags, " "))
  624. flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--exclude-libs,"+minimalRuntimeLib)
  625. }
  626. if Bool(sanitize.Properties.Sanitize.Fuzzer) {
  627. // When fuzzing, we wish to crash with diagnostics on any bug.
  628. flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize-trap=all", "-fno-sanitize-recover=all")
  629. } else if ctx.Host() {
  630. flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize-recover=all")
  631. } else {
  632. flags.Local.CFlags = append(flags.Local.CFlags, "-fsanitize-trap=all", "-ftrap-function=abort")
  633. }
  634. // http://b/119329758, Android core does not boot up with this sanitizer yet.
  635. if toDisableImplicitIntegerChange(flags.Local.CFlags) {
  636. flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize=implicit-integer-sign-change")
  637. }
  638. // http://b/171275751, Android doesn't build with this sanitizer yet.
  639. if toDisableUnsignedShiftBaseChange(flags.Local.CFlags) {
  640. flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize=unsigned-shift-base")
  641. }
  642. }
  643. if len(sanitize.Properties.DiagSanitizers) > 0 {
  644. flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize-trap="+strings.Join(sanitize.Properties.DiagSanitizers, ","))
  645. }
  646. // FIXME: enable RTTI if diag + (cfi or vptr)
  647. if sanitize.Properties.Sanitize.Recover != nil {
  648. flags.Local.CFlags = append(flags.Local.CFlags, "-fsanitize-recover="+
  649. strings.Join(sanitize.Properties.Sanitize.Recover, ","))
  650. }
  651. if sanitize.Properties.Sanitize.Diag.No_recover != nil {
  652. flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize-recover="+
  653. strings.Join(sanitize.Properties.Sanitize.Diag.No_recover, ","))
  654. }
  655. blocklist := android.OptionalPathForModuleSrc(ctx, sanitize.Properties.Sanitize.Blocklist)
  656. if blocklist.Valid() {
  657. flags.Local.CFlags = append(flags.Local.CFlags, "-fsanitize-ignorelist="+blocklist.String())
  658. flags.CFlagsDeps = append(flags.CFlagsDeps, blocklist.Path())
  659. }
  660. return flags
  661. }
  662. func (sanitize *sanitize) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
  663. // Add a suffix for cfi/hwasan/scs-enabled static/header libraries to allow surfacing
  664. // both the sanitized and non-sanitized variants to make without a name conflict.
  665. if entries.Class == "STATIC_LIBRARIES" || entries.Class == "HEADER_LIBRARIES" {
  666. if Bool(sanitize.Properties.Sanitize.Cfi) {
  667. entries.SubName += ".cfi"
  668. }
  669. if Bool(sanitize.Properties.Sanitize.Hwaddress) {
  670. entries.SubName += ".hwasan"
  671. }
  672. if Bool(sanitize.Properties.Sanitize.Scs) {
  673. entries.SubName += ".scs"
  674. }
  675. }
  676. }
  677. func (sanitize *sanitize) inSanitizerDir() bool {
  678. return sanitize.Properties.InSanitizerDir
  679. }
  680. // getSanitizerBoolPtr returns the SanitizerTypes associated bool pointer from SanitizeProperties.
  681. func (sanitize *sanitize) getSanitizerBoolPtr(t SanitizerType) *bool {
  682. switch t {
  683. case Asan:
  684. return sanitize.Properties.Sanitize.Address
  685. case Hwasan:
  686. return sanitize.Properties.Sanitize.Hwaddress
  687. case tsan:
  688. return sanitize.Properties.Sanitize.Thread
  689. case intOverflow:
  690. return sanitize.Properties.Sanitize.Integer_overflow
  691. case cfi:
  692. return sanitize.Properties.Sanitize.Cfi
  693. case scs:
  694. return sanitize.Properties.Sanitize.Scs
  695. case Memtag_heap:
  696. return sanitize.Properties.Sanitize.Memtag_heap
  697. case Fuzzer:
  698. return sanitize.Properties.Sanitize.Fuzzer
  699. default:
  700. panic(fmt.Errorf("unknown SanitizerType %d", t))
  701. }
  702. }
  703. // isUnsanitizedVariant returns true if no sanitizers are enabled.
  704. func (sanitize *sanitize) isUnsanitizedVariant() bool {
  705. return !sanitize.isSanitizerEnabled(Asan) &&
  706. !sanitize.isSanitizerEnabled(Hwasan) &&
  707. !sanitize.isSanitizerEnabled(tsan) &&
  708. !sanitize.isSanitizerEnabled(cfi) &&
  709. !sanitize.isSanitizerEnabled(scs) &&
  710. !sanitize.isSanitizerEnabled(Memtag_heap) &&
  711. !sanitize.isSanitizerEnabled(Fuzzer)
  712. }
  713. // isVariantOnProductionDevice returns true if variant is for production devices (no non-production sanitizers enabled).
  714. func (sanitize *sanitize) isVariantOnProductionDevice() bool {
  715. return !sanitize.isSanitizerEnabled(Asan) &&
  716. !sanitize.isSanitizerEnabled(Hwasan) &&
  717. !sanitize.isSanitizerEnabled(tsan) &&
  718. !sanitize.isSanitizerEnabled(Fuzzer)
  719. }
  720. func (sanitize *sanitize) SetSanitizer(t SanitizerType, b bool) {
  721. bPtr := proptools.BoolPtr(b)
  722. if !b {
  723. bPtr = nil
  724. }
  725. switch t {
  726. case Asan:
  727. sanitize.Properties.Sanitize.Address = bPtr
  728. case Hwasan:
  729. sanitize.Properties.Sanitize.Hwaddress = bPtr
  730. case tsan:
  731. sanitize.Properties.Sanitize.Thread = bPtr
  732. case intOverflow:
  733. sanitize.Properties.Sanitize.Integer_overflow = bPtr
  734. case cfi:
  735. sanitize.Properties.Sanitize.Cfi = bPtr
  736. case scs:
  737. sanitize.Properties.Sanitize.Scs = bPtr
  738. case Memtag_heap:
  739. sanitize.Properties.Sanitize.Memtag_heap = bPtr
  740. case Fuzzer:
  741. sanitize.Properties.Sanitize.Fuzzer = bPtr
  742. default:
  743. panic(fmt.Errorf("unknown SanitizerType %d", t))
  744. }
  745. if b {
  746. sanitize.Properties.SanitizerEnabled = true
  747. }
  748. }
  749. // Check if the sanitizer is explicitly disabled (as opposed to nil by
  750. // virtue of not being set).
  751. func (sanitize *sanitize) isSanitizerExplicitlyDisabled(t SanitizerType) bool {
  752. if sanitize == nil {
  753. return false
  754. }
  755. sanitizerVal := sanitize.getSanitizerBoolPtr(t)
  756. return sanitizerVal != nil && *sanitizerVal == false
  757. }
  758. // There isn't an analog of the method above (ie:isSanitizerExplicitlyEnabled)
  759. // because enabling a sanitizer either directly (via the blueprint) or
  760. // indirectly (via a mutator) sets the bool ptr to true, and you can't
  761. // distinguish between the cases. It isn't needed though - both cases can be
  762. // treated identically.
  763. func (sanitize *sanitize) isSanitizerEnabled(t SanitizerType) bool {
  764. if sanitize == nil {
  765. return false
  766. }
  767. sanitizerVal := sanitize.getSanitizerBoolPtr(t)
  768. return sanitizerVal != nil && *sanitizerVal == true
  769. }
  770. // IsSanitizableDependencyTag returns true if the dependency tag is sanitizable.
  771. func IsSanitizableDependencyTag(tag blueprint.DependencyTag) bool {
  772. switch t := tag.(type) {
  773. case dependencyTag:
  774. return t == reuseObjTag || t == objDepTag
  775. case libraryDependencyTag:
  776. return true
  777. default:
  778. return false
  779. }
  780. }
  781. func (m *Module) SanitizableDepTagChecker() SantizableDependencyTagChecker {
  782. return IsSanitizableDependencyTag
  783. }
  784. // Determines if the current module is a static library going to be captured
  785. // as vendor snapshot. Such modules must create both cfi and non-cfi variants,
  786. // except for ones which explicitly disable cfi.
  787. func needsCfiForVendorSnapshot(mctx android.TopDownMutatorContext) bool {
  788. if snapshot.IsVendorProprietaryModule(mctx) {
  789. return false
  790. }
  791. c := mctx.Module().(PlatformSanitizeable)
  792. if !c.InVendor() {
  793. return false
  794. }
  795. if !c.StaticallyLinked() {
  796. return false
  797. }
  798. if c.IsPrebuilt() {
  799. return false
  800. }
  801. if !c.SanitizerSupported(cfi) {
  802. return false
  803. }
  804. return c.SanitizePropDefined() &&
  805. !c.SanitizeNever() &&
  806. !c.IsSanitizerExplicitlyDisabled(cfi)
  807. }
  808. // Propagate sanitizer requirements down from binaries
  809. func sanitizerDepsMutator(t SanitizerType) func(android.TopDownMutatorContext) {
  810. return func(mctx android.TopDownMutatorContext) {
  811. if c, ok := mctx.Module().(PlatformSanitizeable); ok {
  812. enabled := c.IsSanitizerEnabled(t)
  813. if t == cfi && needsCfiForVendorSnapshot(mctx) {
  814. // We shouldn't change the result of isSanitizerEnabled(cfi) to correctly
  815. // determine defaultVariation in sanitizerMutator below.
  816. // Instead, just mark SanitizeDep to forcefully create cfi variant.
  817. enabled = true
  818. c.SetSanitizeDep(true)
  819. }
  820. if enabled {
  821. isSanitizableDependencyTag := c.SanitizableDepTagChecker()
  822. mctx.WalkDeps(func(child, parent android.Module) bool {
  823. if !isSanitizableDependencyTag(mctx.OtherModuleDependencyTag(child)) {
  824. return false
  825. }
  826. if d, ok := child.(PlatformSanitizeable); ok && d.SanitizePropDefined() &&
  827. !d.SanitizeNever() &&
  828. !d.IsSanitizerExplicitlyDisabled(t) {
  829. if t == cfi || t == Hwasan || t == scs || t == Asan {
  830. if d.StaticallyLinked() && d.SanitizerSupported(t) {
  831. // Rust does not support some of these sanitizers, so we need to check if it's
  832. // supported before setting this true.
  833. d.SetSanitizeDep(true)
  834. }
  835. } else {
  836. d.SetSanitizeDep(true)
  837. }
  838. }
  839. return true
  840. })
  841. }
  842. } else if sanitizeable, ok := mctx.Module().(Sanitizeable); ok {
  843. // If an APEX module includes a lib which is enabled for a sanitizer T, then
  844. // the APEX module is also enabled for the same sanitizer type.
  845. mctx.VisitDirectDeps(func(child android.Module) {
  846. if c, ok := child.(*Module); ok && c.sanitize.isSanitizerEnabled(t) {
  847. sanitizeable.EnableSanitizer(t.name())
  848. }
  849. })
  850. }
  851. }
  852. }
  853. func (c *Module) SanitizeNever() bool {
  854. return Bool(c.sanitize.Properties.Sanitize.Never)
  855. }
  856. func (c *Module) IsSanitizerExplicitlyDisabled(t SanitizerType) bool {
  857. return c.sanitize.isSanitizerExplicitlyDisabled(t)
  858. }
  859. // Propagate the ubsan minimal runtime dependency when there are integer overflow sanitized static dependencies.
  860. func sanitizerRuntimeDepsMutator(mctx android.TopDownMutatorContext) {
  861. // Change this to PlatformSanitizable when/if non-cc modules support ubsan sanitizers.
  862. if c, ok := mctx.Module().(*Module); ok && c.sanitize != nil {
  863. isSanitizableDependencyTag := c.SanitizableDepTagChecker()
  864. mctx.WalkDeps(func(child, parent android.Module) bool {
  865. if !isSanitizableDependencyTag(mctx.OtherModuleDependencyTag(child)) {
  866. return false
  867. }
  868. d, ok := child.(*Module)
  869. if !ok || !d.static() {
  870. return false
  871. }
  872. if d.sanitize != nil {
  873. if enableMinimalRuntime(d.sanitize) {
  874. // If a static dependency is built with the minimal runtime,
  875. // make sure we include the ubsan minimal runtime.
  876. c.sanitize.Properties.MinimalRuntimeDep = true
  877. } else if enableUbsanRuntime(d.sanitize) {
  878. // If a static dependency runs with full ubsan diagnostics,
  879. // make sure we include the ubsan runtime.
  880. c.sanitize.Properties.UbsanRuntimeDep = true
  881. }
  882. if c.sanitize.Properties.MinimalRuntimeDep &&
  883. c.sanitize.Properties.UbsanRuntimeDep {
  884. // both flags that this mutator might set are true, so don't bother recursing
  885. return false
  886. }
  887. if c.Os() == android.Linux {
  888. c.sanitize.Properties.BuiltinsDep = true
  889. }
  890. return true
  891. }
  892. if p, ok := d.linker.(*snapshotLibraryDecorator); ok {
  893. if Bool(p.properties.Sanitize_minimal_dep) {
  894. c.sanitize.Properties.MinimalRuntimeDep = true
  895. }
  896. if Bool(p.properties.Sanitize_ubsan_dep) {
  897. c.sanitize.Properties.UbsanRuntimeDep = true
  898. }
  899. }
  900. return false
  901. })
  902. }
  903. }
  904. // Add the dependency to the runtime library for each of the sanitizer variants
  905. func sanitizerRuntimeMutator(mctx android.BottomUpMutatorContext) {
  906. if c, ok := mctx.Module().(*Module); ok && c.sanitize != nil {
  907. if !c.Enabled() {
  908. return
  909. }
  910. var sanitizers []string
  911. var diagSanitizers []string
  912. if Bool(c.sanitize.Properties.Sanitize.All_undefined) {
  913. sanitizers = append(sanitizers, "undefined")
  914. } else {
  915. if Bool(c.sanitize.Properties.Sanitize.Undefined) {
  916. sanitizers = append(sanitizers,
  917. "bool",
  918. "integer-divide-by-zero",
  919. "return",
  920. "returns-nonnull-attribute",
  921. "shift-exponent",
  922. "unreachable",
  923. "vla-bound",
  924. // TODO(danalbert): The following checks currently have compiler performance issues.
  925. //"alignment",
  926. //"bounds",
  927. //"enum",
  928. //"float-cast-overflow",
  929. //"float-divide-by-zero",
  930. //"nonnull-attribute",
  931. //"null",
  932. //"shift-base",
  933. //"signed-integer-overflow",
  934. // TODO(danalbert): Fix UB in libc++'s __tree so we can turn this on.
  935. // https://llvm.org/PR19302
  936. // http://reviews.llvm.org/D6974
  937. // "object-size",
  938. )
  939. }
  940. sanitizers = append(sanitizers, c.sanitize.Properties.Sanitize.Misc_undefined...)
  941. }
  942. if Bool(c.sanitize.Properties.Sanitize.Diag.Undefined) {
  943. diagSanitizers = append(diagSanitizers, "undefined")
  944. }
  945. diagSanitizers = append(diagSanitizers, c.sanitize.Properties.Sanitize.Diag.Misc_undefined...)
  946. if Bool(c.sanitize.Properties.Sanitize.Address) {
  947. sanitizers = append(sanitizers, "address")
  948. diagSanitizers = append(diagSanitizers, "address")
  949. }
  950. if Bool(c.sanitize.Properties.Sanitize.Hwaddress) {
  951. sanitizers = append(sanitizers, "hwaddress")
  952. }
  953. if Bool(c.sanitize.Properties.Sanitize.Thread) {
  954. sanitizers = append(sanitizers, "thread")
  955. }
  956. if Bool(c.sanitize.Properties.Sanitize.Safestack) {
  957. sanitizers = append(sanitizers, "safe-stack")
  958. }
  959. if Bool(c.sanitize.Properties.Sanitize.Cfi) {
  960. sanitizers = append(sanitizers, "cfi")
  961. if Bool(c.sanitize.Properties.Sanitize.Diag.Cfi) {
  962. diagSanitizers = append(diagSanitizers, "cfi")
  963. }
  964. }
  965. if Bool(c.sanitize.Properties.Sanitize.Integer_overflow) {
  966. sanitizers = append(sanitizers, "unsigned-integer-overflow")
  967. sanitizers = append(sanitizers, "signed-integer-overflow")
  968. if Bool(c.sanitize.Properties.Sanitize.Diag.Integer_overflow) {
  969. diagSanitizers = append(diagSanitizers, "unsigned-integer-overflow")
  970. diagSanitizers = append(diagSanitizers, "signed-integer-overflow")
  971. }
  972. }
  973. if Bool(c.sanitize.Properties.Sanitize.Scudo) {
  974. sanitizers = append(sanitizers, "scudo")
  975. }
  976. if Bool(c.sanitize.Properties.Sanitize.Scs) {
  977. sanitizers = append(sanitizers, "shadow-call-stack")
  978. }
  979. if Bool(c.sanitize.Properties.Sanitize.Memtag_heap) && c.Binary() {
  980. noteDep := "note_memtag_heap_async"
  981. if Bool(c.sanitize.Properties.Sanitize.Diag.Memtag_heap) {
  982. noteDep = "note_memtag_heap_sync"
  983. }
  984. // If we're using snapshots, redirect to snapshot whenever possible
  985. // TODO(b/178470649): clean manual snapshot redirections
  986. snapshot := mctx.Provider(SnapshotInfoProvider).(SnapshotInfo)
  987. if lib, ok := snapshot.StaticLibs[noteDep]; ok {
  988. noteDep = lib
  989. }
  990. depTag := StaticDepTag(true)
  991. variations := append(mctx.Target().Variations(),
  992. blueprint.Variation{Mutator: "link", Variation: "static"})
  993. if c.Device() {
  994. variations = append(variations, c.ImageVariation())
  995. }
  996. mctx.AddFarVariationDependencies(variations, depTag, noteDep)
  997. }
  998. if Bool(c.sanitize.Properties.Sanitize.Fuzzer) {
  999. sanitizers = append(sanitizers, "fuzzer-no-link")
  1000. }
  1001. // Save the list of sanitizers. These will be used again when generating
  1002. // the build rules (for Cflags, etc.)
  1003. c.sanitize.Properties.Sanitizers = sanitizers
  1004. c.sanitize.Properties.DiagSanitizers = diagSanitizers
  1005. // TODO(b/150822854) Hosts have a different default behavior and assume the runtime library is used.
  1006. if c.Host() {
  1007. diagSanitizers = sanitizers
  1008. }
  1009. // Determine the runtime library required
  1010. runtimeLibrary := ""
  1011. var extraStaticDeps []string
  1012. toolchain := c.toolchain(mctx)
  1013. if Bool(c.sanitize.Properties.Sanitize.Address) {
  1014. runtimeLibrary = config.AddressSanitizerRuntimeLibrary(toolchain)
  1015. } else if Bool(c.sanitize.Properties.Sanitize.Hwaddress) {
  1016. if c.staticBinary() {
  1017. runtimeLibrary = config.HWAddressSanitizerStaticLibrary(toolchain)
  1018. extraStaticDeps = []string{"libdl"}
  1019. } else {
  1020. runtimeLibrary = config.HWAddressSanitizerRuntimeLibrary(toolchain)
  1021. }
  1022. } else if Bool(c.sanitize.Properties.Sanitize.Thread) {
  1023. runtimeLibrary = config.ThreadSanitizerRuntimeLibrary(toolchain)
  1024. } else if Bool(c.sanitize.Properties.Sanitize.Scudo) {
  1025. if len(diagSanitizers) == 0 && !c.sanitize.Properties.UbsanRuntimeDep {
  1026. runtimeLibrary = config.ScudoMinimalRuntimeLibrary(toolchain)
  1027. } else {
  1028. runtimeLibrary = config.ScudoRuntimeLibrary(toolchain)
  1029. }
  1030. } else if len(diagSanitizers) > 0 || c.sanitize.Properties.UbsanRuntimeDep ||
  1031. Bool(c.sanitize.Properties.Sanitize.Fuzzer) ||
  1032. Bool(c.sanitize.Properties.Sanitize.Undefined) ||
  1033. Bool(c.sanitize.Properties.Sanitize.All_undefined) {
  1034. runtimeLibrary = config.UndefinedBehaviorSanitizerRuntimeLibrary(toolchain)
  1035. if c.staticBinary() {
  1036. runtimeLibrary += ".static"
  1037. }
  1038. }
  1039. addStaticDeps := func(deps ...string) {
  1040. // If we're using snapshots, redirect to snapshot whenever possible
  1041. snapshot := mctx.Provider(SnapshotInfoProvider).(SnapshotInfo)
  1042. for idx, dep := range deps {
  1043. if lib, ok := snapshot.StaticLibs[dep]; ok {
  1044. deps[idx] = lib
  1045. }
  1046. }
  1047. // static executable gets static runtime libs
  1048. depTag := libraryDependencyTag{Kind: staticLibraryDependency}
  1049. variations := append(mctx.Target().Variations(),
  1050. blueprint.Variation{Mutator: "link", Variation: "static"})
  1051. if c.Device() {
  1052. variations = append(variations, c.ImageVariation())
  1053. }
  1054. if c.UseSdk() {
  1055. variations = append(variations,
  1056. blueprint.Variation{Mutator: "sdk", Variation: "sdk"})
  1057. }
  1058. mctx.AddFarVariationDependencies(variations, depTag, deps...)
  1059. }
  1060. if enableMinimalRuntime(c.sanitize) || c.sanitize.Properties.MinimalRuntimeDep {
  1061. addStaticDeps(config.UndefinedBehaviorSanitizerMinimalRuntimeLibrary(toolchain))
  1062. }
  1063. if c.sanitize.Properties.BuiltinsDep {
  1064. addStaticDeps(config.BuiltinsRuntimeLibrary(toolchain))
  1065. }
  1066. if runtimeLibrary != "" && (toolchain.Bionic() || c.sanitize.Properties.UbsanRuntimeDep) {
  1067. // UBSan is supported on non-bionic linux host builds as well
  1068. // Adding dependency to the runtime library. We are using *FarVariation*
  1069. // because the runtime libraries themselves are not mutated by sanitizer
  1070. // mutators and thus don't have sanitizer variants whereas this module
  1071. // has been already mutated.
  1072. //
  1073. // Note that by adding dependency with {static|shared}DepTag, the lib is
  1074. // added to libFlags and LOCAL_SHARED_LIBRARIES by cc.Module
  1075. if c.staticBinary() {
  1076. addStaticDeps(runtimeLibrary)
  1077. addStaticDeps(extraStaticDeps...)
  1078. } else if !c.static() && !c.Header() {
  1079. // If we're using snapshots, redirect to snapshot whenever possible
  1080. snapshot := mctx.Provider(SnapshotInfoProvider).(SnapshotInfo)
  1081. if lib, ok := snapshot.SharedLibs[runtimeLibrary]; ok {
  1082. runtimeLibrary = lib
  1083. }
  1084. // Skip apex dependency check for sharedLibraryDependency
  1085. // when sanitizer diags are enabled. Skipping the check will allow
  1086. // building with diag libraries without having to list the
  1087. // dependency in Apex's allowed_deps file.
  1088. diagEnabled := len(diagSanitizers) > 0
  1089. // dynamic executable and shared libs get shared runtime libs
  1090. depTag := libraryDependencyTag{
  1091. Kind: sharedLibraryDependency,
  1092. Order: earlyLibraryDependency,
  1093. skipApexAllowedDependenciesCheck: diagEnabled,
  1094. }
  1095. variations := append(mctx.Target().Variations(),
  1096. blueprint.Variation{Mutator: "link", Variation: "shared"})
  1097. if c.Device() {
  1098. variations = append(variations, c.ImageVariation())
  1099. }
  1100. if c.UseSdk() {
  1101. variations = append(variations,
  1102. blueprint.Variation{Mutator: "sdk", Variation: "sdk"})
  1103. }
  1104. AddSharedLibDependenciesWithVersions(mctx, c, variations, depTag, runtimeLibrary, "", true)
  1105. }
  1106. // static lib does not have dependency to the runtime library. The
  1107. // dependency will be added to the executables or shared libs using
  1108. // the static lib.
  1109. }
  1110. }
  1111. }
  1112. type Sanitizeable interface {
  1113. android.Module
  1114. IsSanitizerEnabled(ctx android.BaseModuleContext, sanitizerName string) bool
  1115. EnableSanitizer(sanitizerName string)
  1116. AddSanitizerDependencies(ctx android.BottomUpMutatorContext, sanitizerName string)
  1117. }
  1118. func (c *Module) MinimalRuntimeDep() bool {
  1119. return c.sanitize.Properties.MinimalRuntimeDep
  1120. }
  1121. func (c *Module) UbsanRuntimeDep() bool {
  1122. return c.sanitize.Properties.UbsanRuntimeDep
  1123. }
  1124. func (c *Module) SanitizePropDefined() bool {
  1125. return c.sanitize != nil
  1126. }
  1127. func (c *Module) IsSanitizerEnabled(t SanitizerType) bool {
  1128. return c.sanitize.isSanitizerEnabled(t)
  1129. }
  1130. func (c *Module) SanitizeDep() bool {
  1131. return c.sanitize.Properties.SanitizeDep
  1132. }
  1133. func (c *Module) StaticallyLinked() bool {
  1134. return c.static()
  1135. }
  1136. func (c *Module) SetInSanitizerDir() {
  1137. if c.sanitize != nil {
  1138. c.sanitize.Properties.InSanitizerDir = true
  1139. }
  1140. }
  1141. func (c *Module) SetSanitizer(t SanitizerType, b bool) {
  1142. if c.sanitize != nil {
  1143. c.sanitize.SetSanitizer(t, b)
  1144. }
  1145. }
  1146. func (c *Module) SetSanitizeDep(b bool) {
  1147. if c.sanitize != nil {
  1148. c.sanitize.Properties.SanitizeDep = b
  1149. }
  1150. }
  1151. var _ PlatformSanitizeable = (*Module)(nil)
  1152. // Create sanitized variants for modules that need them
  1153. func sanitizerMutator(t SanitizerType) func(android.BottomUpMutatorContext) {
  1154. return func(mctx android.BottomUpMutatorContext) {
  1155. if c, ok := mctx.Module().(PlatformSanitizeable); ok && c.SanitizePropDefined() {
  1156. // Make sure we're not setting CFI to any value if it's not supported.
  1157. cfiSupported := mctx.Module().(PlatformSanitizeable).SanitizerSupported(cfi)
  1158. if c.Binary() && c.IsSanitizerEnabled(t) {
  1159. modules := mctx.CreateVariations(t.variationName())
  1160. modules[0].(PlatformSanitizeable).SetSanitizer(t, true)
  1161. } else if c.IsSanitizerEnabled(t) || c.SanitizeDep() {
  1162. isSanitizerEnabled := c.IsSanitizerEnabled(t)
  1163. if c.StaticallyLinked() || c.Header() || t == Fuzzer {
  1164. // Static and header libs are split into non-sanitized and sanitized variants.
  1165. // Shared libs are not split. However, for asan and fuzzer, we split even for shared
  1166. // libs because a library sanitized for asan/fuzzer can't be linked from a library
  1167. // that isn't sanitized for asan/fuzzer.
  1168. //
  1169. // Note for defaultVariation: since we don't split for shared libs but for static/header
  1170. // libs, it is possible for the sanitized variant of a static/header lib to depend
  1171. // on non-sanitized variant of a shared lib. Such unfulfilled variation causes an
  1172. // error when the module is split. defaultVariation is the name of the variation that
  1173. // will be used when such a dangling dependency occurs during the split of the current
  1174. // module. By setting it to the name of the sanitized variation, the dangling dependency
  1175. // is redirected to the sanitized variant of the dependent module.
  1176. defaultVariation := t.variationName()
  1177. // Not all PlatformSanitizeable modules support the CFI sanitizer
  1178. mctx.SetDefaultDependencyVariation(&defaultVariation)
  1179. modules := mctx.CreateVariations("", t.variationName())
  1180. modules[0].(PlatformSanitizeable).SetSanitizer(t, false)
  1181. modules[1].(PlatformSanitizeable).SetSanitizer(t, true)
  1182. modules[0].(PlatformSanitizeable).SetSanitizeDep(false)
  1183. modules[1].(PlatformSanitizeable).SetSanitizeDep(false)
  1184. if mctx.Device() && t.incompatibleWithCfi() && cfiSupported {
  1185. // TODO: Make sure that cfi mutator runs "after" any of the sanitizers that
  1186. // are incompatible with cfi
  1187. modules[1].(PlatformSanitizeable).SetSanitizer(cfi, false)
  1188. }
  1189. // For cfi/scs/hwasan, we can export both sanitized and un-sanitized variants
  1190. // to Make, because the sanitized version has a different suffix in name.
  1191. // For other types of sanitizers, suppress the variation that is disabled.
  1192. if t != cfi && t != scs && t != Hwasan {
  1193. if isSanitizerEnabled {
  1194. modules[0].(PlatformSanitizeable).SetPreventInstall()
  1195. modules[0].(PlatformSanitizeable).SetHideFromMake()
  1196. } else {
  1197. modules[1].(PlatformSanitizeable).SetPreventInstall()
  1198. modules[1].(PlatformSanitizeable).SetHideFromMake()
  1199. }
  1200. }
  1201. // Export the static lib name to make
  1202. if c.StaticallyLinked() && c.ExportedToMake() {
  1203. if t == cfi {
  1204. cfiStaticLibs(mctx.Config()).add(c, c.Module().Name())
  1205. } else if t == Hwasan {
  1206. hwasanStaticLibs(mctx.Config()).add(c, c.Module().Name())
  1207. }
  1208. }
  1209. } else {
  1210. // Shared libs are not split. Only the sanitized variant is created.
  1211. modules := mctx.CreateVariations(t.variationName())
  1212. modules[0].(PlatformSanitizeable).SetSanitizer(t, true)
  1213. modules[0].(PlatformSanitizeable).SetSanitizeDep(false)
  1214. // locate the asan libraries under /data/asan
  1215. if mctx.Device() && t == Asan && isSanitizerEnabled {
  1216. modules[0].(PlatformSanitizeable).SetInSanitizerDir()
  1217. }
  1218. if mctx.Device() && t.incompatibleWithCfi() && cfiSupported {
  1219. // TODO: Make sure that cfi mutator runs "after" any of the sanitizers that
  1220. // are incompatible with cfi
  1221. modules[0].(PlatformSanitizeable).SetSanitizer(cfi, false)
  1222. }
  1223. }
  1224. }
  1225. c.SetSanitizeDep(false)
  1226. } else if sanitizeable, ok := mctx.Module().(Sanitizeable); ok && sanitizeable.IsSanitizerEnabled(mctx, t.name()) {
  1227. // APEX modules fall here
  1228. sanitizeable.AddSanitizerDependencies(mctx, t.name())
  1229. mctx.CreateVariations(t.variationName())
  1230. } else if c, ok := mctx.Module().(*Module); ok {
  1231. //TODO: When Rust modules have vendor support, enable this path for PlatformSanitizeable
  1232. // Check if it's a snapshot module supporting sanitizer
  1233. if s, ok := c.linker.(snapshotSanitizer); ok && s.isSanitizerEnabled(t) {
  1234. // Set default variation as above.
  1235. defaultVariation := t.variationName()
  1236. mctx.SetDefaultDependencyVariation(&defaultVariation)
  1237. modules := mctx.CreateVariations("", t.variationName())
  1238. modules[0].(*Module).linker.(snapshotSanitizer).setSanitizerVariation(t, false)
  1239. modules[1].(*Module).linker.(snapshotSanitizer).setSanitizerVariation(t, true)
  1240. // Export the static lib name to make
  1241. if c.static() && c.ExportedToMake() {
  1242. if t == cfi {
  1243. // use BaseModuleName which is the name for Make.
  1244. cfiStaticLibs(mctx.Config()).add(c, c.BaseModuleName())
  1245. }
  1246. }
  1247. }
  1248. }
  1249. }
  1250. }
  1251. type sanitizerStaticLibsMap struct {
  1252. // libsMap contains one list of modules per each image and each arch.
  1253. // e.g. libs[vendor]["arm"] contains arm modules installed to vendor
  1254. libsMap map[ImageVariantType]map[string][]string
  1255. libsMapLock sync.Mutex
  1256. sanitizerType SanitizerType
  1257. }
  1258. func newSanitizerStaticLibsMap(t SanitizerType) *sanitizerStaticLibsMap {
  1259. return &sanitizerStaticLibsMap{
  1260. sanitizerType: t,
  1261. libsMap: make(map[ImageVariantType]map[string][]string),
  1262. }
  1263. }
  1264. // Add the current module to sanitizer static libs maps
  1265. // Each module should pass its exported name as names of Make and Soong can differ.
  1266. func (s *sanitizerStaticLibsMap) add(c LinkableInterface, name string) {
  1267. image := GetImageVariantType(c)
  1268. arch := c.Module().Target().Arch.ArchType.String()
  1269. s.libsMapLock.Lock()
  1270. defer s.libsMapLock.Unlock()
  1271. if _, ok := s.libsMap[image]; !ok {
  1272. s.libsMap[image] = make(map[string][]string)
  1273. }
  1274. s.libsMap[image][arch] = append(s.libsMap[image][arch], name)
  1275. }
  1276. // Exports makefile variables in the following format:
  1277. // SOONG_{sanitizer}_{image}_{arch}_STATIC_LIBRARIES
  1278. // e.g. SOONG_cfi_core_x86_STATIC_LIBRARIES
  1279. // These are to be used by use_soong_sanitized_static_libraries.
  1280. // See build/make/core/binary.mk for more details.
  1281. func (s *sanitizerStaticLibsMap) exportToMake(ctx android.MakeVarsContext) {
  1282. for _, image := range android.SortedStringKeys(s.libsMap) {
  1283. archMap := s.libsMap[ImageVariantType(image)]
  1284. for _, arch := range android.SortedStringKeys(archMap) {
  1285. libs := archMap[arch]
  1286. sort.Strings(libs)
  1287. key := fmt.Sprintf(
  1288. "SOONG_%s_%s_%s_STATIC_LIBRARIES",
  1289. s.sanitizerType.variationName(),
  1290. image, // already upper
  1291. arch)
  1292. ctx.Strict(key, strings.Join(libs, " "))
  1293. }
  1294. }
  1295. }
  1296. var cfiStaticLibsKey = android.NewOnceKey("cfiStaticLibs")
  1297. func cfiStaticLibs(config android.Config) *sanitizerStaticLibsMap {
  1298. return config.Once(cfiStaticLibsKey, func() interface{} {
  1299. return newSanitizerStaticLibsMap(cfi)
  1300. }).(*sanitizerStaticLibsMap)
  1301. }
  1302. var hwasanStaticLibsKey = android.NewOnceKey("hwasanStaticLibs")
  1303. func hwasanStaticLibs(config android.Config) *sanitizerStaticLibsMap {
  1304. return config.Once(hwasanStaticLibsKey, func() interface{} {
  1305. return newSanitizerStaticLibsMap(Hwasan)
  1306. }).(*sanitizerStaticLibsMap)
  1307. }
  1308. func enableMinimalRuntime(sanitize *sanitize) bool {
  1309. if !Bool(sanitize.Properties.Sanitize.Address) &&
  1310. !Bool(sanitize.Properties.Sanitize.Hwaddress) &&
  1311. !Bool(sanitize.Properties.Sanitize.Fuzzer) &&
  1312. (Bool(sanitize.Properties.Sanitize.Integer_overflow) ||
  1313. len(sanitize.Properties.Sanitize.Misc_undefined) > 0 ||
  1314. Bool(sanitize.Properties.Sanitize.Undefined) ||
  1315. Bool(sanitize.Properties.Sanitize.All_undefined)) &&
  1316. !(Bool(sanitize.Properties.Sanitize.Diag.Integer_overflow) ||
  1317. Bool(sanitize.Properties.Sanitize.Diag.Cfi) ||
  1318. Bool(sanitize.Properties.Sanitize.Diag.Undefined) ||
  1319. len(sanitize.Properties.Sanitize.Diag.Misc_undefined) > 0) {
  1320. return true
  1321. }
  1322. return false
  1323. }
  1324. func (m *Module) UbsanRuntimeNeeded() bool {
  1325. return enableUbsanRuntime(m.sanitize)
  1326. }
  1327. func (m *Module) MinimalRuntimeNeeded() bool {
  1328. return enableMinimalRuntime(m.sanitize)
  1329. }
  1330. func enableUbsanRuntime(sanitize *sanitize) bool {
  1331. return Bool(sanitize.Properties.Sanitize.Diag.Integer_overflow) ||
  1332. Bool(sanitize.Properties.Sanitize.Diag.Undefined) ||
  1333. len(sanitize.Properties.Sanitize.Diag.Misc_undefined) > 0
  1334. }
  1335. func cfiMakeVarsProvider(ctx android.MakeVarsContext) {
  1336. cfiStaticLibs(ctx.Config()).exportToMake(ctx)
  1337. }
  1338. func hwasanMakeVarsProvider(ctx android.MakeVarsContext) {
  1339. hwasanStaticLibs(ctx.Config()).exportToMake(ctx)
  1340. }