rust: Bundle Rust shared dependencies in fuzzers

Rust shared library dependencies are not always bundled in cc_fuzz or
rust_fuzz modules, which can lead to difficult to debug runtime errors
when running these fuzzers. It can also be hard to determine which
dependencies need to be explicitly declared.

This CL makes sure that we bundle the appropriate transitive
dependencies for our fuzzers.

Bug: 249551848
Test: Soong tests
Test: m <fuzzer> # check data/fuzz/<arch>/lib dir contents
Change-Id: I957ca8898079b61e2ff20d750f8c92bf61ac394f
This commit is contained in:
Ivan Lozano
2023-06-09 14:06:44 -04:00
parent b2cd6f6963
commit 61c02cc537
5 changed files with 93 additions and 0 deletions

View File

@@ -1076,6 +1076,10 @@ func (c *Module) CcLibraryInterface() bool {
return false
}
func (c *Module) RustLibraryInterface() bool {
return false
}
func (c *Module) IsFuzzModule() bool {
if _, ok := c.compiler.(*fuzzBinary); ok {
return true

View File

@@ -535,6 +535,17 @@ func CollectAllSharedDependencies(ctx android.ModuleContext) (android.RuleBuilde
})
ctx.WalkDeps(func(child, parent android.Module) bool {
// If this is a Rust module which is not rust_ffi_shared, we still want to bundle any transitive
// shared dependencies (even for rust_ffi_static)
if rustmod, ok := child.(LinkableInterface); ok && rustmod.RustLibraryInterface() && !rustmod.Shared() {
if recursed[ctx.OtherModuleName(child)] {
return false
}
recursed[ctx.OtherModuleName(child)] = true
return true
}
if !IsValidSharedDependency(child) {
return false
}

View File

@@ -100,6 +100,9 @@ type LinkableInterface interface {
CcLibrary() bool
CcLibraryInterface() bool
// RustLibraryInterface returns true if this is a Rust library module
RustLibraryInterface() bool
// BaseModuleName returns the android.ModuleBase.BaseModuleName() value for this module.
BaseModuleName() string

View File

@@ -19,6 +19,7 @@ import (
"testing"
"android/soong/android"
"android/soong/cc"
)
func TestRustFuzz(t *testing.T) {
@@ -59,3 +60,68 @@ func TestRustFuzz(t *testing.T) {
t.Errorf("rust_fuzz dependent library does not contain the expected flags (sancov-module, cfg fuzzing).")
}
}
func TestRustFuzzDepBundling(t *testing.T) {
ctx := testRust(t, `
cc_library {
name: "libcc_transitive_dep",
}
cc_library {
name: "libcc_direct_dep",
}
rust_library {
name: "libtest_fuzzing",
crate_name: "test_fuzzing",
srcs: ["foo.rs"],
shared_libs: ["libcc_transitive_dep"],
}
rust_fuzz {
name: "fuzz_libtest",
srcs: ["foo.rs"],
rustlibs: ["libtest_fuzzing"],
shared_libs: ["libcc_direct_dep"],
}
`)
fuzz_libtest := ctx.ModuleForTests("fuzz_libtest", "android_arm64_armv8-a_fuzzer").Module().(*Module)
if !strings.Contains(fuzz_libtest.FuzzSharedLibraries().String(), ":libcc_direct_dep.so") {
t.Errorf("rust_fuzz does not contain the expected bundled direct shared libs ('libcc_direct_dep'): %#v", fuzz_libtest.FuzzSharedLibraries().String())
}
if !strings.Contains(fuzz_libtest.FuzzSharedLibraries().String(), ":libcc_transitive_dep.so") {
t.Errorf("rust_fuzz does not contain the expected bundled transitive shared libs ('libcc_transitive_dep'): %#v", fuzz_libtest.FuzzSharedLibraries().String())
}
}
func TestCCFuzzDepBundling(t *testing.T) {
ctx := testRust(t, `
cc_library {
name: "libcc_transitive_dep",
}
rust_ffi {
name: "libtest_fuzzing",
crate_name: "test_fuzzing",
srcs: ["foo.rs"],
shared_libs: ["libcc_transitive_dep"],
}
cc_fuzz {
name: "fuzz_shared_libtest",
shared_libs: ["libtest_fuzzing"],
}
cc_fuzz {
name: "fuzz_static_libtest",
static_libs: ["libtest_fuzzing"],
}
`)
fuzz_shared_libtest := ctx.ModuleForTests("fuzz_shared_libtest", "android_arm64_armv8-a_fuzzer").Module().(cc.LinkableInterface)
fuzz_static_libtest := ctx.ModuleForTests("fuzz_static_libtest", "android_arm64_armv8-a_fuzzer").Module().(cc.LinkableInterface)
if !strings.Contains(fuzz_shared_libtest.FuzzSharedLibraries().String(), ":libcc_transitive_dep.so") {
t.Errorf("cc_fuzz does not contain the expected bundled transitive shared libs from rust_ffi_shared ('libcc_transitive_dep'): %#v", fuzz_shared_libtest.FuzzSharedLibraries().String())
}
if !strings.Contains(fuzz_static_libtest.FuzzSharedLibraries().String(), ":libcc_transitive_dep.so") {
t.Errorf("cc_fuzz does not contain the expected bundled transitive shared libs from rust_ffi_static ('libcc_transitive_dep'): %#v", fuzz_static_libtest.FuzzSharedLibraries().String())
}
}

View File

@@ -631,6 +631,15 @@ func (mod *Module) CcLibraryInterface() bool {
return false
}
func (mod *Module) RustLibraryInterface() bool {
if mod.compiler != nil {
if _, ok := mod.compiler.(libraryInterface); ok {
return true
}
}
return false
}
func (mod *Module) IsFuzzModule() bool {
if _, ok := mod.compiler.(*fuzzDecorator); ok {
return true