sanitize.go 64 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893
  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. // DO NOT ADD MLLVM FLAGS HERE! ADD THEM BELOW TO hwasanCommonFlags.
  35. hwasanCflags = []string{
  36. "-fno-omit-frame-pointer",
  37. "-Wno-frame-larger-than=",
  38. "-fsanitize-hwaddress-abi=platform",
  39. }
  40. // ThinLTO performs codegen during link time, thus these flags need to
  41. // passed to both CFLAGS and LDFLAGS.
  42. hwasanCommonflags = []string{
  43. // The following improves debug location information
  44. // availability at the cost of its accuracy. It increases
  45. // the likelihood of a stack variable's frame offset
  46. // to be recorded in the debug info, which is important
  47. // for the quality of hwasan reports. The downside is a
  48. // higher number of "optimized out" stack variables.
  49. // b/112437883.
  50. "-instcombine-lower-dbg-declare=0",
  51. // TODO(b/159343917): HWASan and GlobalISel don't play nicely, and
  52. // GlobalISel is the default at -O0 on aarch64.
  53. "--aarch64-enable-global-isel-at-O=-1",
  54. "-fast-isel=false",
  55. "-hwasan-use-after-scope=1",
  56. "-dom-tree-reachability-max-bbs-to-explore=128",
  57. }
  58. sanitizeIgnorelistPrefix = "-fsanitize-ignorelist="
  59. cfiBlocklistPath = "external/compiler-rt/lib/cfi"
  60. cfiBlocklistFilename = "cfi_blocklist.txt"
  61. cfiEnableFlag = "-fsanitize=cfi"
  62. cfiCrossDsoFlag = "-fsanitize-cfi-cross-dso"
  63. cfiCflags = []string{"-flto", cfiCrossDsoFlag,
  64. sanitizeIgnorelistPrefix + cfiBlocklistPath + "/" + cfiBlocklistFilename}
  65. // -flto and -fvisibility are required by clang when -fsanitize=cfi is
  66. // used, but have no effect on assembly files
  67. cfiAsflags = []string{"-flto", "-fvisibility=default"}
  68. cfiLdflags = []string{"-flto", cfiCrossDsoFlag, cfiEnableFlag,
  69. "-Wl,-plugin-opt,O1"}
  70. cfiExportsMapPath = "build/soong/cc/config"
  71. cfiExportsMapFilename = "cfi_exports.map"
  72. cfiAssemblySupportFlag = "-fno-sanitize-cfi-canonical-jump-tables"
  73. intOverflowCflags = []string{"-fsanitize-ignorelist=build/soong/cc/config/integer_overflow_blocklist.txt"}
  74. minimalRuntimeFlags = []string{"-fsanitize-minimal-runtime", "-fno-sanitize-trap=integer,undefined",
  75. "-fno-sanitize-recover=integer,undefined"}
  76. hwasanGlobalOptions = []string{"heap_history_size=1023", "stack_history_size=512",
  77. "export_memory_stats=0", "max_malloc_fill_size=131072", "malloc_fill_byte=0"}
  78. memtagStackCommonFlags = []string{"-march=armv8-a+memtag", "-mllvm", "-dom-tree-reachability-max-bbs-to-explore=128"}
  79. hostOnlySanitizeFlags = []string{"-fno-sanitize-recover=all"}
  80. deviceOnlySanitizeFlags = []string{"-fsanitize-trap=all", "-ftrap-function=abort"}
  81. )
  82. type SanitizerType int
  83. const (
  84. Asan SanitizerType = iota + 1
  85. Hwasan
  86. tsan
  87. intOverflow
  88. scs
  89. Fuzzer
  90. Memtag_heap
  91. Memtag_stack
  92. Memtag_globals
  93. cfi // cfi is last to prevent it running before incompatible mutators
  94. )
  95. var Sanitizers = []SanitizerType{
  96. Asan,
  97. Hwasan,
  98. tsan,
  99. intOverflow,
  100. scs,
  101. Fuzzer,
  102. Memtag_heap,
  103. Memtag_stack,
  104. Memtag_globals,
  105. cfi, // cfi is last to prevent it running before incompatible mutators
  106. }
  107. // Name of the sanitizer variation for this sanitizer type
  108. func (t SanitizerType) variationName() string {
  109. switch t {
  110. case Asan:
  111. return "asan"
  112. case Hwasan:
  113. return "hwasan"
  114. case tsan:
  115. return "tsan"
  116. case intOverflow:
  117. return "intOverflow"
  118. case cfi:
  119. return "cfi"
  120. case scs:
  121. return "scs"
  122. case Memtag_heap:
  123. return "memtag_heap"
  124. case Memtag_stack:
  125. return "memtag_stack"
  126. case Memtag_globals:
  127. return "memtag_globals"
  128. case Fuzzer:
  129. return "fuzzer"
  130. default:
  131. panic(fmt.Errorf("unknown SanitizerType %d", t))
  132. }
  133. }
  134. // This is the sanitizer names in SANITIZE_[TARGET|HOST]
  135. func (t SanitizerType) name() string {
  136. switch t {
  137. case Asan:
  138. return "address"
  139. case Hwasan:
  140. return "hwaddress"
  141. case Memtag_heap:
  142. return "memtag_heap"
  143. case Memtag_stack:
  144. return "memtag_stack"
  145. case Memtag_globals:
  146. return "memtag_globals"
  147. case tsan:
  148. return "thread"
  149. case intOverflow:
  150. return "integer_overflow"
  151. case cfi:
  152. return "cfi"
  153. case scs:
  154. return "shadow-call-stack"
  155. case Fuzzer:
  156. return "fuzzer"
  157. default:
  158. panic(fmt.Errorf("unknown SanitizerType %d", t))
  159. }
  160. }
  161. func (t SanitizerType) registerMutators(ctx android.RegisterMutatorsContext) {
  162. switch t {
  163. case cfi, Hwasan, Asan, tsan, Fuzzer, scs:
  164. sanitizer := &sanitizerSplitMutator{t}
  165. ctx.TopDown(t.variationName()+"_markapexes", sanitizer.markSanitizableApexesMutator)
  166. ctx.Transition(t.variationName(), sanitizer)
  167. case Memtag_heap, Memtag_stack, Memtag_globals, intOverflow:
  168. // do nothing
  169. default:
  170. panic(fmt.Errorf("unknown SanitizerType %d", t))
  171. }
  172. }
  173. // shouldPropagateToSharedLibraryDeps returns whether a sanitizer type should propagate to share
  174. // dependencies. In most cases, sanitizers only propagate to static dependencies; however, some
  175. // sanitizers also must be enabled for shared libraries for linking.
  176. func (t SanitizerType) shouldPropagateToSharedLibraryDeps() bool {
  177. switch t {
  178. case Fuzzer:
  179. // Typically, shared libs are not split. However, for fuzzer, we split even for shared libs
  180. // because a library sanitized for fuzzer can't be linked from a library that isn't sanitized
  181. // for fuzzer.
  182. return true
  183. default:
  184. return false
  185. }
  186. }
  187. func (*Module) SanitizerSupported(t SanitizerType) bool {
  188. switch t {
  189. case Asan:
  190. return true
  191. case Hwasan:
  192. return true
  193. case tsan:
  194. return true
  195. case intOverflow:
  196. return true
  197. case cfi:
  198. return true
  199. case scs:
  200. return true
  201. case Fuzzer:
  202. return true
  203. case Memtag_heap:
  204. return true
  205. case Memtag_stack:
  206. return true
  207. case Memtag_globals:
  208. return true
  209. default:
  210. return false
  211. }
  212. }
  213. // incompatibleWithCfi returns true if a sanitizer is incompatible with CFI.
  214. func (t SanitizerType) incompatibleWithCfi() bool {
  215. return t == Asan || t == Fuzzer || t == Hwasan
  216. }
  217. type SanitizeUserProps struct {
  218. // Prevent use of any sanitizers on this module
  219. Never *bool `android:"arch_variant"`
  220. // ASan (Address sanitizer), incompatible with static binaries.
  221. // Always runs in a diagnostic mode.
  222. // Use of address sanitizer disables cfi sanitizer.
  223. // Hwaddress sanitizer takes precedence over this sanitizer.
  224. Address *bool `android:"arch_variant"`
  225. // TSan (Thread sanitizer), incompatible with static binaries and 32 bit architectures.
  226. // Always runs in a diagnostic mode.
  227. // Use of thread sanitizer disables cfi and scudo sanitizers.
  228. // Hwaddress sanitizer takes precedence over this sanitizer.
  229. Thread *bool `android:"arch_variant"`
  230. // HWASan (Hardware Address sanitizer).
  231. // Use of hwasan sanitizer disables cfi, address, thread, and scudo sanitizers.
  232. Hwaddress *bool `android:"arch_variant"`
  233. // Undefined behavior sanitizer
  234. All_undefined *bool `android:"arch_variant"`
  235. // Subset of undefined behavior sanitizer
  236. Undefined *bool `android:"arch_variant"`
  237. // List of specific undefined behavior sanitizers to enable
  238. Misc_undefined []string `android:"arch_variant"`
  239. // Fuzzer, incompatible with static binaries.
  240. Fuzzer *bool `android:"arch_variant"`
  241. // safe-stack sanitizer, incompatible with 32-bit architectures.
  242. Safestack *bool `android:"arch_variant"`
  243. // cfi sanitizer, incompatible with asan, hwasan, fuzzer, or Darwin
  244. Cfi *bool `android:"arch_variant"`
  245. // signed/unsigned integer overflow sanitizer, incompatible with Darwin.
  246. Integer_overflow *bool `android:"arch_variant"`
  247. // scudo sanitizer, incompatible with asan, hwasan, tsan
  248. // This should not be used in Android 11+ : https://source.android.com/devices/tech/debug/scudo
  249. // deprecated
  250. Scudo *bool `android:"arch_variant"`
  251. // shadow-call-stack sanitizer, only available on arm64/riscv64.
  252. Scs *bool `android:"arch_variant"`
  253. // Memory-tagging, only available on arm64
  254. // if diag.memtag unset or false, enables async memory tagging
  255. Memtag_heap *bool `android:"arch_variant"`
  256. // Memory-tagging stack instrumentation, only available on arm64
  257. // Adds instrumentation to detect stack buffer overflows and use-after-scope using MTE.
  258. Memtag_stack *bool `android:"arch_variant"`
  259. // Memory-tagging globals instrumentation, only available on arm64
  260. // Adds instrumentation to detect global buffer overflows using MTE.
  261. Memtag_globals *bool `android:"arch_variant"`
  262. // A modifier for ASAN and HWASAN for write only instrumentation
  263. Writeonly *bool `android:"arch_variant"`
  264. // Sanitizers to run in the diagnostic mode (as opposed to the release mode).
  265. // Replaces abort() on error with a human-readable error message.
  266. // Address and Thread sanitizers always run in diagnostic mode.
  267. Diag struct {
  268. // Undefined behavior sanitizer, diagnostic mode
  269. Undefined *bool `android:"arch_variant"`
  270. // cfi sanitizer, diagnostic mode, incompatible with asan, hwasan, fuzzer, or Darwin
  271. Cfi *bool `android:"arch_variant"`
  272. // signed/unsigned integer overflow sanitizer, diagnostic mode, incompatible with Darwin.
  273. Integer_overflow *bool `android:"arch_variant"`
  274. // Memory-tagging, only available on arm64
  275. // requires sanitizer.memtag: true
  276. // if set, enables sync memory tagging
  277. Memtag_heap *bool `android:"arch_variant"`
  278. // List of specific undefined behavior sanitizers to enable in diagnostic mode
  279. Misc_undefined []string `android:"arch_variant"`
  280. // List of sanitizers to pass to -fno-sanitize-recover
  281. // results in only the first detected error for these sanitizers being reported and program then
  282. // exits with a non-zero exit code.
  283. No_recover []string `android:"arch_variant"`
  284. } `android:"arch_variant"`
  285. // Sanitizers to run with flag configuration specified
  286. Config struct {
  287. // Enables CFI support flags for assembly-heavy libraries
  288. Cfi_assembly_support *bool `android:"arch_variant"`
  289. } `android:"arch_variant"`
  290. // List of sanitizers to pass to -fsanitize-recover
  291. // allows execution to continue for these sanitizers to detect multiple errors rather than only
  292. // the first one
  293. Recover []string
  294. // value to pass to -fsanitize-ignorelist
  295. Blocklist *string
  296. }
  297. type sanitizeMutatedProperties struct {
  298. // Whether sanitizers can be enabled on this module
  299. Never *bool `blueprint:"mutated"`
  300. // Whether ASan (Address sanitizer) is enabled for this module.
  301. // Hwaddress sanitizer takes precedence over this sanitizer.
  302. Address *bool `blueprint:"mutated"`
  303. // Whether TSan (Thread sanitizer) is enabled for this module
  304. Thread *bool `blueprint:"mutated"`
  305. // Whether HWASan (Hardware Address sanitizer) is enabled for this module
  306. Hwaddress *bool `blueprint:"mutated"`
  307. // Whether Undefined behavior sanitizer is enabled for this module
  308. All_undefined *bool `blueprint:"mutated"`
  309. // Whether undefined behavior sanitizer subset is enabled for this module
  310. Undefined *bool `blueprint:"mutated"`
  311. // List of specific undefined behavior sanitizers enabled for this module
  312. Misc_undefined []string `blueprint:"mutated"`
  313. // Whether Fuzzeris enabled for this module
  314. Fuzzer *bool `blueprint:"mutated"`
  315. // whether safe-stack sanitizer is enabled for this module
  316. Safestack *bool `blueprint:"mutated"`
  317. // Whether cfi sanitizer is enabled for this module
  318. Cfi *bool `blueprint:"mutated"`
  319. // Whether signed/unsigned integer overflow sanitizer is enabled for this module
  320. Integer_overflow *bool `blueprint:"mutated"`
  321. // Whether scudo sanitizer is enabled for this module
  322. Scudo *bool `blueprint:"mutated"`
  323. // Whether shadow-call-stack sanitizer is enabled for this module.
  324. Scs *bool `blueprint:"mutated"`
  325. // Whether Memory-tagging is enabled for this module
  326. Memtag_heap *bool `blueprint:"mutated"`
  327. // Whether Memory-tagging stack instrumentation is enabled for this module
  328. Memtag_stack *bool `blueprint:"mutated"`
  329. // Whether Memory-tagging globals instrumentation is enabled for this module
  330. Memtag_globals *bool `android:"arch_variant"`
  331. // Whether a modifier for ASAN and HWASAN for write only instrumentation is enabled for this
  332. // module
  333. Writeonly *bool `blueprint:"mutated"`
  334. // Sanitizers to run in the diagnostic mode (as opposed to the release mode).
  335. Diag struct {
  336. // Whether Undefined behavior sanitizer, diagnostic mode is enabled for this module
  337. Undefined *bool `blueprint:"mutated"`
  338. // Whether cfi sanitizer, diagnostic mode is enabled for this module
  339. Cfi *bool `blueprint:"mutated"`
  340. // Whether signed/unsigned integer overflow sanitizer, diagnostic mode is enabled for this
  341. // module
  342. Integer_overflow *bool `blueprint:"mutated"`
  343. // Whether Memory-tagging, diagnostic mode is enabled for this module
  344. Memtag_heap *bool `blueprint:"mutated"`
  345. // List of specific undefined behavior sanitizers enabled in diagnostic mode
  346. Misc_undefined []string `blueprint:"mutated"`
  347. } `blueprint:"mutated"`
  348. }
  349. type SanitizeProperties struct {
  350. Sanitize SanitizeUserProps `android:"arch_variant"`
  351. SanitizeMutated sanitizeMutatedProperties `blueprint:"mutated"`
  352. SanitizerEnabled bool `blueprint:"mutated"`
  353. MinimalRuntimeDep bool `blueprint:"mutated"`
  354. BuiltinsDep bool `blueprint:"mutated"`
  355. UbsanRuntimeDep bool `blueprint:"mutated"`
  356. InSanitizerDir bool `blueprint:"mutated"`
  357. Sanitizers []string `blueprint:"mutated"`
  358. DiagSanitizers []string `blueprint:"mutated"`
  359. }
  360. type sanitize struct {
  361. Properties SanitizeProperties
  362. }
  363. // Mark this tag with a check to see if apex dependency check should be skipped
  364. func (t libraryDependencyTag) SkipApexAllowedDependenciesCheck() bool {
  365. return t.skipApexAllowedDependenciesCheck
  366. }
  367. var _ android.SkipApexAllowedDependenciesCheck = (*libraryDependencyTag)(nil)
  368. var exportedVars = android.NewExportedVariables(pctx)
  369. func init() {
  370. exportedVars.ExportStringListStaticVariable("HostOnlySanitizeFlags", hostOnlySanitizeFlags)
  371. exportedVars.ExportStringList("DeviceOnlySanitizeFlags", deviceOnlySanitizeFlags)
  372. // Leave out "-flto" from the slices exported to bazel, as we will use the
  373. // dedicated LTO feature for this. For C Flags and Linker Flags, also leave
  374. // out the cross DSO flag which will be added separately under the correct conditions.
  375. exportedVars.ExportStringList("CfiCFlags", append(cfiCflags[2:], cfiEnableFlag))
  376. exportedVars.ExportStringList("CfiLdFlags", cfiLdflags[2:])
  377. exportedVars.ExportStringList("CfiAsFlags", cfiAsflags[1:])
  378. exportedVars.ExportString("SanitizeIgnorelistPrefix", sanitizeIgnorelistPrefix)
  379. exportedVars.ExportString("CfiCrossDsoFlag", cfiCrossDsoFlag)
  380. exportedVars.ExportString("CfiBlocklistPath", cfiBlocklistPath)
  381. exportedVars.ExportString("CfiBlocklistFilename", cfiBlocklistFilename)
  382. exportedVars.ExportString("CfiExportsMapPath", cfiExportsMapPath)
  383. exportedVars.ExportString("CfiExportsMapFilename", cfiExportsMapFilename)
  384. exportedVars.ExportString("CfiAssemblySupportFlag", cfiAssemblySupportFlag)
  385. android.RegisterMakeVarsProvider(pctx, cfiMakeVarsProvider)
  386. android.RegisterMakeVarsProvider(pctx, hwasanMakeVarsProvider)
  387. }
  388. func (sanitize *sanitize) props() []interface{} {
  389. return []interface{}{&sanitize.Properties}
  390. }
  391. func (p *sanitizeMutatedProperties) copyUserPropertiesToMutated(userProps *SanitizeUserProps) {
  392. p.Never = userProps.Never
  393. p.Address = userProps.Address
  394. p.All_undefined = userProps.All_undefined
  395. p.Cfi = userProps.Cfi
  396. p.Fuzzer = userProps.Fuzzer
  397. p.Hwaddress = userProps.Hwaddress
  398. p.Integer_overflow = userProps.Integer_overflow
  399. p.Memtag_heap = userProps.Memtag_heap
  400. p.Memtag_stack = userProps.Memtag_stack
  401. p.Memtag_globals = userProps.Memtag_globals
  402. p.Safestack = userProps.Safestack
  403. p.Scs = userProps.Scs
  404. p.Scudo = userProps.Scudo
  405. p.Thread = userProps.Thread
  406. p.Undefined = userProps.Undefined
  407. p.Writeonly = userProps.Writeonly
  408. p.Misc_undefined = make([]string, 0, len(userProps.Misc_undefined))
  409. for _, v := range userProps.Misc_undefined {
  410. p.Misc_undefined = append(p.Misc_undefined, v)
  411. }
  412. p.Diag.Cfi = userProps.Diag.Cfi
  413. p.Diag.Integer_overflow = userProps.Diag.Integer_overflow
  414. p.Diag.Memtag_heap = userProps.Diag.Memtag_heap
  415. p.Diag.Undefined = userProps.Diag.Undefined
  416. p.Diag.Misc_undefined = make([]string, 0, len(userProps.Diag.Misc_undefined))
  417. for _, v := range userProps.Diag.Misc_undefined {
  418. p.Diag.Misc_undefined = append(p.Diag.Misc_undefined, v)
  419. }
  420. }
  421. func (sanitize *sanitize) begin(ctx BaseModuleContext) {
  422. s := &sanitize.Properties.SanitizeMutated
  423. s.copyUserPropertiesToMutated(&sanitize.Properties.Sanitize)
  424. // Don't apply sanitizers to NDK code.
  425. if ctx.useSdk() {
  426. s.Never = BoolPtr(true)
  427. }
  428. // Never always wins.
  429. if Bool(s.Never) {
  430. return
  431. }
  432. // cc_test targets default to SYNC MemTag unless explicitly set to ASYNC (via diag: {memtag_heap: false}).
  433. if ctx.testBinary() {
  434. if s.Memtag_heap == nil {
  435. s.Memtag_heap = proptools.BoolPtr(true)
  436. }
  437. if s.Diag.Memtag_heap == nil {
  438. s.Diag.Memtag_heap = proptools.BoolPtr(true)
  439. }
  440. }
  441. var globalSanitizers []string
  442. var globalSanitizersDiag []string
  443. if ctx.Host() {
  444. if !ctx.Windows() {
  445. globalSanitizers = ctx.Config().SanitizeHost()
  446. }
  447. } else {
  448. arches := ctx.Config().SanitizeDeviceArch()
  449. if len(arches) == 0 || inList(ctx.Arch().ArchType.Name, arches) {
  450. globalSanitizers = ctx.Config().SanitizeDevice()
  451. globalSanitizersDiag = ctx.Config().SanitizeDeviceDiag()
  452. }
  453. }
  454. if len(globalSanitizers) > 0 {
  455. var found bool
  456. if found, globalSanitizers = removeFromList("undefined", globalSanitizers); found && s.All_undefined == nil {
  457. s.All_undefined = proptools.BoolPtr(true)
  458. }
  459. if found, globalSanitizers = removeFromList("default-ub", globalSanitizers); found && s.Undefined == nil {
  460. s.Undefined = proptools.BoolPtr(true)
  461. }
  462. if found, globalSanitizers = removeFromList("address", globalSanitizers); found && s.Address == nil {
  463. s.Address = proptools.BoolPtr(true)
  464. }
  465. if found, globalSanitizers = removeFromList("thread", globalSanitizers); found && s.Thread == nil {
  466. s.Thread = proptools.BoolPtr(true)
  467. }
  468. if found, globalSanitizers = removeFromList("fuzzer", globalSanitizers); found && s.Fuzzer == nil {
  469. s.Fuzzer = proptools.BoolPtr(true)
  470. }
  471. if found, globalSanitizers = removeFromList("safe-stack", globalSanitizers); found && s.Safestack == nil {
  472. s.Safestack = proptools.BoolPtr(true)
  473. }
  474. if found, globalSanitizers = removeFromList("cfi", globalSanitizers); found && s.Cfi == nil {
  475. if !ctx.Config().CFIDisabledForPath(ctx.ModuleDir()) {
  476. s.Cfi = proptools.BoolPtr(true)
  477. }
  478. }
  479. // Global integer_overflow builds do not support static libraries.
  480. if found, globalSanitizers = removeFromList("integer_overflow", globalSanitizers); found && s.Integer_overflow == nil {
  481. if !ctx.Config().IntegerOverflowDisabledForPath(ctx.ModuleDir()) && !ctx.static() {
  482. s.Integer_overflow = proptools.BoolPtr(true)
  483. }
  484. }
  485. if found, globalSanitizers = removeFromList("scudo", globalSanitizers); found && s.Scudo == nil {
  486. s.Scudo = proptools.BoolPtr(true)
  487. }
  488. if found, globalSanitizers = removeFromList("hwaddress", globalSanitizers); found && s.Hwaddress == nil {
  489. s.Hwaddress = proptools.BoolPtr(true)
  490. }
  491. if found, globalSanitizers = removeFromList("writeonly", globalSanitizers); found && s.Writeonly == nil {
  492. // Hwaddress and Address are set before, so we can check them here
  493. // If they aren't explicitly set in the blueprint/SANITIZE_(HOST|TARGET), they would be nil instead of false
  494. if s.Address == nil && s.Hwaddress == nil {
  495. ctx.ModuleErrorf("writeonly modifier cannot be used without 'address' or 'hwaddress'")
  496. }
  497. s.Writeonly = proptools.BoolPtr(true)
  498. }
  499. if found, globalSanitizers = removeFromList("memtag_heap", globalSanitizers); found && s.Memtag_heap == nil {
  500. if !ctx.Config().MemtagHeapDisabledForPath(ctx.ModuleDir()) {
  501. s.Memtag_heap = proptools.BoolPtr(true)
  502. }
  503. }
  504. if found, globalSanitizers = removeFromList("memtag_stack", globalSanitizers); found && s.Memtag_stack == nil {
  505. s.Memtag_stack = proptools.BoolPtr(true)
  506. }
  507. if found, globalSanitizers = removeFromList("memtag_globals", globalSanitizers); found && s.Memtag_globals == nil {
  508. s.Memtag_globals = proptools.BoolPtr(true)
  509. }
  510. if len(globalSanitizers) > 0 {
  511. ctx.ModuleErrorf("unknown global sanitizer option %s", globalSanitizers[0])
  512. }
  513. // Global integer_overflow builds do not support static library diagnostics.
  514. if found, globalSanitizersDiag = removeFromList("integer_overflow", globalSanitizersDiag); found &&
  515. s.Diag.Integer_overflow == nil && Bool(s.Integer_overflow) && !ctx.static() {
  516. s.Diag.Integer_overflow = proptools.BoolPtr(true)
  517. }
  518. if found, globalSanitizersDiag = removeFromList("cfi", globalSanitizersDiag); found &&
  519. s.Diag.Cfi == nil && Bool(s.Cfi) {
  520. s.Diag.Cfi = proptools.BoolPtr(true)
  521. }
  522. if found, globalSanitizersDiag = removeFromList("memtag_heap", globalSanitizersDiag); found &&
  523. s.Diag.Memtag_heap == nil && Bool(s.Memtag_heap) {
  524. s.Diag.Memtag_heap = proptools.BoolPtr(true)
  525. }
  526. if len(globalSanitizersDiag) > 0 {
  527. ctx.ModuleErrorf("unknown global sanitizer diagnostics option %s", globalSanitizersDiag[0])
  528. }
  529. }
  530. // Enable Memtag for all components in the include paths (for Aarch64 only)
  531. if ctx.Arch().ArchType == android.Arm64 && ctx.toolchain().Bionic() {
  532. if ctx.Config().MemtagHeapSyncEnabledForPath(ctx.ModuleDir()) {
  533. if s.Memtag_heap == nil {
  534. s.Memtag_heap = proptools.BoolPtr(true)
  535. }
  536. if s.Diag.Memtag_heap == nil {
  537. s.Diag.Memtag_heap = proptools.BoolPtr(true)
  538. }
  539. } else if ctx.Config().MemtagHeapAsyncEnabledForPath(ctx.ModuleDir()) {
  540. if s.Memtag_heap == nil {
  541. s.Memtag_heap = proptools.BoolPtr(true)
  542. }
  543. }
  544. }
  545. // Enable HWASan for all components in the include paths (for Aarch64 only)
  546. if s.Hwaddress == nil && ctx.Config().HWASanEnabledForPath(ctx.ModuleDir()) &&
  547. ctx.Arch().ArchType == android.Arm64 && ctx.toolchain().Bionic() {
  548. s.Hwaddress = proptools.BoolPtr(true)
  549. }
  550. // Enable CFI for non-host components in the include paths
  551. if s.Cfi == nil && ctx.Config().CFIEnabledForPath(ctx.ModuleDir()) && !ctx.Host() {
  552. s.Cfi = proptools.BoolPtr(true)
  553. if inList("cfi", ctx.Config().SanitizeDeviceDiag()) {
  554. s.Diag.Cfi = proptools.BoolPtr(true)
  555. }
  556. }
  557. // Is CFI actually enabled?
  558. if !ctx.Config().EnableCFI() {
  559. s.Cfi = nil
  560. s.Diag.Cfi = nil
  561. }
  562. // HWASan requires AArch64 hardware feature (top-byte-ignore).
  563. if ctx.Arch().ArchType != android.Arm64 || !ctx.toolchain().Bionic() {
  564. s.Hwaddress = nil
  565. }
  566. // SCS is only implemented on AArch64/riscv64.
  567. if (ctx.Arch().ArchType != android.Arm64 && ctx.Arch().ArchType != android.Riscv64) || !ctx.toolchain().Bionic() {
  568. s.Scs = nil
  569. }
  570. // ...but temporarily globally disabled on riscv64 (http://b/277909695).
  571. if ctx.Arch().ArchType == android.Riscv64 {
  572. s.Scs = nil
  573. }
  574. // Memtag_heap is only implemented on AArch64.
  575. // Memtag ABI is Android specific for now, so disable for host.
  576. if ctx.Arch().ArchType != android.Arm64 || !ctx.toolchain().Bionic() || ctx.Host() {
  577. s.Memtag_heap = nil
  578. s.Memtag_stack = nil
  579. s.Memtag_globals = nil
  580. }
  581. // Also disable CFI if ASAN is enabled.
  582. if Bool(s.Address) || Bool(s.Hwaddress) {
  583. s.Cfi = nil
  584. s.Diag.Cfi = nil
  585. // HWASAN and ASAN win against MTE.
  586. s.Memtag_heap = nil
  587. s.Memtag_stack = nil
  588. s.Memtag_globals = nil
  589. }
  590. // Disable sanitizers that depend on the UBSan runtime for windows/darwin builds.
  591. if !ctx.Os().Linux() {
  592. s.Cfi = nil
  593. s.Diag.Cfi = nil
  594. s.Misc_undefined = nil
  595. s.Undefined = nil
  596. s.All_undefined = nil
  597. s.Integer_overflow = nil
  598. }
  599. // TODO(b/254713216): CFI doesn't work for riscv64 yet because LTO doesn't work.
  600. if ctx.Arch().ArchType == android.Riscv64 {
  601. s.Cfi = nil
  602. s.Diag.Cfi = nil
  603. }
  604. // Disable CFI for musl
  605. if ctx.toolchain().Musl() {
  606. s.Cfi = nil
  607. s.Diag.Cfi = nil
  608. }
  609. // TODO(b/280478629): runtimes don't exist for musl arm64 yet.
  610. if ctx.toolchain().Musl() && ctx.Arch().ArchType == android.Arm64 {
  611. s.Address = nil
  612. s.Hwaddress = nil
  613. s.Thread = nil
  614. s.Scudo = nil
  615. s.Fuzzer = nil
  616. s.Cfi = nil
  617. s.Diag.Cfi = nil
  618. s.Misc_undefined = nil
  619. s.Undefined = nil
  620. s.All_undefined = nil
  621. s.Integer_overflow = nil
  622. }
  623. // Also disable CFI for VNDK variants of components
  624. if ctx.isVndk() && ctx.useVndk() {
  625. s.Cfi = nil
  626. s.Diag.Cfi = nil
  627. }
  628. // HWASan ramdisk (which is built from recovery) goes over some bootloader limit.
  629. // Keep libc instrumented so that ramdisk / vendor_ramdisk / recovery can run hwasan-instrumented code if necessary.
  630. if (ctx.inRamdisk() || ctx.inVendorRamdisk() || ctx.inRecovery()) && !strings.HasPrefix(ctx.ModuleDir(), "bionic/libc") {
  631. s.Hwaddress = nil
  632. }
  633. if ctx.staticBinary() {
  634. s.Address = nil
  635. s.Fuzzer = nil
  636. s.Thread = nil
  637. }
  638. if Bool(s.All_undefined) {
  639. s.Undefined = nil
  640. }
  641. if !ctx.toolchain().Is64Bit() {
  642. // TSAN and SafeStack are not supported on 32-bit architectures
  643. s.Thread = nil
  644. s.Safestack = nil
  645. // TODO(ccross): error for compile_multilib = "32"?
  646. }
  647. if ctx.Os() != android.Windows && (Bool(s.All_undefined) || Bool(s.Undefined) || Bool(s.Address) || Bool(s.Thread) ||
  648. Bool(s.Fuzzer) || Bool(s.Safestack) || Bool(s.Cfi) || Bool(s.Integer_overflow) || len(s.Misc_undefined) > 0 ||
  649. Bool(s.Scudo) || Bool(s.Hwaddress) || Bool(s.Scs) || Bool(s.Memtag_heap) || Bool(s.Memtag_stack) ||
  650. Bool(s.Memtag_globals)) {
  651. sanitize.Properties.SanitizerEnabled = true
  652. }
  653. // Disable Scudo if ASan or TSan is enabled, or if it's disabled globally.
  654. if Bool(s.Address) || Bool(s.Thread) || Bool(s.Hwaddress) || ctx.Config().DisableScudo() {
  655. s.Scudo = nil
  656. }
  657. if Bool(s.Hwaddress) {
  658. s.Address = nil
  659. s.Thread = nil
  660. }
  661. // TODO(b/131771163): CFI transiently depends on LTO, and thus Fuzzer is
  662. // mutually incompatible.
  663. if Bool(s.Fuzzer) {
  664. s.Cfi = nil
  665. }
  666. }
  667. func toDisableImplicitIntegerChange(flags []string) bool {
  668. // Returns true if any flag is fsanitize*integer, and there is
  669. // no explicit flag about sanitize=implicit-integer-sign-change.
  670. for _, f := range flags {
  671. if strings.Contains(f, "sanitize=implicit-integer-sign-change") {
  672. return false
  673. }
  674. }
  675. for _, f := range flags {
  676. if strings.HasPrefix(f, "-fsanitize") && strings.Contains(f, "integer") {
  677. return true
  678. }
  679. }
  680. return false
  681. }
  682. func toDisableUnsignedShiftBaseChange(flags []string) bool {
  683. // Returns true if any flag is fsanitize*integer, and there is
  684. // no explicit flag about sanitize=unsigned-shift-base.
  685. for _, f := range flags {
  686. if strings.Contains(f, "sanitize=unsigned-shift-base") {
  687. return false
  688. }
  689. }
  690. for _, f := range flags {
  691. if strings.HasPrefix(f, "-fsanitize") && strings.Contains(f, "integer") {
  692. return true
  693. }
  694. }
  695. return false
  696. }
  697. func (s *sanitize) flags(ctx ModuleContext, flags Flags) Flags {
  698. if !s.Properties.SanitizerEnabled && !s.Properties.UbsanRuntimeDep {
  699. return flags
  700. }
  701. sanProps := &s.Properties.SanitizeMutated
  702. if Bool(sanProps.Address) {
  703. if ctx.Arch().ArchType == android.Arm {
  704. // Frame pointer based unwinder in ASan requires ARM frame setup.
  705. // TODO: put in flags?
  706. flags.RequiredInstructionSet = "arm"
  707. }
  708. flags.Local.CFlags = append(flags.Local.CFlags, asanCflags...)
  709. flags.Local.LdFlags = append(flags.Local.LdFlags, asanLdflags...)
  710. if Bool(sanProps.Writeonly) {
  711. flags.Local.CFlags = append(flags.Local.CFlags, "-mllvm", "-asan-instrument-reads=0")
  712. }
  713. if ctx.Host() {
  714. // -nodefaultlibs (provided with libc++) prevents the driver from linking
  715. // libraries needed with -fsanitize=address. http://b/18650275 (WAI)
  716. flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--no-as-needed")
  717. } else {
  718. flags.Local.CFlags = append(flags.Local.CFlags, "-mllvm", "-asan-globals=0")
  719. if ctx.bootstrap() {
  720. flags.DynamicLinker = "/system/bin/bootstrap/linker_asan"
  721. } else {
  722. flags.DynamicLinker = "/system/bin/linker_asan"
  723. }
  724. if flags.Toolchain.Is64Bit() {
  725. flags.DynamicLinker += "64"
  726. }
  727. }
  728. }
  729. if Bool(sanProps.Hwaddress) {
  730. flags.Local.CFlags = append(flags.Local.CFlags, hwasanCflags...)
  731. for _, flag := range hwasanCommonflags {
  732. flags.Local.CFlags = append(flags.Local.CFlags, "-mllvm", flag)
  733. }
  734. for _, flag := range hwasanCommonflags {
  735. flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-mllvm,"+flag)
  736. }
  737. if Bool(sanProps.Writeonly) {
  738. flags.Local.CFlags = append(flags.Local.CFlags, "-mllvm", "-hwasan-instrument-reads=0")
  739. }
  740. if !ctx.staticBinary() && !ctx.Host() {
  741. if ctx.bootstrap() {
  742. flags.DynamicLinker = "/system/bin/bootstrap/linker_hwasan64"
  743. } else {
  744. flags.DynamicLinker = "/system/bin/linker_hwasan64"
  745. }
  746. }
  747. }
  748. if Bool(sanProps.Fuzzer) {
  749. flags.Local.CFlags = append(flags.Local.CFlags, "-fsanitize=fuzzer-no-link")
  750. // TODO(b/131771163): LTO and Fuzzer support is mutually incompatible.
  751. _, flags.Local.LdFlags = removeFromList("-flto", flags.Local.LdFlags)
  752. _, flags.Local.CFlags = removeFromList("-flto", flags.Local.CFlags)
  753. flags.Local.LdFlags = append(flags.Local.LdFlags, "-fno-lto")
  754. flags.Local.CFlags = append(flags.Local.CFlags, "-fno-lto")
  755. // TODO(b/142430592): Upstream linker scripts for sanitizer runtime libraries
  756. // discard the sancov_lowest_stack symbol, because it's emulated TLS (and thus
  757. // doesn't match the linker script due to the "__emutls_v." prefix).
  758. flags.Local.LdFlags = append(flags.Local.LdFlags, "-fno-sanitize-coverage=stack-depth")
  759. flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize-coverage=stack-depth")
  760. // Disable fortify for fuzzing builds. Generally, we'll be building with
  761. // UBSan or ASan here and the fortify checks pollute the stack traces.
  762. flags.Local.CFlags = append(flags.Local.CFlags, "-U_FORTIFY_SOURCE")
  763. // Build fuzzer-sanitized libraries with an $ORIGIN DT_RUNPATH. Android's
  764. // linker uses DT_RUNPATH, not DT_RPATH. When we deploy cc_fuzz targets and
  765. // their libraries to /data/fuzz/<arch>/lib, any transient shared library gets
  766. // the DT_RUNPATH from the shared library above it, and not the executable,
  767. // meaning that the lookup falls back to the system. Adding the $ORIGIN to the
  768. // DT_RUNPATH here means that transient shared libraries can be found
  769. // colocated with their parents.
  770. flags.Local.LdFlags = append(flags.Local.LdFlags, `-Wl,-rpath,\$$ORIGIN`)
  771. }
  772. if Bool(sanProps.Cfi) {
  773. if ctx.Arch().ArchType == android.Arm {
  774. // __cfi_check needs to be built as Thumb (see the code in linker_cfi.cpp). LLVM is not set up
  775. // to do this on a function basis, so force Thumb on the entire module.
  776. flags.RequiredInstructionSet = "thumb"
  777. }
  778. flags.Local.CFlags = append(flags.Local.CFlags, cfiCflags...)
  779. flags.Local.AsFlags = append(flags.Local.AsFlags, cfiAsflags...)
  780. if Bool(s.Properties.Sanitize.Config.Cfi_assembly_support) {
  781. flags.Local.CFlags = append(flags.Local.CFlags, cfiAssemblySupportFlag)
  782. }
  783. // Only append the default visibility flag if -fvisibility has not already been set
  784. // to hidden.
  785. if !inList("-fvisibility=hidden", flags.Local.CFlags) {
  786. flags.Local.CFlags = append(flags.Local.CFlags, "-fvisibility=default")
  787. }
  788. flags.Local.LdFlags = append(flags.Local.LdFlags, cfiLdflags...)
  789. if ctx.staticBinary() {
  790. _, flags.Local.CFlags = removeFromList("-fsanitize-cfi-cross-dso", flags.Local.CFlags)
  791. _, flags.Local.LdFlags = removeFromList("-fsanitize-cfi-cross-dso", flags.Local.LdFlags)
  792. }
  793. }
  794. if Bool(sanProps.Memtag_stack) {
  795. flags.Local.CFlags = append(flags.Local.CFlags, memtagStackCommonFlags...)
  796. flags.Local.AsFlags = append(flags.Local.AsFlags, memtagStackCommonFlags...)
  797. flags.Local.LdFlags = append(flags.Local.LdFlags, memtagStackCommonFlags...)
  798. }
  799. if (Bool(sanProps.Memtag_heap) || Bool(sanProps.Memtag_stack) || Bool(sanProps.Memtag_globals)) && ctx.binary() {
  800. if Bool(sanProps.Diag.Memtag_heap) {
  801. flags.Local.LdFlags = append(flags.Local.LdFlags, "-fsanitize-memtag-mode=sync")
  802. } else {
  803. flags.Local.LdFlags = append(flags.Local.LdFlags, "-fsanitize-memtag-mode=async")
  804. }
  805. }
  806. if Bool(sanProps.Integer_overflow) {
  807. flags.Local.CFlags = append(flags.Local.CFlags, intOverflowCflags...)
  808. }
  809. if len(s.Properties.Sanitizers) > 0 {
  810. sanitizeArg := "-fsanitize=" + strings.Join(s.Properties.Sanitizers, ",")
  811. flags.Local.CFlags = append(flags.Local.CFlags, sanitizeArg)
  812. flags.Local.AsFlags = append(flags.Local.AsFlags, sanitizeArg)
  813. flags.Local.LdFlags = append(flags.Local.LdFlags, sanitizeArg)
  814. if ctx.toolchain().Bionic() || ctx.toolchain().Musl() {
  815. // Bionic and musl sanitizer runtimes have already been added as dependencies so that
  816. // the right variant of the runtime will be used (with the "-android" or "-musl"
  817. // suffixes), so don't let clang the runtime library.
  818. flags.Local.LdFlags = append(flags.Local.LdFlags, "-fno-sanitize-link-runtime")
  819. } else {
  820. // Host sanitizers only link symbols in the final executable, so
  821. // there will always be undefined symbols in intermediate libraries.
  822. _, flags.Global.LdFlags = removeFromList("-Wl,--no-undefined", flags.Global.LdFlags)
  823. }
  824. if !ctx.toolchain().Bionic() {
  825. // non-Bionic toolchain prebuilts are missing UBSan's vptr and function san.
  826. // Musl toolchain prebuilts have vptr and function sanitizers, but enabling them
  827. // implicitly enables RTTI which causes RTTI mismatch issues with dependencies.
  828. flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize=vptr,function")
  829. }
  830. if Bool(sanProps.Fuzzer) {
  831. // When fuzzing, we wish to crash with diagnostics on any bug.
  832. flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize-trap=all", "-fno-sanitize-recover=all")
  833. } else if ctx.Host() {
  834. flags.Local.CFlags = append(flags.Local.CFlags, hostOnlySanitizeFlags...)
  835. } else {
  836. flags.Local.CFlags = append(flags.Local.CFlags, deviceOnlySanitizeFlags...)
  837. }
  838. if enableMinimalRuntime(s) {
  839. flags.Local.CFlags = append(flags.Local.CFlags, strings.Join(minimalRuntimeFlags, " "))
  840. }
  841. // http://b/119329758, Android core does not boot up with this sanitizer yet.
  842. if toDisableImplicitIntegerChange(flags.Local.CFlags) {
  843. flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize=implicit-integer-sign-change")
  844. }
  845. // http://b/171275751, Android doesn't build with this sanitizer yet.
  846. if toDisableUnsignedShiftBaseChange(flags.Local.CFlags) {
  847. flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize=unsigned-shift-base")
  848. }
  849. }
  850. if len(s.Properties.DiagSanitizers) > 0 {
  851. flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize-trap="+strings.Join(s.Properties.DiagSanitizers, ","))
  852. }
  853. // FIXME: enable RTTI if diag + (cfi or vptr)
  854. if s.Properties.Sanitize.Recover != nil {
  855. flags.Local.CFlags = append(flags.Local.CFlags, "-fsanitize-recover="+
  856. strings.Join(s.Properties.Sanitize.Recover, ","))
  857. }
  858. if s.Properties.Sanitize.Diag.No_recover != nil {
  859. flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize-recover="+
  860. strings.Join(s.Properties.Sanitize.Diag.No_recover, ","))
  861. }
  862. blocklist := android.OptionalPathForModuleSrc(ctx, s.Properties.Sanitize.Blocklist)
  863. if blocklist.Valid() {
  864. flags.Local.CFlags = append(flags.Local.CFlags, sanitizeIgnorelistPrefix+blocklist.String())
  865. flags.CFlagsDeps = append(flags.CFlagsDeps, blocklist.Path())
  866. }
  867. return flags
  868. }
  869. func (s *sanitize) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
  870. // Add a suffix for cfi/hwasan/scs-enabled static/header libraries to allow surfacing
  871. // both the sanitized and non-sanitized variants to make without a name conflict.
  872. if entries.Class == "STATIC_LIBRARIES" || entries.Class == "HEADER_LIBRARIES" {
  873. if Bool(s.Properties.SanitizeMutated.Cfi) {
  874. entries.SubName += ".cfi"
  875. }
  876. if Bool(s.Properties.SanitizeMutated.Hwaddress) {
  877. entries.SubName += ".hwasan"
  878. }
  879. if Bool(s.Properties.SanitizeMutated.Scs) {
  880. entries.SubName += ".scs"
  881. }
  882. }
  883. }
  884. func (s *sanitize) inSanitizerDir() bool {
  885. return s.Properties.InSanitizerDir
  886. }
  887. // getSanitizerBoolPtr returns the SanitizerTypes associated bool pointer from SanitizeProperties.
  888. func (s *sanitize) getSanitizerBoolPtr(t SanitizerType) *bool {
  889. switch t {
  890. case Asan:
  891. return s.Properties.SanitizeMutated.Address
  892. case Hwasan:
  893. return s.Properties.SanitizeMutated.Hwaddress
  894. case tsan:
  895. return s.Properties.SanitizeMutated.Thread
  896. case intOverflow:
  897. return s.Properties.SanitizeMutated.Integer_overflow
  898. case cfi:
  899. return s.Properties.SanitizeMutated.Cfi
  900. case scs:
  901. return s.Properties.SanitizeMutated.Scs
  902. case Memtag_heap:
  903. return s.Properties.SanitizeMutated.Memtag_heap
  904. case Memtag_stack:
  905. return s.Properties.SanitizeMutated.Memtag_stack
  906. case Memtag_globals:
  907. return s.Properties.SanitizeMutated.Memtag_globals
  908. case Fuzzer:
  909. return s.Properties.SanitizeMutated.Fuzzer
  910. default:
  911. panic(fmt.Errorf("unknown SanitizerType %d", t))
  912. }
  913. }
  914. // isUnsanitizedVariant returns true if no sanitizers are enabled.
  915. func (sanitize *sanitize) isUnsanitizedVariant() bool {
  916. return !sanitize.isSanitizerEnabled(Asan) &&
  917. !sanitize.isSanitizerEnabled(Hwasan) &&
  918. !sanitize.isSanitizerEnabled(tsan) &&
  919. !sanitize.isSanitizerEnabled(cfi) &&
  920. !sanitize.isSanitizerEnabled(scs) &&
  921. !sanitize.isSanitizerEnabled(Memtag_heap) &&
  922. !sanitize.isSanitizerEnabled(Memtag_stack) &&
  923. !sanitize.isSanitizerEnabled(Memtag_globals) &&
  924. !sanitize.isSanitizerEnabled(Fuzzer)
  925. }
  926. // isVariantOnProductionDevice returns true if variant is for production devices (no non-production sanitizers enabled).
  927. func (sanitize *sanitize) isVariantOnProductionDevice() bool {
  928. return !sanitize.isSanitizerEnabled(Asan) &&
  929. !sanitize.isSanitizerEnabled(Hwasan) &&
  930. !sanitize.isSanitizerEnabled(tsan) &&
  931. !sanitize.isSanitizerEnabled(Fuzzer)
  932. }
  933. func (sanitize *sanitize) SetSanitizer(t SanitizerType, b bool) {
  934. bPtr := proptools.BoolPtr(b)
  935. if !b {
  936. bPtr = nil
  937. }
  938. switch t {
  939. case Asan:
  940. sanitize.Properties.SanitizeMutated.Address = bPtr
  941. // For ASAN variant, we need to disable Memtag_stack
  942. sanitize.Properties.SanitizeMutated.Memtag_stack = nil
  943. sanitize.Properties.SanitizeMutated.Memtag_globals = nil
  944. case Hwasan:
  945. sanitize.Properties.SanitizeMutated.Hwaddress = bPtr
  946. // For HWAsan variant, we need to disable Memtag_stack
  947. sanitize.Properties.SanitizeMutated.Memtag_stack = nil
  948. sanitize.Properties.SanitizeMutated.Memtag_globals = nil
  949. case tsan:
  950. sanitize.Properties.SanitizeMutated.Thread = bPtr
  951. case intOverflow:
  952. sanitize.Properties.SanitizeMutated.Integer_overflow = bPtr
  953. case cfi:
  954. sanitize.Properties.SanitizeMutated.Cfi = bPtr
  955. case scs:
  956. sanitize.Properties.SanitizeMutated.Scs = bPtr
  957. case Memtag_heap:
  958. sanitize.Properties.SanitizeMutated.Memtag_heap = bPtr
  959. case Memtag_stack:
  960. sanitize.Properties.SanitizeMutated.Memtag_stack = bPtr
  961. // We do not need to disable ASAN or HWASan here, as there is no Memtag_stack variant.
  962. case Memtag_globals:
  963. sanitize.Properties.Sanitize.Memtag_globals = bPtr
  964. case Fuzzer:
  965. sanitize.Properties.SanitizeMutated.Fuzzer = bPtr
  966. default:
  967. panic(fmt.Errorf("unknown SanitizerType %d", t))
  968. }
  969. if b {
  970. sanitize.Properties.SanitizerEnabled = true
  971. }
  972. }
  973. // Check if the sanitizer is explicitly disabled (as opposed to nil by
  974. // virtue of not being set).
  975. func (sanitize *sanitize) isSanitizerExplicitlyDisabled(t SanitizerType) bool {
  976. if sanitize == nil {
  977. return false
  978. }
  979. sanitizerVal := sanitize.getSanitizerBoolPtr(t)
  980. return sanitizerVal != nil && *sanitizerVal == false
  981. }
  982. // There isn't an analog of the method above (ie:isSanitizerExplicitlyEnabled)
  983. // because enabling a sanitizer either directly (via the blueprint) or
  984. // indirectly (via a mutator) sets the bool ptr to true, and you can't
  985. // distinguish between the cases. It isn't needed though - both cases can be
  986. // treated identically.
  987. func (sanitize *sanitize) isSanitizerEnabled(t SanitizerType) bool {
  988. if sanitize == nil {
  989. return false
  990. }
  991. sanitizerVal := sanitize.getSanitizerBoolPtr(t)
  992. return sanitizerVal != nil && *sanitizerVal == true
  993. }
  994. // IsSanitizableDependencyTag returns true if the dependency tag is sanitizable.
  995. func IsSanitizableDependencyTag(tag blueprint.DependencyTag) bool {
  996. switch t := tag.(type) {
  997. case dependencyTag:
  998. return t == reuseObjTag || t == objDepTag
  999. case libraryDependencyTag:
  1000. return true
  1001. default:
  1002. return false
  1003. }
  1004. }
  1005. func (m *Module) SanitizableDepTagChecker() SantizableDependencyTagChecker {
  1006. return IsSanitizableDependencyTag
  1007. }
  1008. // Determines if the current module is a static library going to be captured
  1009. // as vendor snapshot. Such modules must create both cfi and non-cfi variants,
  1010. // except for ones which explicitly disable cfi.
  1011. func needsCfiForVendorSnapshot(mctx android.BaseModuleContext) bool {
  1012. if inList("hwaddress", mctx.Config().SanitizeDevice()) {
  1013. // cfi will not be built if SANITIZE_TARGET=hwaddress is set
  1014. return false
  1015. }
  1016. if snapshot.IsVendorProprietaryModule(mctx) {
  1017. return false
  1018. }
  1019. c := mctx.Module().(PlatformSanitizeable)
  1020. if !c.InVendor() {
  1021. return false
  1022. }
  1023. if !c.StaticallyLinked() {
  1024. return false
  1025. }
  1026. if c.IsPrebuilt() {
  1027. return false
  1028. }
  1029. if !c.SanitizerSupported(cfi) {
  1030. return false
  1031. }
  1032. return c.SanitizePropDefined() &&
  1033. !c.SanitizeNever() &&
  1034. !c.IsSanitizerExplicitlyDisabled(cfi)
  1035. }
  1036. type sanitizerSplitMutator struct {
  1037. sanitizer SanitizerType
  1038. }
  1039. // If an APEX is sanitized or not depends on whether it contains at least one
  1040. // sanitized module. Transition mutators cannot propagate information up the
  1041. // dependency graph this way, so we need an auxiliary mutator to do so.
  1042. func (s *sanitizerSplitMutator) markSanitizableApexesMutator(ctx android.TopDownMutatorContext) {
  1043. if sanitizeable, ok := ctx.Module().(Sanitizeable); ok {
  1044. enabled := sanitizeable.IsSanitizerEnabled(ctx.Config(), s.sanitizer.name())
  1045. ctx.VisitDirectDeps(func(dep android.Module) {
  1046. if c, ok := dep.(*Module); ok && c.sanitize.isSanitizerEnabled(s.sanitizer) {
  1047. enabled = true
  1048. }
  1049. })
  1050. if enabled {
  1051. sanitizeable.EnableSanitizer(s.sanitizer.name())
  1052. }
  1053. }
  1054. }
  1055. func (s *sanitizerSplitMutator) Split(ctx android.BaseModuleContext) []string {
  1056. if c, ok := ctx.Module().(PlatformSanitizeable); ok && c.SanitizePropDefined() {
  1057. if s.sanitizer == cfi && needsCfiForVendorSnapshot(ctx) {
  1058. return []string{"", s.sanitizer.variationName()}
  1059. }
  1060. // If the given sanitizer is not requested in the .bp file for a module, it
  1061. // won't automatically build the sanitized variation.
  1062. if !c.IsSanitizerEnabled(s.sanitizer) {
  1063. return []string{""}
  1064. }
  1065. if c.Binary() {
  1066. // If a sanitizer is enabled for a binary, we do not build the version
  1067. // without the sanitizer
  1068. return []string{s.sanitizer.variationName()}
  1069. } else if c.StaticallyLinked() || c.Header() {
  1070. // For static libraries, we build both versions. Some Make modules
  1071. // apparently depend on this behavior.
  1072. return []string{"", s.sanitizer.variationName()}
  1073. } else {
  1074. // We only build the requested variation of dynamic libraries
  1075. return []string{s.sanitizer.variationName()}
  1076. }
  1077. }
  1078. if _, ok := ctx.Module().(JniSanitizeable); ok {
  1079. // TODO: this should call into JniSanitizable.IsSanitizerEnabledForJni but
  1080. // that is short-circuited for now
  1081. return []string{""}
  1082. }
  1083. // If an APEX has a sanitized dependency, we build the APEX in the sanitized
  1084. // variation. This is useful because such APEXes require extra dependencies.
  1085. if sanitizeable, ok := ctx.Module().(Sanitizeable); ok {
  1086. enabled := sanitizeable.IsSanitizerEnabled(ctx.Config(), s.sanitizer.name())
  1087. if enabled {
  1088. return []string{s.sanitizer.variationName()}
  1089. } else {
  1090. return []string{""}
  1091. }
  1092. }
  1093. if c, ok := ctx.Module().(*Module); ok {
  1094. //TODO: When Rust modules have vendor support, enable this path for PlatformSanitizeable
  1095. // Check if it's a snapshot module supporting sanitizer
  1096. if ss, ok := c.linker.(snapshotSanitizer); ok {
  1097. if ss.isSanitizerAvailable(s.sanitizer) {
  1098. return []string{"", s.sanitizer.variationName()}
  1099. } else {
  1100. return []string{""}
  1101. }
  1102. }
  1103. }
  1104. return []string{""}
  1105. }
  1106. func (s *sanitizerSplitMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
  1107. if c, ok := ctx.Module().(PlatformSanitizeable); ok {
  1108. if !c.SanitizableDepTagChecker()(ctx.DepTag()) {
  1109. // If the dependency is through a non-sanitizable tag, use the
  1110. // non-sanitized variation
  1111. return ""
  1112. }
  1113. return sourceVariation
  1114. } else if _, ok := ctx.Module().(JniSanitizeable); ok {
  1115. // TODO: this should call into JniSanitizable.IsSanitizerEnabledForJni but
  1116. // that is short-circuited for now
  1117. return ""
  1118. } else {
  1119. // Otherwise, do not rock the boat.
  1120. return sourceVariation
  1121. }
  1122. }
  1123. func (s *sanitizerSplitMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
  1124. if d, ok := ctx.Module().(PlatformSanitizeable); ok {
  1125. if dm, ok := ctx.Module().(*Module); ok {
  1126. if ss, ok := dm.linker.(snapshotSanitizer); ok && ss.isSanitizerAvailable(s.sanitizer) {
  1127. return incomingVariation
  1128. }
  1129. }
  1130. if !d.SanitizePropDefined() ||
  1131. d.SanitizeNever() ||
  1132. d.IsSanitizerExplicitlyDisabled(s.sanitizer) ||
  1133. !d.SanitizerSupported(s.sanitizer) {
  1134. // If a module opts out of a sanitizer, use its non-sanitized variation
  1135. return ""
  1136. }
  1137. // Binaries are always built in the variation they requested.
  1138. if d.Binary() {
  1139. if d.IsSanitizerEnabled(s.sanitizer) {
  1140. return s.sanitizer.variationName()
  1141. } else {
  1142. return ""
  1143. }
  1144. }
  1145. // If a shared library requests to be sanitized, it will be built for that
  1146. // sanitizer. Otherwise, some sanitizers propagate through shared library
  1147. // dependency edges, some do not.
  1148. if !d.StaticallyLinked() && !d.Header() {
  1149. if d.IsSanitizerEnabled(s.sanitizer) {
  1150. return s.sanitizer.variationName()
  1151. }
  1152. // Some sanitizers do not propagate to shared dependencies
  1153. if !s.sanitizer.shouldPropagateToSharedLibraryDeps() {
  1154. return ""
  1155. }
  1156. }
  1157. // Static and header libraries inherit whether they are sanitized from the
  1158. // module they are linked into
  1159. return incomingVariation
  1160. } else if d, ok := ctx.Module().(Sanitizeable); ok {
  1161. // If an APEX contains a sanitized module, it will be built in the variation
  1162. // corresponding to that sanitizer.
  1163. enabled := d.IsSanitizerEnabled(ctx.Config(), s.sanitizer.name())
  1164. if enabled {
  1165. return s.sanitizer.variationName()
  1166. }
  1167. return incomingVariation
  1168. }
  1169. return ""
  1170. }
  1171. func (s *sanitizerSplitMutator) Mutate(mctx android.BottomUpMutatorContext, variationName string) {
  1172. sanitizerVariation := variationName == s.sanitizer.variationName()
  1173. if c, ok := mctx.Module().(PlatformSanitizeable); ok && c.SanitizePropDefined() {
  1174. sanitizerEnabled := c.IsSanitizerEnabled(s.sanitizer)
  1175. oneMakeVariation := false
  1176. if c.StaticallyLinked() || c.Header() {
  1177. if s.sanitizer != cfi && s.sanitizer != scs && s.sanitizer != Hwasan {
  1178. // These sanitizers export only one variation to Make. For the rest,
  1179. // Make targets can depend on both the sanitized and non-sanitized
  1180. // versions.
  1181. oneMakeVariation = true
  1182. }
  1183. } else if !c.Binary() {
  1184. // Shared library. These are the sanitizers that do propagate through shared
  1185. // library dependencies and therefore can cause multiple variations of a
  1186. // shared library to be built.
  1187. if s.sanitizer != cfi && s.sanitizer != Hwasan && s.sanitizer != scs && s.sanitizer != Asan {
  1188. oneMakeVariation = true
  1189. }
  1190. }
  1191. if oneMakeVariation {
  1192. if sanitizerEnabled != sanitizerVariation {
  1193. c.SetPreventInstall()
  1194. c.SetHideFromMake()
  1195. }
  1196. }
  1197. if sanitizerVariation {
  1198. c.SetSanitizer(s.sanitizer, true)
  1199. // CFI is incompatible with ASAN so disable it in ASAN variations
  1200. if s.sanitizer.incompatibleWithCfi() {
  1201. cfiSupported := mctx.Module().(PlatformSanitizeable).SanitizerSupported(cfi)
  1202. if mctx.Device() && cfiSupported {
  1203. c.SetSanitizer(cfi, false)
  1204. }
  1205. }
  1206. // locate the asan libraries under /data/asan
  1207. if !c.Binary() && !c.StaticallyLinked() && !c.Header() && mctx.Device() && s.sanitizer == Asan && sanitizerEnabled {
  1208. c.SetInSanitizerDir()
  1209. }
  1210. if c.StaticallyLinked() && c.ExportedToMake() {
  1211. if s.sanitizer == Hwasan {
  1212. hwasanStaticLibs(mctx.Config()).add(c, c.Module().Name())
  1213. } else if s.sanitizer == cfi {
  1214. cfiStaticLibs(mctx.Config()).add(c, c.Module().Name())
  1215. }
  1216. }
  1217. } else if c.IsSanitizerEnabled(s.sanitizer) {
  1218. // Disable the sanitizer for the non-sanitized variation
  1219. c.SetSanitizer(s.sanitizer, false)
  1220. }
  1221. } else if sanitizeable, ok := mctx.Module().(Sanitizeable); ok {
  1222. // If an APEX has sanitized dependencies, it gets a few more dependencies
  1223. if sanitizerVariation {
  1224. sanitizeable.AddSanitizerDependencies(mctx, s.sanitizer.name())
  1225. }
  1226. } else if c, ok := mctx.Module().(*Module); ok {
  1227. if ss, ok := c.linker.(snapshotSanitizer); ok && ss.isSanitizerAvailable(s.sanitizer) {
  1228. if !ss.isUnsanitizedVariant() {
  1229. // Snapshot sanitizer may have only one variantion.
  1230. // Skip exporting the module if it already has a sanitizer variation.
  1231. c.SetPreventInstall()
  1232. c.SetHideFromMake()
  1233. return
  1234. }
  1235. c.linker.(snapshotSanitizer).setSanitizerVariation(s.sanitizer, sanitizerVariation)
  1236. // Export the static lib name to make
  1237. if c.static() && c.ExportedToMake() {
  1238. // use BaseModuleName which is the name for Make.
  1239. if s.sanitizer == cfi {
  1240. cfiStaticLibs(mctx.Config()).add(c, c.BaseModuleName())
  1241. } else if s.sanitizer == Hwasan {
  1242. hwasanStaticLibs(mctx.Config()).add(c, c.BaseModuleName())
  1243. }
  1244. }
  1245. }
  1246. }
  1247. }
  1248. func (c *Module) SanitizeNever() bool {
  1249. return Bool(c.sanitize.Properties.SanitizeMutated.Never)
  1250. }
  1251. func (c *Module) IsSanitizerExplicitlyDisabled(t SanitizerType) bool {
  1252. return c.sanitize.isSanitizerExplicitlyDisabled(t)
  1253. }
  1254. // Propagate the ubsan minimal runtime dependency when there are integer overflow sanitized static dependencies.
  1255. func sanitizerRuntimeDepsMutator(mctx android.TopDownMutatorContext) {
  1256. // Change this to PlatformSanitizable when/if non-cc modules support ubsan sanitizers.
  1257. if c, ok := mctx.Module().(*Module); ok && c.sanitize != nil {
  1258. isSanitizableDependencyTag := c.SanitizableDepTagChecker()
  1259. mctx.WalkDeps(func(child, parent android.Module) bool {
  1260. if !isSanitizableDependencyTag(mctx.OtherModuleDependencyTag(child)) {
  1261. return false
  1262. }
  1263. d, ok := child.(*Module)
  1264. if !ok || !d.static() {
  1265. return false
  1266. }
  1267. if d.sanitize != nil {
  1268. if enableMinimalRuntime(d.sanitize) {
  1269. // If a static dependency is built with the minimal runtime,
  1270. // make sure we include the ubsan minimal runtime.
  1271. c.sanitize.Properties.MinimalRuntimeDep = true
  1272. } else if enableUbsanRuntime(d.sanitize) {
  1273. // If a static dependency runs with full ubsan diagnostics,
  1274. // make sure we include the ubsan runtime.
  1275. c.sanitize.Properties.UbsanRuntimeDep = true
  1276. }
  1277. if c.sanitize.Properties.MinimalRuntimeDep &&
  1278. c.sanitize.Properties.UbsanRuntimeDep {
  1279. // both flags that this mutator might set are true, so don't bother recursing
  1280. return false
  1281. }
  1282. if c.Os() == android.Linux {
  1283. c.sanitize.Properties.BuiltinsDep = true
  1284. }
  1285. return true
  1286. }
  1287. if p, ok := d.linker.(*snapshotLibraryDecorator); ok {
  1288. if Bool(p.properties.Sanitize_minimal_dep) {
  1289. c.sanitize.Properties.MinimalRuntimeDep = true
  1290. }
  1291. if Bool(p.properties.Sanitize_ubsan_dep) {
  1292. c.sanitize.Properties.UbsanRuntimeDep = true
  1293. }
  1294. }
  1295. return false
  1296. })
  1297. }
  1298. }
  1299. // Add the dependency to the runtime library for each of the sanitizer variants
  1300. func sanitizerRuntimeMutator(mctx android.BottomUpMutatorContext) {
  1301. if c, ok := mctx.Module().(*Module); ok && c.sanitize != nil {
  1302. if !c.Enabled() {
  1303. return
  1304. }
  1305. var sanitizers []string
  1306. var diagSanitizers []string
  1307. sanProps := &c.sanitize.Properties.SanitizeMutated
  1308. if Bool(sanProps.All_undefined) {
  1309. sanitizers = append(sanitizers, "undefined")
  1310. } else {
  1311. if Bool(sanProps.Undefined) {
  1312. sanitizers = append(sanitizers,
  1313. "bool",
  1314. "integer-divide-by-zero",
  1315. "return",
  1316. "returns-nonnull-attribute",
  1317. "shift-exponent",
  1318. "unreachable",
  1319. "vla-bound",
  1320. // TODO(danalbert): The following checks currently have compiler performance issues.
  1321. //"alignment",
  1322. //"bounds",
  1323. //"enum",
  1324. //"float-cast-overflow",
  1325. //"float-divide-by-zero",
  1326. //"nonnull-attribute",
  1327. //"null",
  1328. //"shift-base",
  1329. //"signed-integer-overflow",
  1330. // TODO(danalbert): Fix UB in libc++'s __tree so we can turn this on.
  1331. // https://llvm.org/PR19302
  1332. // http://reviews.llvm.org/D6974
  1333. // "object-size",
  1334. )
  1335. }
  1336. sanitizers = append(sanitizers, sanProps.Misc_undefined...)
  1337. }
  1338. if Bool(sanProps.Diag.Undefined) {
  1339. diagSanitizers = append(diagSanitizers, "undefined")
  1340. }
  1341. diagSanitizers = append(diagSanitizers, sanProps.Diag.Misc_undefined...)
  1342. if Bool(sanProps.Address) {
  1343. sanitizers = append(sanitizers, "address")
  1344. diagSanitizers = append(diagSanitizers, "address")
  1345. }
  1346. if Bool(sanProps.Hwaddress) {
  1347. sanitizers = append(sanitizers, "hwaddress")
  1348. }
  1349. if Bool(sanProps.Thread) {
  1350. sanitizers = append(sanitizers, "thread")
  1351. }
  1352. if Bool(sanProps.Safestack) {
  1353. sanitizers = append(sanitizers, "safe-stack")
  1354. }
  1355. if Bool(sanProps.Cfi) {
  1356. sanitizers = append(sanitizers, "cfi")
  1357. if Bool(sanProps.Diag.Cfi) {
  1358. diagSanitizers = append(diagSanitizers, "cfi")
  1359. }
  1360. }
  1361. if Bool(sanProps.Integer_overflow) {
  1362. sanitizers = append(sanitizers, "unsigned-integer-overflow")
  1363. sanitizers = append(sanitizers, "signed-integer-overflow")
  1364. if Bool(sanProps.Diag.Integer_overflow) {
  1365. diagSanitizers = append(diagSanitizers, "unsigned-integer-overflow")
  1366. diagSanitizers = append(diagSanitizers, "signed-integer-overflow")
  1367. }
  1368. }
  1369. if Bool(sanProps.Scudo) {
  1370. sanitizers = append(sanitizers, "scudo")
  1371. }
  1372. if Bool(sanProps.Scs) {
  1373. sanitizers = append(sanitizers, "shadow-call-stack")
  1374. }
  1375. if Bool(sanProps.Memtag_heap) && c.Binary() {
  1376. sanitizers = append(sanitizers, "memtag-heap")
  1377. }
  1378. if Bool(sanProps.Memtag_stack) {
  1379. sanitizers = append(sanitizers, "memtag-stack")
  1380. }
  1381. if Bool(sanProps.Memtag_globals) {
  1382. sanitizers = append(sanitizers, "memtag-globals")
  1383. // TODO(mitchp): For now, enable memtag-heap with memtag-globals because the linker
  1384. // isn't new enough (https://reviews.llvm.org/differential/changeset/?ref=4243566).
  1385. sanitizers = append(sanitizers, "memtag-heap")
  1386. }
  1387. if Bool(sanProps.Fuzzer) {
  1388. sanitizers = append(sanitizers, "fuzzer-no-link")
  1389. }
  1390. // Save the list of sanitizers. These will be used again when generating
  1391. // the build rules (for Cflags, etc.)
  1392. c.sanitize.Properties.Sanitizers = sanitizers
  1393. c.sanitize.Properties.DiagSanitizers = diagSanitizers
  1394. // TODO(b/150822854) Hosts have a different default behavior and assume the runtime library is used.
  1395. if c.Host() {
  1396. diagSanitizers = sanitizers
  1397. }
  1398. addStaticDeps := func(dep string, hideSymbols bool) {
  1399. // If we're using snapshots, redirect to snapshot whenever possible
  1400. snapshot := mctx.Provider(SnapshotInfoProvider).(SnapshotInfo)
  1401. if lib, ok := snapshot.StaticLibs[dep]; ok {
  1402. dep = lib
  1403. }
  1404. // static executable gets static runtime libs
  1405. depTag := libraryDependencyTag{Kind: staticLibraryDependency, unexportedSymbols: hideSymbols}
  1406. variations := append(mctx.Target().Variations(),
  1407. blueprint.Variation{Mutator: "link", Variation: "static"})
  1408. if c.Device() {
  1409. variations = append(variations, c.ImageVariation())
  1410. }
  1411. if c.UseSdk() {
  1412. variations = append(variations,
  1413. blueprint.Variation{Mutator: "sdk", Variation: "sdk"})
  1414. }
  1415. mctx.AddFarVariationDependencies(variations, depTag, dep)
  1416. }
  1417. // Determine the runtime library required
  1418. runtimeSharedLibrary := ""
  1419. toolchain := c.toolchain(mctx)
  1420. if Bool(sanProps.Address) {
  1421. if toolchain.Musl() || (c.staticBinary() && toolchain.Bionic()) {
  1422. // Use a static runtime for musl to match what clang does for glibc.
  1423. addStaticDeps(config.AddressSanitizerStaticRuntimeLibrary(toolchain), false)
  1424. addStaticDeps(config.AddressSanitizerCXXStaticRuntimeLibrary(toolchain), false)
  1425. } else {
  1426. runtimeSharedLibrary = config.AddressSanitizerRuntimeLibrary(toolchain)
  1427. }
  1428. } else if Bool(sanProps.Hwaddress) {
  1429. if c.staticBinary() {
  1430. addStaticDeps(config.HWAddressSanitizerStaticLibrary(toolchain), true)
  1431. addStaticDeps("libdl", false)
  1432. } else {
  1433. runtimeSharedLibrary = config.HWAddressSanitizerRuntimeLibrary(toolchain)
  1434. }
  1435. } else if Bool(sanProps.Thread) {
  1436. runtimeSharedLibrary = config.ThreadSanitizerRuntimeLibrary(toolchain)
  1437. } else if Bool(sanProps.Scudo) {
  1438. if len(diagSanitizers) == 0 && !c.sanitize.Properties.UbsanRuntimeDep {
  1439. runtimeSharedLibrary = config.ScudoMinimalRuntimeLibrary(toolchain)
  1440. } else {
  1441. runtimeSharedLibrary = config.ScudoRuntimeLibrary(toolchain)
  1442. }
  1443. } else if len(diagSanitizers) > 0 || c.sanitize.Properties.UbsanRuntimeDep ||
  1444. Bool(sanProps.Fuzzer) ||
  1445. Bool(sanProps.Undefined) ||
  1446. Bool(sanProps.All_undefined) {
  1447. if toolchain.Musl() || (c.staticBinary() && toolchain.Bionic()) {
  1448. // Use a static runtime for static binaries.
  1449. // Also use a static runtime for musl to match
  1450. // what clang does for glibc. Otherwise dlopening
  1451. // libraries that depend on libclang_rt.ubsan_standalone.so
  1452. // fails with:
  1453. // Error relocating ...: initial-exec TLS resolves to dynamic definition
  1454. addStaticDeps(config.UndefinedBehaviorSanitizerRuntimeLibrary(toolchain)+".static", true)
  1455. } else {
  1456. runtimeSharedLibrary = config.UndefinedBehaviorSanitizerRuntimeLibrary(toolchain)
  1457. }
  1458. }
  1459. if enableMinimalRuntime(c.sanitize) || c.sanitize.Properties.MinimalRuntimeDep {
  1460. addStaticDeps(config.UndefinedBehaviorSanitizerMinimalRuntimeLibrary(toolchain), true)
  1461. }
  1462. if c.sanitize.Properties.BuiltinsDep {
  1463. addStaticDeps(config.BuiltinsRuntimeLibrary(toolchain), true)
  1464. }
  1465. if runtimeSharedLibrary != "" && (toolchain.Bionic() || toolchain.Musl() || c.sanitize.Properties.UbsanRuntimeDep) {
  1466. // UBSan is supported on non-bionic linux host builds as well
  1467. // Adding dependency to the runtime library. We are using *FarVariation*
  1468. // because the runtime libraries themselves are not mutated by sanitizer
  1469. // mutators and thus don't have sanitizer variants whereas this module
  1470. // has been already mutated.
  1471. //
  1472. // Note that by adding dependency with {static|shared}DepTag, the lib is
  1473. // added to libFlags and LOCAL_SHARED_LIBRARIES by cc.Module
  1474. if c.staticBinary() {
  1475. // Most sanitizers are either disabled for static binaries or have already
  1476. // handled the static binary case above through a direct call to addStaticDeps.
  1477. // If not, treat the runtime shared library as a static library and hope for
  1478. // the best.
  1479. addStaticDeps(runtimeSharedLibrary, true)
  1480. } else if !c.static() && !c.Header() {
  1481. // If we're using snapshots, redirect to snapshot whenever possible
  1482. snapshot := mctx.Provider(SnapshotInfoProvider).(SnapshotInfo)
  1483. if lib, ok := snapshot.SharedLibs[runtimeSharedLibrary]; ok {
  1484. runtimeSharedLibrary = lib
  1485. }
  1486. // Skip apex dependency check for sharedLibraryDependency
  1487. // when sanitizer diags are enabled. Skipping the check will allow
  1488. // building with diag libraries without having to list the
  1489. // dependency in Apex's allowed_deps file.
  1490. diagEnabled := len(diagSanitizers) > 0
  1491. // dynamic executable and shared libs get shared runtime libs
  1492. depTag := libraryDependencyTag{
  1493. Kind: sharedLibraryDependency,
  1494. Order: earlyLibraryDependency,
  1495. skipApexAllowedDependenciesCheck: diagEnabled,
  1496. }
  1497. variations := append(mctx.Target().Variations(),
  1498. blueprint.Variation{Mutator: "link", Variation: "shared"})
  1499. if c.Device() {
  1500. variations = append(variations, c.ImageVariation())
  1501. }
  1502. if c.UseSdk() {
  1503. variations = append(variations,
  1504. blueprint.Variation{Mutator: "sdk", Variation: "sdk"})
  1505. }
  1506. AddSharedLibDependenciesWithVersions(mctx, c, variations, depTag, runtimeSharedLibrary, "", true)
  1507. }
  1508. // static lib does not have dependency to the runtime library. The
  1509. // dependency will be added to the executables or shared libs using
  1510. // the static lib.
  1511. }
  1512. }
  1513. }
  1514. type Sanitizeable interface {
  1515. android.Module
  1516. IsSanitizerEnabled(config android.Config, sanitizerName string) bool
  1517. EnableSanitizer(sanitizerName string)
  1518. AddSanitizerDependencies(ctx android.BottomUpMutatorContext, sanitizerName string)
  1519. }
  1520. type JniSanitizeable interface {
  1521. android.Module
  1522. IsSanitizerEnabledForJni(ctx android.BaseModuleContext, sanitizerName string) bool
  1523. }
  1524. func (c *Module) MinimalRuntimeDep() bool {
  1525. return c.sanitize.Properties.MinimalRuntimeDep
  1526. }
  1527. func (c *Module) UbsanRuntimeDep() bool {
  1528. return c.sanitize.Properties.UbsanRuntimeDep
  1529. }
  1530. func (c *Module) SanitizePropDefined() bool {
  1531. return c.sanitize != nil
  1532. }
  1533. func (c *Module) IsSanitizerEnabled(t SanitizerType) bool {
  1534. return c.sanitize.isSanitizerEnabled(t)
  1535. }
  1536. func (c *Module) StaticallyLinked() bool {
  1537. return c.static()
  1538. }
  1539. func (c *Module) SetInSanitizerDir() {
  1540. if c.sanitize != nil {
  1541. c.sanitize.Properties.InSanitizerDir = true
  1542. }
  1543. }
  1544. func (c *Module) SetSanitizer(t SanitizerType, b bool) {
  1545. if c.sanitize != nil {
  1546. c.sanitize.SetSanitizer(t, b)
  1547. }
  1548. }
  1549. var _ PlatformSanitizeable = (*Module)(nil)
  1550. type sanitizerStaticLibsMap struct {
  1551. // libsMap contains one list of modules per each image and each arch.
  1552. // e.g. libs[vendor]["arm"] contains arm modules installed to vendor
  1553. libsMap map[ImageVariantType]map[string][]string
  1554. libsMapLock sync.Mutex
  1555. sanitizerType SanitizerType
  1556. }
  1557. func newSanitizerStaticLibsMap(t SanitizerType) *sanitizerStaticLibsMap {
  1558. return &sanitizerStaticLibsMap{
  1559. sanitizerType: t,
  1560. libsMap: make(map[ImageVariantType]map[string][]string),
  1561. }
  1562. }
  1563. // Add the current module to sanitizer static libs maps
  1564. // Each module should pass its exported name as names of Make and Soong can differ.
  1565. func (s *sanitizerStaticLibsMap) add(c LinkableInterface, name string) {
  1566. image := GetImageVariantType(c)
  1567. arch := c.Module().Target().Arch.ArchType.String()
  1568. s.libsMapLock.Lock()
  1569. defer s.libsMapLock.Unlock()
  1570. if _, ok := s.libsMap[image]; !ok {
  1571. s.libsMap[image] = make(map[string][]string)
  1572. }
  1573. s.libsMap[image][arch] = append(s.libsMap[image][arch], name)
  1574. }
  1575. // Exports makefile variables in the following format:
  1576. // SOONG_{sanitizer}_{image}_{arch}_STATIC_LIBRARIES
  1577. // e.g. SOONG_cfi_core_x86_STATIC_LIBRARIES
  1578. // These are to be used by use_soong_sanitized_static_libraries.
  1579. // See build/make/core/binary.mk for more details.
  1580. func (s *sanitizerStaticLibsMap) exportToMake(ctx android.MakeVarsContext) {
  1581. for _, image := range android.SortedKeys(s.libsMap) {
  1582. archMap := s.libsMap[ImageVariantType(image)]
  1583. for _, arch := range android.SortedKeys(archMap) {
  1584. libs := archMap[arch]
  1585. sort.Strings(libs)
  1586. key := fmt.Sprintf(
  1587. "SOONG_%s_%s_%s_STATIC_LIBRARIES",
  1588. s.sanitizerType.variationName(),
  1589. image, // already upper
  1590. arch)
  1591. ctx.Strict(key, strings.Join(libs, " "))
  1592. }
  1593. }
  1594. }
  1595. var cfiStaticLibsKey = android.NewOnceKey("cfiStaticLibs")
  1596. func cfiStaticLibs(config android.Config) *sanitizerStaticLibsMap {
  1597. return config.Once(cfiStaticLibsKey, func() interface{} {
  1598. return newSanitizerStaticLibsMap(cfi)
  1599. }).(*sanitizerStaticLibsMap)
  1600. }
  1601. var hwasanStaticLibsKey = android.NewOnceKey("hwasanStaticLibs")
  1602. func hwasanStaticLibs(config android.Config) *sanitizerStaticLibsMap {
  1603. return config.Once(hwasanStaticLibsKey, func() interface{} {
  1604. return newSanitizerStaticLibsMap(Hwasan)
  1605. }).(*sanitizerStaticLibsMap)
  1606. }
  1607. func enableMinimalRuntime(sanitize *sanitize) bool {
  1608. if sanitize.isSanitizerEnabled(Asan) {
  1609. return false
  1610. } else if sanitize.isSanitizerEnabled(Hwasan) {
  1611. return false
  1612. } else if sanitize.isSanitizerEnabled(Fuzzer) {
  1613. return false
  1614. }
  1615. if enableUbsanRuntime(sanitize) {
  1616. return false
  1617. }
  1618. sanitizeProps := &sanitize.Properties.SanitizeMutated
  1619. if Bool(sanitizeProps.Diag.Cfi) {
  1620. return false
  1621. }
  1622. return Bool(sanitizeProps.Integer_overflow) ||
  1623. len(sanitizeProps.Misc_undefined) > 0 ||
  1624. Bool(sanitizeProps.Undefined) ||
  1625. Bool(sanitizeProps.All_undefined)
  1626. }
  1627. func (m *Module) UbsanRuntimeNeeded() bool {
  1628. return enableUbsanRuntime(m.sanitize)
  1629. }
  1630. func (m *Module) MinimalRuntimeNeeded() bool {
  1631. return enableMinimalRuntime(m.sanitize)
  1632. }
  1633. func enableUbsanRuntime(sanitize *sanitize) bool {
  1634. sanitizeProps := &sanitize.Properties.SanitizeMutated
  1635. return Bool(sanitizeProps.Diag.Integer_overflow) ||
  1636. Bool(sanitizeProps.Diag.Undefined) ||
  1637. len(sanitizeProps.Diag.Misc_undefined) > 0
  1638. }
  1639. func cfiMakeVarsProvider(ctx android.MakeVarsContext) {
  1640. cfiStaticLibs(ctx.Config()).exportToMake(ctx)
  1641. }
  1642. func hwasanMakeVarsProvider(ctx android.MakeVarsContext) {
  1643. hwasanStaticLibs(ctx.Config()).exportToMake(ctx)
  1644. }
  1645. func BazelCcSanitizerToolchainVars(config android.Config) string {
  1646. return android.BazelToolchainVars(config, exportedVars)
  1647. }