Target sanitize properties can disable the global sanitizer.
With this change, sanitize: { address: false } disables SANITIZE_TARGET=address for one target. Also rename SafeStack to Safestack, because the former can not be used as a target property. Bug: 27729263 Change-Id: I20f55c0e62b2fdd191ba66c0f661a039109bd78f
This commit is contained in:
127
cc/sanitize.go
127
cc/sanitize.go
@@ -25,6 +25,14 @@ import (
|
|||||||
|
|
||||||
type sanitizerType int
|
type sanitizerType int
|
||||||
|
|
||||||
|
func boolPtr(v bool) *bool {
|
||||||
|
if v {
|
||||||
|
return &v
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
pctx.StaticVariable("clangAsanLibDir", "${clangPath}/lib64/clang/3.8/lib/linux")
|
pctx.StaticVariable("clangAsanLibDir", "${clangPath}/lib64/clang/3.8/lib/linux")
|
||||||
}
|
}
|
||||||
@@ -51,15 +59,15 @@ type SanitizeProperties struct {
|
|||||||
Never bool `android:"arch_variant"`
|
Never bool `android:"arch_variant"`
|
||||||
|
|
||||||
// main sanitizers
|
// main sanitizers
|
||||||
Address bool `android:"arch_variant"`
|
Address *bool `android:"arch_variant"`
|
||||||
Thread bool `android:"arch_variant"`
|
Thread *bool `android:"arch_variant"`
|
||||||
|
|
||||||
// local sanitizers
|
// local sanitizers
|
||||||
Undefined bool `android:"arch_variant"`
|
Undefined *bool `android:"arch_variant"`
|
||||||
All_undefined bool `android:"arch_variant"`
|
All_undefined *bool `android:"arch_variant"`
|
||||||
Misc_undefined []string `android:"arch_variant"`
|
Misc_undefined []string `android:"arch_variant"`
|
||||||
Coverage bool `android:"arch_variant"`
|
Coverage *bool `android:"arch_variant"`
|
||||||
SafeStack bool `android:"arch_variant"`
|
Safestack *bool `android:"arch_variant"`
|
||||||
|
|
||||||
// value to pass to -fsantitize-recover=
|
// value to pass to -fsantitize-recover=
|
||||||
Recover []string
|
Recover []string
|
||||||
@@ -82,20 +90,18 @@ func (sanitize *sanitize) props() []interface{} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (sanitize *sanitize) begin(ctx BaseModuleContext) {
|
func (sanitize *sanitize) begin(ctx BaseModuleContext) {
|
||||||
|
s := &sanitize.Properties.Sanitize
|
||||||
|
|
||||||
// Don't apply sanitizers to NDK code.
|
// Don't apply sanitizers to NDK code.
|
||||||
if ctx.sdk() {
|
if ctx.sdk() {
|
||||||
sanitize.Properties.Sanitize.Never = true
|
s.Never = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Never always wins.
|
// Never always wins.
|
||||||
if sanitize.Properties.Sanitize.Never {
|
if s.Never {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.ContainsProperty("sanitize") {
|
|
||||||
sanitize.Properties.SanitizerEnabled = true
|
|
||||||
}
|
|
||||||
|
|
||||||
var globalSanitizers []string
|
var globalSanitizers []string
|
||||||
if ctx.clang() {
|
if ctx.clang() {
|
||||||
if ctx.Host() {
|
if ctx.Host() {
|
||||||
@@ -105,48 +111,59 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The sanitizer specified by the environment wins over the module.
|
var found bool
|
||||||
|
if s.All_undefined == nil {
|
||||||
|
found, globalSanitizers = removeFromList("undefined", globalSanitizers)
|
||||||
|
s.All_undefined = boolPtr(found)
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.Undefined == nil {
|
||||||
|
found, globalSanitizers = removeFromList("default-ub", globalSanitizers)
|
||||||
|
s.Undefined = boolPtr(found)
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.Address == nil {
|
||||||
|
found, globalSanitizers = removeFromList("address", globalSanitizers)
|
||||||
|
s.Address = boolPtr(found)
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.Thread == nil {
|
||||||
|
found, globalSanitizers = removeFromList("thread", globalSanitizers)
|
||||||
|
s.Thread = boolPtr(found)
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.Coverage == nil {
|
||||||
|
found, globalSanitizers = removeFromList("coverage", globalSanitizers)
|
||||||
|
s.Coverage = boolPtr(found)
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.Safestack == nil {
|
||||||
|
found, globalSanitizers = removeFromList("safe-stack", globalSanitizers)
|
||||||
|
s.Safestack = boolPtr(found)
|
||||||
|
}
|
||||||
|
|
||||||
if len(globalSanitizers) > 0 {
|
if len(globalSanitizers) > 0 {
|
||||||
// wipe the enabled sanitizers
|
ctx.ModuleErrorf("unknown global sanitizer option %s", globalSanitizers[0])
|
||||||
sanitize.Properties = SanitizeProperties{}
|
}
|
||||||
var found bool
|
|
||||||
if found, globalSanitizers = removeFromList("undefined", globalSanitizers); found {
|
|
||||||
sanitize.Properties.Sanitize.All_undefined = true
|
|
||||||
} else if found, globalSanitizers = removeFromList("default-ub", globalSanitizers); found {
|
|
||||||
sanitize.Properties.Sanitize.Undefined = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if found, globalSanitizers = removeFromList("address", globalSanitizers); found {
|
if Bool(s.All_undefined) || Bool(s.Undefined) || Bool(s.Address) ||
|
||||||
sanitize.Properties.Sanitize.Address = true
|
Bool(s.Thread) || Bool(s.Coverage) || Bool(s.Safestack) {
|
||||||
}
|
|
||||||
|
|
||||||
if found, globalSanitizers = removeFromList("thread", globalSanitizers); found {
|
|
||||||
sanitize.Properties.Sanitize.Thread = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if found, globalSanitizers = removeFromList("coverage", globalSanitizers); found {
|
|
||||||
sanitize.Properties.Sanitize.Coverage = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if found, globalSanitizers = removeFromList("safe-stack", globalSanitizers); found {
|
|
||||||
sanitize.Properties.Sanitize.SafeStack = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(globalSanitizers) > 0 {
|
|
||||||
ctx.ModuleErrorf("unknown global sanitizer option %s", globalSanitizers[0])
|
|
||||||
}
|
|
||||||
sanitize.Properties.SanitizerEnabled = true
|
sanitize.Properties.SanitizerEnabled = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if Bool(s.All_undefined) {
|
||||||
|
s.Undefined = nil
|
||||||
|
}
|
||||||
|
|
||||||
if !ctx.toolchain().Is64Bit() {
|
if !ctx.toolchain().Is64Bit() {
|
||||||
// TSAN and SafeStack are not supported on 32-bit architectures
|
// TSAN and SafeStack are not supported on 32-bit architectures
|
||||||
sanitize.Properties.Sanitize.Thread = false
|
s.Thread = nil
|
||||||
sanitize.Properties.Sanitize.SafeStack = false
|
s.Safestack = nil
|
||||||
// TODO(ccross): error for compile_multilib = "32"?
|
// TODO(ccross): error for compile_multilib = "32"?
|
||||||
}
|
}
|
||||||
|
|
||||||
if sanitize.Properties.Sanitize.Coverage {
|
if Bool(s.Coverage) {
|
||||||
if !sanitize.Properties.Sanitize.Address {
|
if !Bool(s.Address) {
|
||||||
ctx.ModuleErrorf(`Use of "coverage" also requires "address"`)
|
ctx.ModuleErrorf(`Use of "coverage" also requires "address"`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -159,7 +176,7 @@ func (sanitize *sanitize) deps(ctx BaseModuleContext, deps Deps) Deps {
|
|||||||
|
|
||||||
if ctx.Device() {
|
if ctx.Device() {
|
||||||
deps.SharedLibs = append(deps.SharedLibs, "libdl")
|
deps.SharedLibs = append(deps.SharedLibs, "libdl")
|
||||||
if sanitize.Properties.Sanitize.Address {
|
if Bool(sanitize.Properties.Sanitize.Address) {
|
||||||
deps.StaticLibs = append(deps.StaticLibs, "libasan")
|
deps.StaticLibs = append(deps.StaticLibs, "libasan")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -178,13 +195,13 @@ func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags) Flags {
|
|||||||
|
|
||||||
var sanitizers []string
|
var sanitizers []string
|
||||||
|
|
||||||
if sanitize.Properties.Sanitize.All_undefined {
|
if Bool(sanitize.Properties.Sanitize.All_undefined) {
|
||||||
sanitizers = append(sanitizers, "undefined")
|
sanitizers = append(sanitizers, "undefined")
|
||||||
if ctx.Device() {
|
if ctx.Device() {
|
||||||
ctx.ModuleErrorf("ubsan is not yet supported on the device")
|
ctx.ModuleErrorf("ubsan is not yet supported on the device")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if sanitize.Properties.Sanitize.Undefined {
|
if Bool(sanitize.Properties.Sanitize.Undefined) {
|
||||||
sanitizers = append(sanitizers,
|
sanitizers = append(sanitizers,
|
||||||
"bool",
|
"bool",
|
||||||
"integer-divide-by-zero",
|
"integer-divide-by-zero",
|
||||||
@@ -212,7 +229,7 @@ func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags) Flags {
|
|||||||
sanitizers = append(sanitizers, sanitize.Properties.Sanitize.Misc_undefined...)
|
sanitizers = append(sanitizers, sanitize.Properties.Sanitize.Misc_undefined...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if sanitize.Properties.Sanitize.Address {
|
if Bool(sanitize.Properties.Sanitize.Address) {
|
||||||
if ctx.Arch().ArchType == android.Arm {
|
if ctx.Arch().ArchType == android.Arm {
|
||||||
// Frame pointer based unwinder in ASan requires ARM frame setup.
|
// Frame pointer based unwinder in ASan requires ARM frame setup.
|
||||||
// TODO: put in flags?
|
// TODO: put in flags?
|
||||||
@@ -241,11 +258,11 @@ func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags) Flags {
|
|||||||
sanitizers = append(sanitizers, "address")
|
sanitizers = append(sanitizers, "address")
|
||||||
}
|
}
|
||||||
|
|
||||||
if sanitize.Properties.Sanitize.Coverage {
|
if Bool(sanitize.Properties.Sanitize.Coverage) {
|
||||||
flags.CFlags = append(flags.CFlags, "-fsanitize-coverage=edge,indirect-calls,8bit-counters,trace-cmp")
|
flags.CFlags = append(flags.CFlags, "-fsanitize-coverage=edge,indirect-calls,8bit-counters,trace-cmp")
|
||||||
}
|
}
|
||||||
|
|
||||||
if sanitize.Properties.Sanitize.SafeStack {
|
if Bool(sanitize.Properties.Sanitize.Safestack) {
|
||||||
sanitizers = append(sanitizers, "safe-stack")
|
sanitizers = append(sanitizers, "safe-stack")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,7 +279,7 @@ func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags) Flags {
|
|||||||
flags.LdFlags = append(flags.LdFlags, sanitizeArg)
|
flags.LdFlags = append(flags.LdFlags, sanitizeArg)
|
||||||
flags.LdFlags = append(flags.LdFlags, "-lrt", "-ldl")
|
flags.LdFlags = append(flags.LdFlags, "-lrt", "-ldl")
|
||||||
} else {
|
} else {
|
||||||
if !sanitize.Properties.Sanitize.Address {
|
if !Bool(sanitize.Properties.Sanitize.Address) {
|
||||||
flags.CFlags = append(flags.CFlags, "-fsanitize-trap=all", "-ftrap-function=abort")
|
flags.CFlags = append(flags.CFlags, "-fsanitize-trap=all", "-ftrap-function=abort")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -288,9 +305,9 @@ func (sanitize *sanitize) Sanitizer(t sanitizerType) bool {
|
|||||||
|
|
||||||
switch t {
|
switch t {
|
||||||
case asan:
|
case asan:
|
||||||
return sanitize.Properties.Sanitize.Address
|
return Bool(sanitize.Properties.Sanitize.Address)
|
||||||
case tsan:
|
case tsan:
|
||||||
return sanitize.Properties.Sanitize.Thread
|
return Bool(sanitize.Properties.Sanitize.Thread)
|
||||||
default:
|
default:
|
||||||
panic(fmt.Errorf("unknown sanitizerType %d", t))
|
panic(fmt.Errorf("unknown sanitizerType %d", t))
|
||||||
}
|
}
|
||||||
@@ -299,9 +316,9 @@ func (sanitize *sanitize) Sanitizer(t sanitizerType) bool {
|
|||||||
func (sanitize *sanitize) SetSanitizer(t sanitizerType, b bool) {
|
func (sanitize *sanitize) SetSanitizer(t sanitizerType, b bool) {
|
||||||
switch t {
|
switch t {
|
||||||
case asan:
|
case asan:
|
||||||
sanitize.Properties.Sanitize.Address = b
|
sanitize.Properties.Sanitize.Address = boolPtr(b)
|
||||||
case tsan:
|
case tsan:
|
||||||
sanitize.Properties.Sanitize.Thread = b
|
sanitize.Properties.Sanitize.Thread = boolPtr(b)
|
||||||
default:
|
default:
|
||||||
panic(fmt.Errorf("unknown sanitizerType %d", t))
|
panic(fmt.Errorf("unknown sanitizerType %d", t))
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user