From 2fcbffa4a1dd445586bb6be14caa38ba3ef4bdc3 Mon Sep 17 00:00:00 2001 From: Ivan Lozano Date: Thu, 27 Jul 2023 10:40:52 -0400 Subject: [PATCH] rust: Add support for host fuzzers. Adds support for host-based Rust fuzzers. Bug: 282897366 Test: SANITZE_HOST="address" m Test: run fuzzer Change-Id: Ibb951f651ef12e763778ebbf12e66769a7113920 --- rust/compiler.go | 9 +++++++++ rust/fuzz.go | 6 ++++++ rust/fuzz_test.go | 10 ++++++++++ rust/sanitize.go | 30 ++++++++++++++++++++++-------- rust/testing.go | 1 + 5 files changed, 48 insertions(+), 8 deletions(-) diff --git a/rust/compiler.go b/rust/compiler.go index 06ae12f79..8d89c4805 100644 --- a/rust/compiler.go +++ b/rust/compiler.go @@ -320,6 +320,15 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags) Flag flags.LinkFlags = append(flags.LinkFlags, cc.RpathFlags(ctx)...) } + if !ctx.toolchain().Bionic() && ctx.Os() != android.LinuxMusl && !ctx.Windows() { + // Add -ldl, -lpthread, -lm and -lrt to host builds to match the default behavior of device + // builds. This is irrelevant for the Windows target as these are Posix specific. + flags.LinkFlags = append(flags.LinkFlags, + "-ldl", + "-lpthread", + "-lm", + ) + } return flags } diff --git a/rust/fuzz.go b/rust/fuzz.go index c2b940525..235f51779 100644 --- a/rust/fuzz.go +++ b/rust/fuzz.go @@ -25,6 +25,7 @@ import ( func init() { android.RegisterModuleType("rust_fuzz", RustFuzzFactory) + android.RegisterModuleType("rust_fuzz_host", RustFuzzHostFactory) } type fuzzDecorator struct { @@ -43,6 +44,11 @@ func RustFuzzFactory() android.Module { return module.Init() } +func RustFuzzHostFactory() android.Module { + module, _ := NewRustFuzz(android.HostSupported) + return module.Init() +} + func NewRustFuzz(hod android.HostOrDeviceSupported) (*Module, *fuzzDecorator) { module, binary := NewRustBinary(hod) fuzz := &fuzzDecorator{ diff --git a/rust/fuzz_test.go b/rust/fuzz_test.go index 0aecf617e..ee28c6d3a 100644 --- a/rust/fuzz_test.go +++ b/rust/fuzz_test.go @@ -34,6 +34,10 @@ func TestRustFuzz(t *testing.T) { srcs: ["foo.rs"], rustlibs: ["libtest_fuzzing"], } + rust_fuzz_host { + name: "host_fuzzer", + srcs: ["foo.rs"], + } `) // Check that appropriate dependencies are added and that the rustlib linkage is correct. @@ -50,7 +54,13 @@ func TestRustFuzz(t *testing.T) { if !strings.Contains(fuzz_libtest.Args["rustcFlags"], "-C passes='sancov-module'") || !strings.Contains(fuzz_libtest.Args["rustcFlags"], "--cfg fuzzing") { t.Errorf("rust_fuzz module does not contain the expected flags (sancov-module, cfg fuzzing).") + } + // Check that host modules support fuzzing. + host_fuzzer := ctx.ModuleForTests("fuzz_libtest", "android_arm64_armv8-a_fuzzer").Rule("rustc") + if !strings.Contains(host_fuzzer.Args["rustcFlags"], "-C passes='sancov-module'") || + !strings.Contains(host_fuzzer.Args["rustcFlags"], "--cfg fuzzing") { + t.Errorf("rust_fuzz_host module does not contain the expected flags (sancov-module, cfg fuzzing).") } // Check that dependencies have 'fuzzer' variants produced for them as well. diff --git a/rust/sanitize.go b/rust/sanitize.go index 862baf7cc..cc19e6e61 100644 --- a/rust/sanitize.go +++ b/rust/sanitize.go @@ -209,8 +209,8 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) { } // TODO:(b/178369775) - // For now sanitizing is only supported on devices - if ctx.Os() == android.Android && (Bool(s.Hwaddress) || Bool(s.Address) || Bool(s.Memtag_heap) || Bool(s.Fuzzer)) { + // For now sanitizing is only supported on non-windows targets + if ctx.Os() != android.Windows && (Bool(s.Hwaddress) || Bool(s.Address) || Bool(s.Memtag_heap) || Bool(s.Fuzzer)) { sanitize.Properties.SanitizerEnabled = true } } @@ -234,6 +234,11 @@ func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags, deps PathDeps) ( if Bool(sanitize.Properties.Sanitize.Address) { flags.RustFlags = append(flags.RustFlags, asanFlags...) + if ctx.Host() { + // -nodefaultlibs (provided with libc++) prevents the driver from linking + // libraries needed with -fsanitize=address. http://b/18650275 (WAI) + flags.LinkFlags = append(flags.LinkFlags, []string{"-Wl,--no-as-needed"}...) + } } return flags, deps } @@ -273,10 +278,17 @@ func rustSanitizerRuntimeMutator(mctx android.BottomUpMutatorContext) { var deps []string if mod.IsSanitizerEnabled(cc.Asan) { - variations = append(variations, - blueprint.Variation{Mutator: "link", Variation: "shared"}) - depTag = cc.SharedDepTag() - deps = []string{config.LibclangRuntimeLibrary(mod.toolchain(mctx), "asan")} + if mod.Host() { + variations = append(variations, + blueprint.Variation{Mutator: "link", Variation: "static"}) + depTag = cc.StaticDepTag(false) + deps = []string{config.LibclangRuntimeLibrary(mod.toolchain(mctx), "asan.static")} + } else { + variations = append(variations, + blueprint.Variation{Mutator: "link", Variation: "shared"}) + depTag = cc.SharedDepTag() + deps = []string{config.LibclangRuntimeLibrary(mod.toolchain(mctx), "asan")} + } } else if mod.IsSanitizerEnabled(cc.Hwasan) { // TODO(b/204776996): HWASan for static Rust binaries isn't supported yet. if binary, ok := mod.compiler.(binaryInterface); ok { @@ -391,7 +403,8 @@ func (sanitize *sanitize) AndroidMk(ctx AndroidMkContext, entries *android.Andro } func (mod *Module) SanitizerSupported(t cc.SanitizerType) bool { - if mod.Host() { + // Sanitizers are not supported on Windows targets. + if mod.Os() == android.Windows { return false } switch t { @@ -417,7 +430,8 @@ func (mod *Module) IsSanitizerEnabled(t cc.SanitizerType) bool { } func (mod *Module) IsSanitizerExplicitlyDisabled(t cc.SanitizerType) bool { - if mod.Host() { + // Sanitizers are not supported on Windows targets. + if mod.Os() == android.Windows { return true } diff --git a/rust/testing.go b/rust/testing.go index 7f3056954..3fe751e17 100644 --- a/rust/testing.go +++ b/rust/testing.go @@ -182,6 +182,7 @@ func registerRequiredBuildComponentsForTest(ctx android.RegistrationContext) { ctx.RegisterModuleType("rust_library_host_dylib", RustLibraryDylibHostFactory) ctx.RegisterModuleType("rust_library_host_rlib", RustLibraryRlibHostFactory) ctx.RegisterModuleType("rust_fuzz", RustFuzzFactory) + ctx.RegisterModuleType("rust_fuzz_host", RustFuzzHostFactory) ctx.RegisterModuleType("rust_ffi", RustFFIFactory) ctx.RegisterModuleType("rust_ffi_shared", RustFFISharedFactory) ctx.RegisterModuleType("rust_ffi_static", RustFFIStaticFactory)