Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5a33a3ca authored by Jiyong Park's avatar Jiyong Park Committed by Gerrit Code Review
Browse files

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

parents 49e94c0a 7d95a510
Loading
Loading
Loading
Loading
+46 −0
Original line number Diff line number Diff line
@@ -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)

+36 −0
Original line number Diff line number Diff line
@@ -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()
+3 −0
Original line number Diff line number Diff line
@@ -2881,6 +2881,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
}