From d18ae5ce983a241a65696817d01da2ff96ec18f7 Mon Sep 17 00:00:00 2001 From: Kostya Kortchinsky Date: Tue, 12 Jun 2018 14:46:54 -0700 Subject: [PATCH] Soong support for Scudo Scudo is a hardened usermode allocator that is part of LLVM's compiler-rt project (home of the Sanitizers). clang allows for -fsanitize=scudo as a possible command line option to link the shared Scudo library to a binary. This patch add Scudo as a potential sanitize option. Scudo is not compatible with ASan and TSan and will be disabled if either is enabled. Bug: 72112048 Test: aosp compiled with m -j Test: local experiment with scudo: true to ensure that a test target (tombstoned) could be linked with scudo. Change-Id: I76bb6c60891d4782f6665a112c4c2bf7c31645da --- cc/config/toolchain.go | 4 ++++ cc/makevars.go | 1 + cc/sanitize.go | 20 +++++++++++++++++++- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/cc/config/toolchain.go b/cc/config/toolchain.go index ca863a7d7..ea8397d7e 100644 --- a/cc/config/toolchain.go +++ b/cc/config/toolchain.go @@ -243,6 +243,10 @@ func ProfileRuntimeLibrary(t Toolchain) string { return SanitizerRuntimeLibrary(t, "profile") } +func ScudoRuntimeLibrary(t Toolchain) string { + return SanitizerRuntimeLibrary(t, "scudo") +} + func ToolPath(t Toolchain) string { if p := t.ToolPath(); p != "" { return p diff --git a/cc/makevars.go b/cc/makevars.go index 8b72dbb32..5a912e10e 100644 --- a/cc/makevars.go +++ b/cc/makevars.go @@ -302,6 +302,7 @@ func makeVarsToolchain(ctx android.MakeVarsContext, secondPrefix string, 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+"SCUDO_RUNTIME_LIBRARY", strings.TrimSuffix(config.ScudoRuntimeLibrary(toolchain), ".so")) } // This is used by external/gentoo/... diff --git a/cc/sanitize.go b/cc/sanitize.go index e59edf58a..38f4fc28d 100644 --- a/cc/sanitize.go +++ b/cc/sanitize.go @@ -94,6 +94,7 @@ type SanitizeProperties struct { Safestack *bool `android:"arch_variant"` Cfi *bool `android:"arch_variant"` Integer_overflow *bool `android:"arch_variant"` + Scudo *bool `android:"arch_variant"` // Sanitizers to run in the diagnostic mode (as opposed to the release mode). // Replaces abort() on error with a human-readable error message. @@ -207,6 +208,10 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) { } } + if found, globalSanitizers = removeFromList("scudo", globalSanitizers); found && s.Scudo == nil { + s.Scudo = boolPtr(true) + } + if len(globalSanitizers) > 0 { ctx.ModuleErrorf("unknown global sanitizer option %s", globalSanitizers[0]) } @@ -281,10 +286,16 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) { } if ctx.Os() != android.Windows && (Bool(s.All_undefined) || Bool(s.Undefined) || Bool(s.Address) || Bool(s.Thread) || - Bool(s.Coverage) || Bool(s.Safestack) || Bool(s.Cfi) || Bool(s.Integer_overflow) || len(s.Misc_undefined) > 0) { + Bool(s.Coverage) || Bool(s.Safestack) || Bool(s.Cfi) || Bool(s.Integer_overflow) || len(s.Misc_undefined) > 0 || + Bool(s.Scudo)) { sanitize.Properties.SanitizerEnabled = true } + // Disable Scudo if ASan or TSan is enabled. + if Bool(s.Address) || Bool(s.Thread) { + s.Scudo = nil + } + if Bool(s.Coverage) { if !Bool(s.Address) { ctx.ModuleErrorf(`Use of "coverage" also requires "address"`) @@ -434,6 +445,10 @@ func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags) Flags { } } + if Bool(sanitize.Properties.Sanitize.Scudo) { + sanitizers = append(sanitizers, "scudo") + } + if len(sanitizers) > 0 { sanitizeArg := "-fsanitize=" + strings.Join(sanitizers, ",") @@ -471,6 +486,8 @@ 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 Bool(sanitize.Properties.Sanitize.Scudo) { + runtimeLibrary = config.ScudoRuntimeLibrary(ctx.toolchain()) } else if len(diagSanitizers) > 0 || sanitize.Properties.UbsanRuntimeDep { runtimeLibrary = config.UndefinedBehaviorSanitizerRuntimeLibrary(ctx.toolchain()) } @@ -705,6 +722,7 @@ func cfiStaticLibs(config android.Config) *[]string { func enableMinimalRuntime(sanitize *sanitize) bool { if !Bool(sanitize.Properties.Sanitize.Address) && + !Bool(sanitize.Properties.Sanitize.Scudo) && (Bool(sanitize.Properties.Sanitize.Integer_overflow) || len(sanitize.Properties.Sanitize.Misc_undefined) > 0) && !(Bool(sanitize.Properties.Sanitize.Diag.Integer_overflow) ||