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:
@@ -518,10 +518,14 @@ func (c *vendorSnapshotLibraryDecorator) AndroidMkEntries(ctx AndroidMkContext,
|
|||||||
entries.Class = "HEADER_LIBRARIES"
|
entries.Class = "HEADER_LIBRARIES"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entries.SubName = ""
|
||||||
|
|
||||||
|
if c.sanitizerProperties.CfiEnabled {
|
||||||
|
entries.SubName += ".cfi"
|
||||||
|
}
|
||||||
|
|
||||||
if c.androidMkVendorSuffix {
|
if c.androidMkVendorSuffix {
|
||||||
entries.SubName = vendorSuffix
|
entries.SubName += vendorSuffix
|
||||||
} else {
|
|
||||||
entries.SubName = ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
|
entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
|
||||||
|
@@ -1013,17 +1013,25 @@ func TestVendorSnapshot(t *testing.T) {
|
|||||||
filepath.Join(sharedDir, "libvendor_available.so.json"))
|
filepath.Join(sharedDir, "libvendor_available.so.json"))
|
||||||
|
|
||||||
// For static libraries, all vendor:true and vendor_available modules (including VNDK) are captured.
|
// 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)
|
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")
|
staticDir := filepath.Join(snapshotVariantPath, archDir, "static")
|
||||||
checkSnapshot(t, ctx, snapshotSingleton, "libb", "libb.a", staticDir, staticVariant)
|
checkSnapshot(t, ctx, snapshotSingleton, "libb", "libb.a", staticDir, staticVariant)
|
||||||
checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.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.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.a", staticDir, staticVariant)
|
||||||
|
checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.cfi.a", staticDir, staticCfiVariant)
|
||||||
jsonFiles = append(jsonFiles,
|
jsonFiles = append(jsonFiles,
|
||||||
filepath.Join(staticDir, "libb.a.json"),
|
filepath.Join(staticDir, "libb.a.json"),
|
||||||
filepath.Join(staticDir, "libvndk.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.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.
|
// For binary executables, all vendor:true and vendor_available modules are captured.
|
||||||
if archType == "arm64" {
|
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) {
|
func TestDoubleLoadableDepError(t *testing.T) {
|
||||||
// Check whether an error is emitted when a LLNDK depends on a non-double_loadable VNDK lib.
|
// 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", `
|
testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
|
||||||
|
120
cc/sanitize.go
120
cc/sanitize.go
@@ -309,14 +309,14 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) {
|
|||||||
|
|
||||||
// Is CFI actually enabled?
|
// Is CFI actually enabled?
|
||||||
if !ctx.Config().EnableCFI() {
|
if !ctx.Config().EnableCFI() {
|
||||||
s.Cfi = nil
|
s.Cfi = boolPtr(false)
|
||||||
s.Diag.Cfi = nil
|
s.Diag.Cfi = boolPtr(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also disable CFI for arm32 until b/35157333 is fixed.
|
// Also disable CFI for arm32 until b/35157333 is fixed.
|
||||||
if ctx.Arch().ArchType == android.Arm {
|
if ctx.Arch().ArchType == android.Arm {
|
||||||
s.Cfi = nil
|
s.Cfi = boolPtr(false)
|
||||||
s.Diag.Cfi = nil
|
s.Diag.Cfi = boolPtr(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HWASan requires AArch64 hardware feature (top-byte-ignore).
|
// HWASan requires AArch64 hardware feature (top-byte-ignore).
|
||||||
@@ -331,14 +331,14 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) {
|
|||||||
|
|
||||||
// Also disable CFI if ASAN is enabled.
|
// Also disable CFI if ASAN is enabled.
|
||||||
if Bool(s.Address) || Bool(s.Hwaddress) {
|
if Bool(s.Address) || Bool(s.Hwaddress) {
|
||||||
s.Cfi = nil
|
s.Cfi = boolPtr(false)
|
||||||
s.Diag.Cfi = nil
|
s.Diag.Cfi = boolPtr(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable sanitizers that depend on the UBSan runtime for windows/darwin builds.
|
// Disable sanitizers that depend on the UBSan runtime for windows/darwin builds.
|
||||||
if !ctx.Os().Linux() {
|
if !ctx.Os().Linux() {
|
||||||
s.Cfi = nil
|
s.Cfi = boolPtr(false)
|
||||||
s.Diag.Cfi = nil
|
s.Diag.Cfi = boolPtr(false)
|
||||||
s.Misc_undefined = nil
|
s.Misc_undefined = nil
|
||||||
s.Undefined = nil
|
s.Undefined = nil
|
||||||
s.All_undefined = nil
|
s.All_undefined = nil
|
||||||
@@ -347,14 +347,15 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) {
|
|||||||
|
|
||||||
// Also disable CFI for VNDK variants of components
|
// Also disable CFI for VNDK variants of components
|
||||||
if ctx.isVndk() && ctx.useVndk() {
|
if ctx.isVndk() && ctx.useVndk() {
|
||||||
s.Cfi = nil
|
if ctx.static() {
|
||||||
s.Diag.Cfi = nil
|
// Cfi variant for static vndk should be captured as vendor snapshot,
|
||||||
}
|
// so don't strictly disable Cfi.
|
||||||
|
s.Cfi = nil
|
||||||
// Also disable CFI if building against snapshot.
|
s.Diag.Cfi = nil
|
||||||
vndkVersion := ctx.DeviceConfig().VndkVersion()
|
} else {
|
||||||
if ctx.useVndk() && vndkVersion != "current" && vndkVersion != "" {
|
s.Cfi = boolPtr(false)
|
||||||
s.Cfi = nil
|
s.Diag.Cfi = boolPtr(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// HWASan ramdisk (which is built from recovery) goes over some bootloader limit.
|
// HWASan ramdisk (which is built from recovery) goes over some bootloader limit.
|
||||||
@@ -399,7 +400,7 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) {
|
|||||||
// TODO(b/131771163): CFI transiently depends on LTO, and thus Fuzzer is
|
// TODO(b/131771163): CFI transiently depends on LTO, and thus Fuzzer is
|
||||||
// mutually incompatible.
|
// mutually incompatible.
|
||||||
if Bool(s.Fuzzer) {
|
if Bool(s.Fuzzer) {
|
||||||
s.Cfi = nil
|
s.Cfi = boolPtr(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -722,27 +723,64 @@ func isSanitizableDependencyTag(tag blueprint.DependencyTag) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Determines if the current module is a static library going to be captured
|
||||||
|
// as vendor snapshot. Such modules must create both cfi and non-cfi variants,
|
||||||
|
// except for ones which explicitly disable cfi.
|
||||||
|
func needsCfiForVendorSnapshot(mctx android.TopDownMutatorContext) bool {
|
||||||
|
if isVendorProprietaryPath(mctx.ModuleDir()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
c := mctx.Module().(*Module)
|
||||||
|
|
||||||
|
if !c.inVendor() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if !c.static() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.Prebuilt() != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.sanitize != nil &&
|
||||||
|
!Bool(c.sanitize.Properties.Sanitize.Never) &&
|
||||||
|
!c.sanitize.isSanitizerExplicitlyDisabled(cfi)
|
||||||
|
}
|
||||||
|
|
||||||
// Propagate sanitizer requirements down from binaries
|
// Propagate sanitizer requirements down from binaries
|
||||||
func sanitizerDepsMutator(t sanitizerType) func(android.TopDownMutatorContext) {
|
func sanitizerDepsMutator(t sanitizerType) func(android.TopDownMutatorContext) {
|
||||||
return func(mctx android.TopDownMutatorContext) {
|
return func(mctx android.TopDownMutatorContext) {
|
||||||
if c, ok := mctx.Module().(*Module); ok && c.sanitize.isSanitizerEnabled(t) {
|
if c, ok := mctx.Module().(*Module); ok {
|
||||||
mctx.WalkDeps(func(child, parent android.Module) bool {
|
enabled := c.sanitize.isSanitizerEnabled(t)
|
||||||
if !isSanitizableDependencyTag(mctx.OtherModuleDependencyTag(child)) {
|
if t == cfi && needsCfiForVendorSnapshot(mctx) {
|
||||||
return false
|
// We shouldn't change the result of isSanitizerEnabled(cfi) to correctly
|
||||||
}
|
// determine defaultVariation in sanitizerMutator below.
|
||||||
if d, ok := child.(*Module); ok && d.sanitize != nil &&
|
// Instead, just mark SanitizeDep to forcefully create cfi variant.
|
||||||
!Bool(d.sanitize.Properties.Sanitize.Never) &&
|
enabled = true
|
||||||
!d.sanitize.isSanitizerExplicitlyDisabled(t) {
|
c.sanitize.Properties.SanitizeDep = true
|
||||||
if t == cfi || t == hwasan || t == scs {
|
}
|
||||||
if d.static() {
|
if enabled {
|
||||||
|
mctx.WalkDeps(func(child, parent android.Module) bool {
|
||||||
|
if !isSanitizableDependencyTag(mctx.OtherModuleDependencyTag(child)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if d, ok := child.(*Module); ok && d.sanitize != nil &&
|
||||||
|
!Bool(d.sanitize.Properties.Sanitize.Never) &&
|
||||||
|
!d.sanitize.isSanitizerExplicitlyDisabled(t) {
|
||||||
|
if t == cfi || t == hwasan || t == scs {
|
||||||
|
if d.static() {
|
||||||
|
d.sanitize.Properties.SanitizeDep = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
d.sanitize.Properties.SanitizeDep = true
|
d.sanitize.Properties.SanitizeDep = true
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
d.sanitize.Properties.SanitizeDep = true
|
|
||||||
}
|
}
|
||||||
}
|
return true
|
||||||
return true
|
})
|
||||||
})
|
}
|
||||||
} else if sanitizeable, ok := mctx.Module().(Sanitizeable); ok {
|
} else if sanitizeable, ok := mctx.Module().(Sanitizeable); ok {
|
||||||
// If an APEX module includes a lib which is enabled for a sanitizer T, then
|
// If an APEX module includes a lib which is enabled for a sanitizer T, then
|
||||||
// the APEX module is also enabled for the same sanitizer type.
|
// the APEX module is also enabled for the same sanitizer type.
|
||||||
@@ -1076,6 +1114,24 @@ func sanitizerMutator(t sanitizerType) func(android.BottomUpMutatorContext) {
|
|||||||
// APEX modules fall here
|
// APEX modules fall here
|
||||||
sanitizeable.AddSanitizerDependencies(mctx, t.name())
|
sanitizeable.AddSanitizerDependencies(mctx, t.name())
|
||||||
mctx.CreateVariations(t.variationName())
|
mctx.CreateVariations(t.variationName())
|
||||||
|
} else if c, ok := mctx.Module().(*Module); ok {
|
||||||
|
// Check if it's a snapshot module supporting sanitizer
|
||||||
|
if s, ok := c.linker.(snapshotSanitizer); ok && s.isSanitizerEnabled(t) {
|
||||||
|
// Set default variation as above.
|
||||||
|
defaultVariation := t.variationName()
|
||||||
|
mctx.SetDefaultDependencyVariation(&defaultVariation)
|
||||||
|
modules := mctx.CreateVariations("", t.variationName())
|
||||||
|
modules[0].(*Module).linker.(snapshotSanitizer).setSanitizerVariation(t, false)
|
||||||
|
modules[1].(*Module).linker.(snapshotSanitizer).setSanitizerVariation(t, true)
|
||||||
|
|
||||||
|
// Export the static lib name to make
|
||||||
|
if c.static() && c.ExportedToMake() {
|
||||||
|
if t == cfi {
|
||||||
|
// use BaseModuleName which is the name for Make.
|
||||||
|
cfiStaticLibs(mctx.Config()).add(c, c.BaseModuleName())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -567,6 +567,7 @@ func CreateTestContext() *android.TestContext {
|
|||||||
ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
|
ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
|
||||||
ctx.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory)
|
ctx.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory)
|
||||||
ctx.RegisterModuleType("vndk_libraries_txt", VndkLibrariesTxtFactory)
|
ctx.RegisterModuleType("vndk_libraries_txt", VndkLibrariesTxtFactory)
|
||||||
|
ctx.RegisterModuleType("vendor_snapshot_static", VendorSnapshotStaticFactory)
|
||||||
ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
|
ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
|
||||||
android.RegisterPrebuiltMutators(ctx)
|
android.RegisterPrebuiltMutators(ctx)
|
||||||
RegisterRequiredBuildComponentsForTest(ctx)
|
RegisterRequiredBuildComponentsForTest(ctx)
|
||||||
|
@@ -140,13 +140,15 @@ type vendorSnapshotLibraryProperties struct {
|
|||||||
// Prebuilt file for each arch.
|
// Prebuilt file for each arch.
|
||||||
Src *string `android:"arch_variant"`
|
Src *string `android:"arch_variant"`
|
||||||
|
|
||||||
|
// list of directories that will be added to the include path (using -I).
|
||||||
|
Export_include_dirs []string `android:"arch_variant"`
|
||||||
|
|
||||||
|
// list of directories that will be added to the system path (using -isystem).
|
||||||
|
Export_system_include_dirs []string `android:"arch_variant"`
|
||||||
|
|
||||||
// list of flags that will be used for any module that links against this module.
|
// list of flags that will be used for any module that links against this module.
|
||||||
Export_flags []string `android:"arch_variant"`
|
Export_flags []string `android:"arch_variant"`
|
||||||
|
|
||||||
// Check the prebuilt ELF files (e.g. DT_SONAME, DT_NEEDED, resolution of undefined symbols,
|
|
||||||
// etc).
|
|
||||||
Check_elf_files *bool
|
|
||||||
|
|
||||||
// Whether this prebuilt needs to depend on sanitize ubsan runtime or not.
|
// Whether this prebuilt needs to depend on sanitize ubsan runtime or not.
|
||||||
Sanitize_ubsan_dep *bool `android:"arch_variant"`
|
Sanitize_ubsan_dep *bool `android:"arch_variant"`
|
||||||
|
|
||||||
@@ -154,10 +156,21 @@ type vendorSnapshotLibraryProperties struct {
|
|||||||
Sanitize_minimal_dep *bool `android:"arch_variant"`
|
Sanitize_minimal_dep *bool `android:"arch_variant"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type snapshotSanitizer interface {
|
||||||
|
isSanitizerEnabled(t sanitizerType) bool
|
||||||
|
setSanitizerVariation(t sanitizerType, enabled bool)
|
||||||
|
}
|
||||||
|
|
||||||
type vendorSnapshotLibraryDecorator struct {
|
type vendorSnapshotLibraryDecorator struct {
|
||||||
vendorSnapshotModuleBase
|
vendorSnapshotModuleBase
|
||||||
*libraryDecorator
|
*libraryDecorator
|
||||||
properties vendorSnapshotLibraryProperties
|
properties vendorSnapshotLibraryProperties
|
||||||
|
sanitizerProperties struct {
|
||||||
|
CfiEnabled bool `blueprint:"mutated"`
|
||||||
|
|
||||||
|
// Library flags for cfi variant.
|
||||||
|
Cfi vendorSnapshotLibraryProperties `android:"arch_variant"`
|
||||||
|
}
|
||||||
androidMkVendorSuffix bool
|
androidMkVendorSuffix bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,11 +199,16 @@ func (p *vendorSnapshotLibraryDecorator) link(ctx ModuleContext,
|
|||||||
return p.libraryDecorator.link(ctx, flags, deps, objs)
|
return p.libraryDecorator.link(ctx, flags, deps, objs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if p.sanitizerProperties.CfiEnabled {
|
||||||
|
p.properties = p.sanitizerProperties.Cfi
|
||||||
|
}
|
||||||
|
|
||||||
if !p.matchesWithDevice(ctx.DeviceConfig()) {
|
if !p.matchesWithDevice(ctx.DeviceConfig()) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
p.libraryDecorator.exportIncludes(ctx)
|
p.libraryDecorator.reexportDirs(android.PathsForModuleSrc(ctx, p.properties.Export_include_dirs)...)
|
||||||
|
p.libraryDecorator.reexportSystemDirs(android.PathsForModuleSrc(ctx, p.properties.Export_system_include_dirs)...)
|
||||||
p.libraryDecorator.reexportFlags(p.properties.Export_flags...)
|
p.libraryDecorator.reexportFlags(p.properties.Export_flags...)
|
||||||
|
|
||||||
in := android.PathForModuleSrc(ctx, *p.properties.Src)
|
in := android.PathForModuleSrc(ctx, *p.properties.Src)
|
||||||
@@ -220,6 +238,27 @@ func (p *vendorSnapshotLibraryDecorator) nativeCoverage() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *vendorSnapshotLibraryDecorator) isSanitizerEnabled(t sanitizerType) bool {
|
||||||
|
switch t {
|
||||||
|
case cfi:
|
||||||
|
return p.sanitizerProperties.Cfi.Src != nil
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *vendorSnapshotLibraryDecorator) setSanitizerVariation(t sanitizerType, enabled bool) {
|
||||||
|
if !enabled {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch t {
|
||||||
|
case cfi:
|
||||||
|
p.sanitizerProperties.CfiEnabled = true
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func vendorSnapshotLibrary(suffix string) (*Module, *vendorSnapshotLibraryDecorator) {
|
func vendorSnapshotLibrary(suffix string) (*Module, *vendorSnapshotLibraryDecorator) {
|
||||||
module, library := NewLibrary(android.DeviceSupported)
|
module, library := NewLibrary(android.DeviceSupported)
|
||||||
|
|
||||||
@@ -244,7 +283,10 @@ func vendorSnapshotLibrary(suffix string) (*Module, *vendorSnapshotLibraryDecora
|
|||||||
module.installer = prebuilt
|
module.installer = prebuilt
|
||||||
|
|
||||||
prebuilt.init(module, suffix)
|
prebuilt.init(module, suffix)
|
||||||
module.AddProperties(&prebuilt.properties)
|
module.AddProperties(
|
||||||
|
&prebuilt.properties,
|
||||||
|
&prebuilt.sanitizerProperties,
|
||||||
|
)
|
||||||
|
|
||||||
return module, prebuilt
|
return module, prebuilt
|
||||||
}
|
}
|
||||||
@@ -267,6 +309,8 @@ func VendorSnapshotHeaderFactory() android.Module {
|
|||||||
return module.Init()
|
return module.Init()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ snapshotSanitizer = (*vendorSnapshotLibraryDecorator)(nil)
|
||||||
|
|
||||||
type vendorSnapshotBinaryProperties struct {
|
type vendorSnapshotBinaryProperties struct {
|
||||||
// Prebuilt file for each arch.
|
// Prebuilt file for each arch.
|
||||||
Src *string `android:"arch_variant"`
|
Src *string `android:"arch_variant"`
|
||||||
@@ -504,13 +548,17 @@ func isVendorSnapshotModule(m *Module, moduleDir string) bool {
|
|||||||
if l, ok := m.linker.(snapshotLibraryInterface); ok {
|
if l, ok := m.linker.(snapshotLibraryInterface); ok {
|
||||||
// TODO(b/65377115): add full support for sanitizer
|
// TODO(b/65377115): add full support for sanitizer
|
||||||
if m.sanitize != nil {
|
if m.sanitize != nil {
|
||||||
// cfi, scs and hwasan export both sanitized and unsanitized variants for static and header
|
// scs and hwasan export both sanitized and unsanitized variants for static and header
|
||||||
// Always use unsanitized variants of them.
|
// Always use unsanitized variants of them.
|
||||||
for _, t := range []sanitizerType{cfi, scs, hwasan} {
|
for _, t := range []sanitizerType{scs, hwasan} {
|
||||||
if !l.shared() && m.sanitize.isSanitizerEnabled(t) {
|
if !l.shared() && m.sanitize.isSanitizerEnabled(t) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// cfi also exports both variants. But for static, we capture both.
|
||||||
|
if !l.static() && !l.shared() && m.sanitize.isSanitizerEnabled(cfi) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if l.static() {
|
if l.static() {
|
||||||
return m.outputFile.Valid() && proptools.BoolDefault(m.VendorProperties.Vendor_available, true)
|
return m.outputFile.Valid() && proptools.BoolDefault(m.VendorProperties.Vendor_available, true)
|
||||||
@@ -604,6 +652,7 @@ func (c *vendorSnapshotSingleton) GenerateBuildActions(ctx android.SingletonCont
|
|||||||
ExportedDirs []string `json:",omitempty"`
|
ExportedDirs []string `json:",omitempty"`
|
||||||
ExportedSystemDirs []string `json:",omitempty"`
|
ExportedSystemDirs []string `json:",omitempty"`
|
||||||
ExportedFlags []string `json:",omitempty"`
|
ExportedFlags []string `json:",omitempty"`
|
||||||
|
Sanitize string `json:",omitempty"`
|
||||||
SanitizeMinimalDep bool `json:",omitempty"`
|
SanitizeMinimalDep bool `json:",omitempty"`
|
||||||
SanitizeUbsanDep bool `json:",omitempty"`
|
SanitizeUbsanDep bool `json:",omitempty"`
|
||||||
|
|
||||||
@@ -653,6 +702,7 @@ func (c *vendorSnapshotSingleton) GenerateBuildActions(ctx android.SingletonCont
|
|||||||
var propOut string
|
var propOut string
|
||||||
|
|
||||||
if l, ok := m.linker.(snapshotLibraryInterface); ok {
|
if l, ok := m.linker.(snapshotLibraryInterface); ok {
|
||||||
|
|
||||||
// library flags
|
// library flags
|
||||||
prop.ExportedFlags = l.exportedFlags()
|
prop.ExportedFlags = l.exportedFlags()
|
||||||
for _, dir := range l.exportedDirs() {
|
for _, dir := range l.exportedDirs() {
|
||||||
@@ -685,6 +735,15 @@ func (c *vendorSnapshotSingleton) GenerateBuildActions(ctx android.SingletonCont
|
|||||||
if libType != "header" {
|
if libType != "header" {
|
||||||
libPath := m.outputFile.Path()
|
libPath := m.outputFile.Path()
|
||||||
stem = libPath.Base()
|
stem = libPath.Base()
|
||||||
|
if l.static() && m.sanitize != nil && m.sanitize.isSanitizerEnabled(cfi) {
|
||||||
|
// both cfi and non-cfi variant for static libraries can exist.
|
||||||
|
// attach .cfi to distinguish between cfi and non-cfi.
|
||||||
|
// e.g. libbase.a -> libbase.cfi.a
|
||||||
|
ext := filepath.Ext(stem)
|
||||||
|
stem = strings.TrimSuffix(stem, ext) + ".cfi" + ext
|
||||||
|
prop.Sanitize = "cfi"
|
||||||
|
prop.ModuleName += ".cfi"
|
||||||
|
}
|
||||||
snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, libType, stem)
|
snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, libType, stem)
|
||||||
ret = append(ret, copyFile(ctx, libPath, snapshotLibOut))
|
ret = append(ret, copyFile(ctx, libPath, snapshotLibOut))
|
||||||
} else {
|
} else {
|
||||||
|
Reference in New Issue
Block a user