Reland "Prevent statically linking to a lib providing stable C APIs"

This reverts commit 5b75774004.

Bug: 151051671
Test: m
Change-Id: I05f0465976098941d47ecc06c978cfa116364d78
This commit is contained in:
Jiyong Park 2020-05-10 15:16:24 +09:00
parent 8a285478aa
commit af7ed39b06
3 changed files with 78 additions and 0 deletions

View File

@ -1852,6 +1852,44 @@ 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
}
// 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 {
@ -1889,6 +1927,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)

View File

@ -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()

View File

@ -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
}