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
This commit is contained in:
parent
d4bc55624a
commit
30c5db2f47
2
cc/cc.go
2
cc/cc.go
|
@ -52,6 +52,8 @@ func init() {
|
||||||
ctx.TopDown("tsan_deps", sanitizerDepsMutator(tsan))
|
ctx.TopDown("tsan_deps", sanitizerDepsMutator(tsan))
|
||||||
ctx.BottomUp("tsan", sanitizerMutator(tsan)).Parallel()
|
ctx.BottomUp("tsan", sanitizerMutator(tsan)).Parallel()
|
||||||
|
|
||||||
|
ctx.TopDown("minimal_runtime_deps", minimalRuntimeDepsMutator())
|
||||||
|
|
||||||
ctx.BottomUp("coverage", coverageLinkingMutator).Parallel()
|
ctx.BottomUp("coverage", coverageLinkingMutator).Parallel()
|
||||||
ctx.TopDown("vndk_deps", sabiDepsMutator)
|
ctx.TopDown("vndk_deps", sabiDepsMutator)
|
||||||
|
|
||||||
|
|
|
@ -215,6 +215,10 @@ func UndefinedBehaviorSanitizerRuntimeLibrary(t Toolchain) string {
|
||||||
return SanitizerRuntimeLibrary(t, "ubsan_standalone")
|
return SanitizerRuntimeLibrary(t, "ubsan_standalone")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func UndefinedBehaviorSanitizerMinimalRuntimeLibrary(t Toolchain) string {
|
||||||
|
return SanitizerRuntimeLibrary(t, "ubsan_minimal")
|
||||||
|
}
|
||||||
|
|
||||||
func ThreadSanitizerRuntimeLibrary(t Toolchain) string {
|
func ThreadSanitizerRuntimeLibrary(t Toolchain) string {
|
||||||
return SanitizerRuntimeLibrary(t, "tsan")
|
return SanitizerRuntimeLibrary(t, "tsan")
|
||||||
}
|
}
|
||||||
|
|
|
@ -276,6 +276,7 @@ func makeVarsToolchain(ctx android.MakeVarsContext, secondPrefix string,
|
||||||
if target.Os.Class == android.Device {
|
if target.Os.Class == android.Device {
|
||||||
ctx.Strict(secondPrefix+"ADDRESS_SANITIZER_RUNTIME_LIBRARY", strings.TrimSuffix(config.AddressSanitizerRuntimeLibrary(toolchain), ".so"))
|
ctx.Strict(secondPrefix+"ADDRESS_SANITIZER_RUNTIME_LIBRARY", strings.TrimSuffix(config.AddressSanitizerRuntimeLibrary(toolchain), ".so"))
|
||||||
ctx.Strict(secondPrefix+"UBSAN_RUNTIME_LIBRARY", strings.TrimSuffix(config.UndefinedBehaviorSanitizerRuntimeLibrary(toolchain), ".so"))
|
ctx.Strict(secondPrefix+"UBSAN_RUNTIME_LIBRARY", strings.TrimSuffix(config.UndefinedBehaviorSanitizerRuntimeLibrary(toolchain), ".so"))
|
||||||
|
ctx.Strict(secondPrefix+"UBSAN_MINIMAL_RUNTIME_LIBRARY", strings.TrimSuffix(config.UndefinedBehaviorSanitizerMinimalRuntimeLibrary(toolchain), ".a"))
|
||||||
ctx.Strict(secondPrefix+"TSAN_RUNTIME_LIBRARY", strings.TrimSuffix(config.ThreadSanitizerRuntimeLibrary(toolchain), ".so"))
|
ctx.Strict(secondPrefix+"TSAN_RUNTIME_LIBRARY", strings.TrimSuffix(config.ThreadSanitizerRuntimeLibrary(toolchain), ".so"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,8 @@ var (
|
||||||
cfiExportsMap android.Path
|
cfiExportsMap android.Path
|
||||||
cfiStaticLibsMutex sync.Mutex
|
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
|
type sanitizerType int
|
||||||
|
@ -112,9 +113,10 @@ type SanitizeProperties struct {
|
||||||
Blacklist *string
|
Blacklist *string
|
||||||
} `android:"arch_variant"`
|
} `android:"arch_variant"`
|
||||||
|
|
||||||
SanitizerEnabled bool `blueprint:"mutated"`
|
SanitizerEnabled bool `blueprint:"mutated"`
|
||||||
SanitizeDep bool `blueprint:"mutated"`
|
SanitizeDep bool `blueprint:"mutated"`
|
||||||
InSanitizerDir bool `blueprint:"mutated"`
|
MinimalRuntimeDep bool `blueprint:"mutated"`
|
||||||
|
InSanitizerDir bool `blueprint:"mutated"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type sanitize struct {
|
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 {
|
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 {
|
if !sanitize.Properties.SanitizerEnabled {
|
||||||
return flags
|
return flags
|
||||||
}
|
}
|
||||||
|
@ -431,6 +438,7 @@ func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags) Flags {
|
||||||
|
|
||||||
if len(sanitizers) > 0 {
|
if len(sanitizers) > 0 {
|
||||||
sanitizeArg := "-fsanitize=" + strings.Join(sanitizers, ",")
|
sanitizeArg := "-fsanitize=" + strings.Join(sanitizers, ",")
|
||||||
|
|
||||||
flags.CFlags = append(flags.CFlags, sanitizeArg)
|
flags.CFlags = append(flags.CFlags, sanitizeArg)
|
||||||
if ctx.Host() {
|
if ctx.Host() {
|
||||||
flags.CFlags = append(flags.CFlags, "-fno-sanitize-recover=all")
|
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)
|
_, flags.LdFlags = removeFromList("-Wl,--no-undefined", flags.LdFlags)
|
||||||
} else {
|
} else {
|
||||||
flags.CFlags = append(flags.CFlags, "-fsanitize-trap=all", "-ftrap-function=abort")
|
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
|
// Create sanitized variants for modules that need them
|
||||||
func sanitizerMutator(t sanitizerType) func(android.BottomUpMutatorContext) {
|
func sanitizerMutator(t sanitizerType) func(android.BottomUpMutatorContext) {
|
||||||
return func(mctx android.BottomUpMutatorContext) {
|
return func(mctx android.BottomUpMutatorContext) {
|
||||||
|
@ -659,6 +690,18 @@ func cfiStaticLibs(config android.Config) *[]string {
|
||||||
}).(*[]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) {
|
func cfiMakeVarsProvider(ctx android.MakeVarsContext) {
|
||||||
cfiStaticLibs := cfiStaticLibs(ctx.Config())
|
cfiStaticLibs := cfiStaticLibs(ctx.Config())
|
||||||
sort.Strings(*cfiStaticLibs)
|
sort.Strings(*cfiStaticLibs)
|
||||||
|
|
Loading…
Reference in New Issue