summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Ivan Lozano <ivanlozano@google.com> 2023-06-09 14:06:44 -0400
committer Ivan Lozano <ivanlozano@google.com> 2023-06-09 14:17:49 -0400
commit61c02cc5371395fc919b49b14ce253a151f2fa93 (patch)
treeb5ebacbcc81db111ae87cdf17aac3e06c9d88394
parentb2cd6f69632f9b21dda9b3b59a6ea081e57860fc (diff)
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
-rw-r--r--cc/cc.go4
-rw-r--r--cc/fuzz.go11
-rw-r--r--cc/linkable.go3
-rw-r--r--rust/fuzz_test.go66
-rw-r--r--rust/rust.go9
5 files changed, 93 insertions, 0 deletions
diff --git a/cc/cc.go b/cc/cc.go
index c9f00e248..ddff2b03d 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -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
diff --git a/cc/fuzz.go b/cc/fuzz.go
index c897501e8..636ad855b 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -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
}
diff --git a/cc/linkable.go b/cc/linkable.go
index 557f5d2b3..976a38201 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -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
diff --git a/rust/fuzz_test.go b/rust/fuzz_test.go
index 7fa9f5c8f..0aecf617e 100644
--- a/rust/fuzz_test.go
+++ b/rust/fuzz_test.go
@@ -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())
+ }
+}
diff --git a/rust/rust.go b/rust/rust.go
index 4324ecbb9..e524c9fb6 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -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