Support integer_overflow static lib diagnostics.
This extends the minimal runtime dependency mutator to allow signed and unsigned integer overflow diagnostics in static libraries and binaries. This also enables the integer_overflow flag for static libraries and binaries. Note compilation will fail if the static library is a dependency of a Make module that does not also have diagnostics enabled. Bug: 66952339 Bug: 73283972 Test: make SANITIZE_TARGET{,_DIAG}=integer_overflow Test: Enabled diagnostics in a static lib, saw results in logcat. Test: Checked showcommands output for ubsan runtime library inclusion. Change-Id: Ic52881a0f74cdcac0e4a15335df493b59b002ae5
This commit is contained in:
parent
d3c59a2b3a
commit
a9255a8378
2 changed files with 35 additions and 20 deletions
2
cc/cc.go
2
cc/cc.go
|
@ -52,7 +52,7 @@ func init() {
|
|||
ctx.TopDown("tsan_deps", sanitizerDepsMutator(tsan))
|
||||
ctx.BottomUp("tsan", sanitizerMutator(tsan)).Parallel()
|
||||
|
||||
ctx.TopDown("minimal_runtime_deps", minimalRuntimeDepsMutator())
|
||||
ctx.TopDown("sanitize_runtime_deps", sanitizerRuntimeDepsMutator())
|
||||
|
||||
ctx.BottomUp("coverage", coverageLinkingMutator).Parallel()
|
||||
ctx.TopDown("vndk_deps", sabiDepsMutator)
|
||||
|
|
|
@ -115,6 +115,7 @@ type SanitizeProperties struct {
|
|||
SanitizerEnabled bool `blueprint:"mutated"`
|
||||
SanitizeDep bool `blueprint:"mutated"`
|
||||
MinimalRuntimeDep bool `blueprint:"mutated"`
|
||||
UbsanRuntimeDep bool `blueprint:"mutated"`
|
||||
InSanitizerDir bool `blueprint:"mutated"`
|
||||
}
|
||||
|
||||
|
@ -199,8 +200,9 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) {
|
|||
}
|
||||
}
|
||||
|
||||
// Global integer_overflow builds do not support static libraries.
|
||||
if found, globalSanitizers = removeFromList("integer_overflow", globalSanitizers); found && s.Integer_overflow == nil {
|
||||
if !ctx.Config().IntegerOverflowDisabledForPath(ctx.ModuleDir()) {
|
||||
if !ctx.Config().IntegerOverflowDisabledForPath(ctx.ModuleDir()) && !ctx.static() {
|
||||
s.Integer_overflow = boolPtr(true)
|
||||
}
|
||||
}
|
||||
|
@ -209,8 +211,9 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) {
|
|||
ctx.ModuleErrorf("unknown global sanitizer option %s", globalSanitizers[0])
|
||||
}
|
||||
|
||||
// Global integer_overflow builds do not support static library diagnostics.
|
||||
if found, globalSanitizersDiag = removeFromList("integer_overflow", globalSanitizersDiag); found &&
|
||||
s.Diag.Integer_overflow == nil && Bool(s.Integer_overflow) {
|
||||
s.Diag.Integer_overflow == nil && Bool(s.Integer_overflow) && !ctx.static() {
|
||||
s.Diag.Integer_overflow = boolPtr(true)
|
||||
}
|
||||
|
||||
|
@ -250,10 +253,14 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) {
|
|||
s.Diag.Cfi = nil
|
||||
}
|
||||
|
||||
// Also disable CFI for host builds.
|
||||
// Disable sanitizers that depend on the UBSan runtime for host builds.
|
||||
if ctx.Host() {
|
||||
s.Cfi = nil
|
||||
s.Diag.Cfi = nil
|
||||
s.Misc_undefined = nil
|
||||
s.Undefined = nil
|
||||
s.All_undefined = nil
|
||||
s.Integer_overflow = nil
|
||||
}
|
||||
|
||||
if ctx.staticBinary() {
|
||||
|
@ -305,7 +312,7 @@ func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags) Flags {
|
|||
if ctx.Device() && sanitize.Properties.MinimalRuntimeDep {
|
||||
flags.LdFlags = append(flags.LdFlags, minimalRuntimePath)
|
||||
}
|
||||
if !sanitize.Properties.SanitizerEnabled {
|
||||
if !sanitize.Properties.SanitizerEnabled && !sanitize.Properties.UbsanRuntimeDep {
|
||||
return flags
|
||||
}
|
||||
|
||||
|
@ -416,14 +423,12 @@ func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags) Flags {
|
|||
}
|
||||
|
||||
if Bool(sanitize.Properties.Sanitize.Integer_overflow) {
|
||||
if !ctx.static() {
|
||||
sanitizers = append(sanitizers, "unsigned-integer-overflow")
|
||||
sanitizers = append(sanitizers, "signed-integer-overflow")
|
||||
flags.CFlags = append(flags.CFlags, intOverflowCflags...)
|
||||
if Bool(sanitize.Properties.Sanitize.Diag.Integer_overflow) {
|
||||
diagSanitizers = append(diagSanitizers, "unsigned-integer-overflow")
|
||||
diagSanitizers = append(diagSanitizers, "signed-integer-overflow")
|
||||
}
|
||||
sanitizers = append(sanitizers, "unsigned-integer-overflow")
|
||||
sanitizers = append(sanitizers, "signed-integer-overflow")
|
||||
flags.CFlags = append(flags.CFlags, intOverflowCflags...)
|
||||
if Bool(sanitize.Properties.Sanitize.Diag.Integer_overflow) {
|
||||
diagSanitizers = append(diagSanitizers, "unsigned-integer-overflow")
|
||||
diagSanitizers = append(diagSanitizers, "signed-integer-overflow")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -463,15 +468,20 @@ func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags) Flags {
|
|||
runtimeLibrary = config.AddressSanitizerRuntimeLibrary(ctx.toolchain())
|
||||
} else if Bool(sanitize.Properties.Sanitize.Thread) {
|
||||
runtimeLibrary = config.ThreadSanitizerRuntimeLibrary(ctx.toolchain())
|
||||
} else if len(diagSanitizers) > 0 {
|
||||
} else if len(diagSanitizers) > 0 || sanitize.Properties.UbsanRuntimeDep {
|
||||
runtimeLibrary = config.UndefinedBehaviorSanitizerRuntimeLibrary(ctx.toolchain())
|
||||
}
|
||||
|
||||
if runtimeLibrary != "" {
|
||||
runtimeLibraryPath := "${config.ClangAsanLibDir}/" + runtimeLibrary
|
||||
if !ctx.static() {
|
||||
runtimeLibraryPath = runtimeLibraryPath + ctx.toolchain().ShlibSuffix()
|
||||
} else {
|
||||
runtimeLibraryPath = runtimeLibraryPath + ".a"
|
||||
}
|
||||
|
||||
// ASan runtime library must be the first in the link order.
|
||||
flags.libFlags = append([]string{
|
||||
"${config.ClangAsanLibDir}/" + runtimeLibrary + ctx.toolchain().ShlibSuffix(),
|
||||
}, flags.libFlags...)
|
||||
flags.libFlags = append([]string{runtimeLibraryPath}, flags.libFlags...)
|
||||
sanitize.runtimeLibrary = runtimeLibrary
|
||||
|
||||
// When linking against VNDK, use the vendor variant of the runtime lib
|
||||
|
@ -594,16 +604,21 @@ 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) {
|
||||
func sanitizerRuntimeDepsMutator() 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) {
|
||||
// If a static dependency is built with the minimal runtime,
|
||||
// make sure we include the ubsan minimal runtime.
|
||||
c.sanitize.Properties.MinimalRuntimeDep = true
|
||||
} else if Bool(d.sanitize.Properties.Sanitize.Diag.Integer_overflow) ||
|
||||
len(d.sanitize.Properties.Sanitize.Diag.Misc_undefined) > 0 {
|
||||
// If a static dependency runs with full ubsan diagnostics,
|
||||
// make sure we include the ubsan runtime.
|
||||
c.sanitize.Properties.UbsanRuntimeDep = true
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue