Add minimal-runtime support for integer overflows.

Adds Soong support for -fsanitze-minimal-runtime when using
the integer overflow sanitizers. This makes the crashes due to these
sanitizers less mysterious.

Bug: 64091660
Test: Compiled and checked the generated compiler commands
Test: Checked program that overflows for the abort reason

Change-Id: Ieeceaf6c35c8371592952d3b8b977aefc11601c5
Merged-In: Ieeceaf6c35c8371592952d3b8b977aefc11601c5
(cherry picked from commit 30c5db2f47)
This commit is contained in:
Ivan Lozano
2018-02-21 15:49:20 -08:00
parent 0a7d85a896
commit 954f430e97
4 changed files with 54 additions and 4 deletions

View File

@@ -42,7 +42,8 @@ var (
cfiExportsMap android.Path
cfiStaticLibsMutex sync.Mutex
intOverflowCflags = []string{"-fsanitize-blacklist=build/soong/cc/config/integer_overflow_blacklist.txt"}
intOverflowCflags = []string{"-fsanitize-blacklist=build/soong/cc/config/integer_overflow_blacklist.txt"}
minimalRuntimeFlags = []string{"-fsanitize-minimal-runtime", "-fno-sanitize-trap=integer", "-fno-sanitize-recover=integer"}
)
type sanitizerType int
@@ -112,9 +113,10 @@ type SanitizeProperties struct {
Blacklist *string
} `android:"arch_variant"`
SanitizerEnabled bool `blueprint:"mutated"`
SanitizeDep bool `blueprint:"mutated"`
InSanitizerDir bool `blueprint:"mutated"`
SanitizerEnabled bool `blueprint:"mutated"`
SanitizeDep bool `blueprint:"mutated"`
MinimalRuntimeDep bool `blueprint:"mutated"`
InSanitizerDir bool `blueprint:"mutated"`
}
type sanitize struct {
@@ -301,6 +303,11 @@ func (sanitize *sanitize) deps(ctx BaseModuleContext, deps Deps) Deps {
}
func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags) Flags {
minimalRuntimePath := "${config.ClangAsanLibDir}/" + config.UndefinedBehaviorSanitizerMinimalRuntimeLibrary(ctx.toolchain()) + ".a"
if ctx.Device() && sanitize.Properties.MinimalRuntimeDep {
flags.LdFlags = append(flags.LdFlags, minimalRuntimePath)
}
if !sanitize.Properties.SanitizerEnabled {
return flags
}
@@ -431,6 +438,7 @@ func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags) Flags {
if len(sanitizers) > 0 {
sanitizeArg := "-fsanitize=" + strings.Join(sanitizers, ",")
flags.CFlags = append(flags.CFlags, sanitizeArg)
if ctx.Host() {
flags.CFlags = append(flags.CFlags, "-fno-sanitize-recover=all")
@@ -440,6 +448,11 @@ func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags) Flags {
_, flags.LdFlags = removeFromList("-Wl,--no-undefined", flags.LdFlags)
} else {
flags.CFlags = append(flags.CFlags, "-fsanitize-trap=all", "-ftrap-function=abort")
if enableMinimalRuntime(sanitize) {
flags.CFlags = append(flags.CFlags, strings.Join(minimalRuntimeFlags, " "))
flags.libFlags = append([]string{minimalRuntimePath}, flags.libFlags...)
}
}
}
@@ -589,6 +602,24 @@ func sanitizerDepsMutator(t sanitizerType) func(android.TopDownMutatorContext) {
}
}
// Propagate the ubsan minimal runtime dependency when there are integer overflow sanitized static dependencies.
func minimalRuntimeDepsMutator() func(android.TopDownMutatorContext) {
return func(mctx android.TopDownMutatorContext) {
if c, ok := mctx.Module().(*Module); ok && c.sanitize != nil {
mctx.VisitDepsDepthFirst(func(module android.Module) {
if d, ok := module.(*Module); ok && d.static() && d.sanitize != nil {
// If a static dependency will be built with the minimal runtime,
// make sure we include the ubsan minimal runtime.
if enableMinimalRuntime(d.sanitize) {
c.sanitize.Properties.MinimalRuntimeDep = true
}
}
})
}
}
}
// Create sanitized variants for modules that need them
func sanitizerMutator(t sanitizerType) func(android.BottomUpMutatorContext) {
return func(mctx android.BottomUpMutatorContext) {
@@ -659,6 +690,18 @@ func cfiStaticLibs(config android.Config) *[]string {
}).(*[]string)
}
func enableMinimalRuntime(sanitize *sanitize) bool {
if !Bool(sanitize.Properties.Sanitize.Address) &&
(Bool(sanitize.Properties.Sanitize.Integer_overflow) ||
len(sanitize.Properties.Sanitize.Misc_undefined) > 0) &&
!(Bool(sanitize.Properties.Sanitize.Diag.Integer_overflow) ||
Bool(sanitize.Properties.Sanitize.Diag.Cfi) ||
len(sanitize.Properties.Sanitize.Diag.Misc_undefined) > 0) {
return true
}
return false
}
func cfiMakeVarsProvider(ctx android.MakeVarsContext) {
cfiStaticLibs := cfiStaticLibs(ctx.Config())
sort.Strings(*cfiStaticLibs)