Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a9255a83 authored by Ivan Lozano's avatar Ivan Lozano
Browse files

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
parent d3c59a2b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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)
+34 −19
Original line number Diff line number Diff line
@@ -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,7 +423,6 @@ 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...)
@@ -425,7 +431,6 @@ func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags) Flags {
			diagSanitizers = append(diagSanitizers, "signed-integer-overflow")
		}
	}
	}

	if len(sanitizers) > 0 {
		sanitizeArg := "-fsanitize=" + strings.Join(sanitizers, ",")
@@ -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
					}
				}
			})