Add cfi static libraries to vendor snapshot
CFI modules can't link against non-CFI static libraries, and vice versa. So without capturing both CFI and non-CFI static libraries, vendor modules won't be able to use CFI, which will be a critical security hole. This captures both CFI and non-CFI variants of all static libraries for vendor snapshot, except for those whose cfi are explicitly disabled. For example, suppose that "libfoo" is defined as follows. cc_library_static { name: "libfoo", vendor_available: true, } As it doesn't have cfi disabled, two libraries "libfoo.a" and "libfoo.cfi.a" will be captured. When installed, vendor snapshot module for "libfoo" will look like: vendor_snapshot_static { name: "libfoo", src: "libfoo.a", cfi: { src: "libfoo.cfi.a", }, } The build system will recognize the "cfi" property, and will create both CFI and non-CFI variant, allowing any modules to link against "libfoo" safely, no matter whether CFI is enabled or not. Two clarification: 1) The reason why we don't create separate modules is that DepsMutator runs before sanitize mutators. CFI and non-CFI variant of a library should exist in a single module. 2) We can't capture CFI variant if the source module explicitly disables cfi variant by specifying the following. sanitize: { cfi: false, } In this case, only non-CFI variant will be created for the vendor snapshot module. Bug: 65377115 Test: m dist vendor-snapshot && install && build against snapshot Change-Id: Idbf3e3205d581800d6093c8d6cf6152374129ba4
This commit is contained in:
@@ -1013,17 +1013,25 @@ func TestVendorSnapshot(t *testing.T) {
|
||||
filepath.Join(sharedDir, "libvendor_available.so.json"))
|
||||
|
||||
// For static libraries, all vendor:true and vendor_available modules (including VNDK) are captured.
|
||||
// Also cfi variants are captured, except for prebuilts like toolchain_library
|
||||
staticVariant := fmt.Sprintf("android_vendor.VER_%s_%s_static", archType, archVariant)
|
||||
staticCfiVariant := fmt.Sprintf("android_vendor.VER_%s_%s_static_cfi", archType, archVariant)
|
||||
staticDir := filepath.Join(snapshotVariantPath, archDir, "static")
|
||||
checkSnapshot(t, ctx, snapshotSingleton, "libb", "libb.a", staticDir, staticVariant)
|
||||
checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.a", staticDir, staticVariant)
|
||||
checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.cfi.a", staticDir, staticCfiVariant)
|
||||
checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.a", staticDir, staticVariant)
|
||||
checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.cfi.a", staticDir, staticCfiVariant)
|
||||
checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.a", staticDir, staticVariant)
|
||||
checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.cfi.a", staticDir, staticCfiVariant)
|
||||
jsonFiles = append(jsonFiles,
|
||||
filepath.Join(staticDir, "libb.a.json"),
|
||||
filepath.Join(staticDir, "libvndk.a.json"),
|
||||
filepath.Join(staticDir, "libvndk.cfi.a.json"),
|
||||
filepath.Join(staticDir, "libvendor.a.json"),
|
||||
filepath.Join(staticDir, "libvendor_available.a.json"))
|
||||
filepath.Join(staticDir, "libvendor.cfi.a.json"),
|
||||
filepath.Join(staticDir, "libvendor_available.a.json"),
|
||||
filepath.Join(staticDir, "libvendor_available.cfi.a.json"))
|
||||
|
||||
// For binary executables, all vendor:true and vendor_available modules are captured.
|
||||
if archType == "arm64" {
|
||||
@@ -1055,6 +1063,39 @@ func TestVendorSnapshot(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestVendorSnapshotSanitizer(t *testing.T) {
|
||||
bp := `
|
||||
vendor_snapshot_static {
|
||||
name: "libsnapshot",
|
||||
vendor: true,
|
||||
target_arch: "arm64",
|
||||
version: "BOARD",
|
||||
arch: {
|
||||
arm64: {
|
||||
src: "libsnapshot.a",
|
||||
cfi: {
|
||||
src: "libsnapshot.cfi.a",
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
`
|
||||
config := TestConfig(buildDir, android.Android, nil, bp, nil)
|
||||
config.TestProductVariables.DeviceVndkVersion = StringPtr("BOARD")
|
||||
config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
|
||||
ctx := testCcWithConfig(t, config)
|
||||
|
||||
// Check non-cfi and cfi variant.
|
||||
staticVariant := "android_vendor.BOARD_arm64_armv8-a_static"
|
||||
staticCfiVariant := "android_vendor.BOARD_arm64_armv8-a_static_cfi"
|
||||
|
||||
staticModule := ctx.ModuleForTests("libsnapshot.vendor_static.BOARD.arm64", staticVariant).Module().(*Module)
|
||||
assertString(t, staticModule.outputFile.Path().Base(), "libsnapshot.a")
|
||||
|
||||
staticCfiModule := ctx.ModuleForTests("libsnapshot.vendor_static.BOARD.arm64", staticCfiVariant).Module().(*Module)
|
||||
assertString(t, staticCfiModule.outputFile.Path().Base(), "libsnapshot.cfi.a")
|
||||
}
|
||||
|
||||
func TestDoubleLoadableDepError(t *testing.T) {
|
||||
// Check whether an error is emitted when a LLNDK depends on a non-double_loadable VNDK lib.
|
||||
testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
|
||||
|
Reference in New Issue
Block a user