From 7d95a510cc888deb13c132f8a51c87e878763be8 Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Sun, 10 May 2020 15:16:24 +0900 Subject: [PATCH] Reland "Prevent statically linking to a lib providing stable C APIs" This reverts commit 5b75774004f0dc26a6dfe5d62976e1d2af4bcff3. Exempt-From-Owner-Approval: cherry-pick from internal Bug: 151051671 Test: m Merged-In: I05f0465976098941d47ecc06c978cfa116364d78 (cherry picked from commit af7ed39b062c534263ea3091250fd64964896e55) Change-Id: I05f0465976098941d47ecc06c978cfa116364d78 --- apex/apex.go | 46 ++++++++++++++++++++++++++++++++++++++++++++++ apex/apex_test.go | 36 ++++++++++++++++++++++++++++++++++++ cc/cc.go | 3 +++ 3 files changed, 85 insertions(+) diff --git a/apex/apex.go b/apex/apex.go index 4b59c6d93..9659c3fcd 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -1848,6 +1848,51 @@ func (a *apexBundle) checkUpdatable(ctx android.ModuleContext) { } } +// Ensures that a lib providing stub isn't statically linked +func (a *apexBundle) checkStaticLinkingToStubLibraries(ctx android.ModuleContext) { + // Practically, we only care about regular APEXes on the device. + if ctx.Host() || a.testApex || a.vndkApex { + return + } + + a.walkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool { + if ccm, ok := to.(*cc.Module); ok { + apexName := ctx.ModuleName() + fromName := ctx.OtherModuleName(from) + toName := ctx.OtherModuleName(to) + + // If `to` is not actually in the same APEX as `from` then it does not need apex_available and neither + // do any of its dependencies. + if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) { + // As soon as the dependency graph crosses the APEX boundary, don't go further. + return false + } + + // TODO(jiyong) remove this check when R is published to AOSP. Currently, libstatssocket + // is capable of providing a stub variant, but is being statically linked from the bluetooth + // APEX. + if toName == "libstatssocket" { + return false + } + + // The dynamic linker and crash_dump tool in the runtime APEX is the only exception to this rule. + // It can't make the static dependencies dynamic because it can't + // do the dynamic linking for itself. + if apexName == "com.android.runtime" && (fromName == "linker" || fromName == "crash_dump") { + return false + } + + isStubLibraryFromOtherApex := ccm.HasStubsVariants() && !android.DirectlyInApex(apexName, toName) + if isStubLibraryFromOtherApex && !externalDep { + ctx.ModuleErrorf("%q required by %q is a native library providing stub. "+ + "It shouldn't be included in this APEX via static linking. Dependency path: %s", to.String(), fromName, ctx.GetPathString(false)) + } + + } + return true + }) +} + func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { buildFlattenedAsDefault := ctx.Config().FlattenApex() && !ctx.Config().UnbundledBuild() switch a.properties.ApexType { @@ -1885,6 +1930,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { a.checkApexAvailability(ctx) a.checkUpdatable(ctx) + a.checkStaticLinkingToStubLibraries(ctx) handleSpecialLibs := !android.Bool(a.properties.Ignore_system_library_special_case) diff --git a/apex/apex_test.go b/apex/apex_test.go index 5461debf4..2d3f52f4c 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -4833,6 +4833,42 @@ func TestApexSet(t *testing.T) { } } +func TestNoStaticLinkingToStubsLib(t *testing.T) { + testApexError(t, `.*required by "mylib" is a native library providing stub.*`, ` + apex { + name: "myapex", + key: "myapex.key", + native_shared_libs: ["mylib"], + } + + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + + cc_library { + name: "mylib", + srcs: ["mylib.cpp"], + static_libs: ["otherlib"], + system_shared_libs: [], + stl: "none", + apex_available: [ "myapex" ], + } + + cc_library { + name: "otherlib", + srcs: ["mylib.cpp"], + system_shared_libs: [], + stl: "none", + stubs: { + versions: ["1", "2", "3"], + }, + apex_available: [ "myapex" ], + } + `) +} + func TestMain(m *testing.M) { run := func() int { setUp() diff --git a/cc/cc.go b/cc/cc.go index fbd5bdfb8..efd90ccb0 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -2871,6 +2871,9 @@ func (c *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Modu return false } } + } else if ctx.OtherModuleDependencyTag(dep) == llndkImplDep { + // We don't track beyond LLNDK + return false } return true }