diff options
| -rw-r--r-- | android/module.go | 5 | ||||
| -rw-r--r-- | apex/apex_test.go | 12 | ||||
| -rw-r--r-- | apex/builder.go | 29 | ||||
| -rw-r--r-- | cc/config/global.go | 12 | ||||
| -rw-r--r-- | cc/library.go | 4 | ||||
| -rw-r--r-- | cc/ndk_library.go | 23 | ||||
| -rw-r--r-- | cc/ndk_sysroot.go | 7 | ||||
| -rw-r--r-- | cc/object.go | 30 | ||||
| -rw-r--r-- | cc/object_test.go | 2 | ||||
| -rw-r--r-- | cc/vndk.go | 46 | ||||
| -rwxr-xr-x | tests/sbom_test.sh | 21 |
11 files changed, 140 insertions, 51 deletions
diff --git a/android/module.go b/android/module.go index 76fe8dc45..ba474530d 100644 --- a/android/module.go +++ b/android/module.go @@ -550,6 +550,7 @@ type Module interface { ExportedToMake() bool InitRc() Paths VintfFragments() Paths + EffectiveLicenseKinds() []string EffectiveLicenseFiles() Paths AddProperties(props ...interface{}) @@ -2024,6 +2025,10 @@ func (m *ModuleBase) ExportedToMake() bool { return m.commonProperties.NamespaceExportedToMake } +func (m *ModuleBase) EffectiveLicenseKinds() []string { + return m.commonProperties.Effective_license_kinds +} + func (m *ModuleBase) EffectiveLicenseFiles() Paths { result := make(Paths, 0, len(m.commonProperties.Effective_license_text)) for _, p := range m.commonProperties.Effective_license_text { diff --git a/apex/apex_test.go b/apex/apex_test.go index 05c888abe..8a02a4a7f 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -7101,7 +7101,7 @@ func TestSymlinksFromApexToSystem(t *testing.T) { native_shared_libs: ["mylib"], java_libs: ["myjar"], updatable: true, - min_sdk_version: "current", + min_sdk_version: "33", } apex_key { @@ -7124,7 +7124,7 @@ func TestSymlinksFromApexToSystem(t *testing.T) { "myapex.updatable", "//apex_available:platform", ], - min_sdk_version: "current", + min_sdk_version: "33", } cc_library { @@ -7137,7 +7137,7 @@ func TestSymlinksFromApexToSystem(t *testing.T) { "myapex.updatable", "//apex_available:platform", ], - min_sdk_version: "current", + min_sdk_version: "33", } cc_library { @@ -7151,7 +7151,7 @@ func TestSymlinksFromApexToSystem(t *testing.T) { "myapex.updatable", "//apex_available:platform", ], - min_sdk_version: "current", + min_sdk_version: "33", } java_library { @@ -7165,7 +7165,7 @@ func TestSymlinksFromApexToSystem(t *testing.T) { "myapex.updatable", "//apex_available:platform", ], - min_sdk_version: "current", + min_sdk_version: "33", } java_library { @@ -7178,7 +7178,7 @@ func TestSymlinksFromApexToSystem(t *testing.T) { "myapex.updatable", "//apex_available:platform", ], - min_sdk_version: "current", + min_sdk_version: "33", } ` diff --git a/apex/builder.go b/apex/builder.go index e3b6f8e48..94aef496e 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -71,6 +71,9 @@ func init() { pctx.HostBinToolVariable("make_erofs", "make_erofs") pctx.HostBinToolVariable("apex_compression_tool", "apex_compression_tool") pctx.HostBinToolVariable("dexdeps", "dexdeps") + pctx.HostBinToolVariable("apex_sepolicy_tests", "apex_sepolicy_tests") + pctx.HostBinToolVariable("deapexer", "deapexer") + pctx.HostBinToolVariable("debugfs_static", "debugfs_static") pctx.SourcePathVariable("genNdkUsedbyApexPath", "build/soong/scripts/gen_ndk_usedby_apex.sh") } @@ -226,7 +229,12 @@ var ( Description: "Generate symbol list used by Apex", }, "image_dir", "readelf") - // Don't add more rules here. Consider using android.NewRuleBuilder instead. + apexSepolicyTestsRule = pctx.StaticRule("apexSepolicyTestsRule", blueprint.RuleParams{ + Command: `${deapexer} --debugfs_path ${debugfs_static} list -Z ${in} > ${out}.fc` + + `&& ${apex_sepolicy_tests} -f ${out}.fc && touch ${out}`, + CommandDeps: []string{"${apex_sepolicy_tests}", "${deapexer}", "${debugfs_static}"}, + Description: "run apex_sepolicy_tests", + }) ) // buildManifest creates buile rules to modify the input apex_manifest.json to add information @@ -872,6 +880,10 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) { args["implicits"] = strings.Join(implicits.Strings(), ",") args["outCommaList"] = signedOutputFile.String() } + var validations android.Paths + if suffix == imageApexSuffix { + validations = append(validations, runApexSepolicyTests(ctx, unsignedOutputFile.OutputPath)) + } ctx.Build(pctx, android.BuildParams{ Rule: rule, Description: "signapk", @@ -879,6 +891,7 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) { Input: unsignedOutputFile, Implicits: implicits, Args: args, + Validations: validations, }) if suffix == imageApexSuffix { a.outputApexFile = signedOutputFile @@ -1172,3 +1185,17 @@ func (a *apexBundle) buildCannedFsConfig(ctx android.ModuleContext) android.Outp return cannedFsConfig.OutputPath } + +// Runs apex_sepolicy_tests +// +// $ deapexer list -Z {apex_file} > {file_contexts} +// $ apex_sepolicy_tests -f {file_contexts} +func runApexSepolicyTests(ctx android.ModuleContext, apexFile android.OutputPath) android.Path { + timestamp := android.PathForModuleOut(ctx, "sepolicy_tests.timestamp") + ctx.Build(pctx, android.BuildParams{ + Rule: apexSepolicyTestsRule, + Input: apexFile, + Output: timestamp, + }) + return timestamp +} diff --git a/cc/config/global.go b/cc/config/global.go index 5b2191af7..a2d5cf439 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -111,6 +111,9 @@ var ( // Turn off FMA which got enabled by default in clang-r445002 (http://b/218805949) "-ffp-contract=off", + + // Turn off stack protector check for noreturn calls. (http://b/264965700) + "-mllvm -disable-check-noreturn-call", } commonGlobalConlyflags = []string{} @@ -147,6 +150,9 @@ var ( commonGlobalLldflags = []string{ "-fuse-ld=lld", "-Wl,--icf=safe", + + // Turn off stack protector check for noreturn calls. (http://b/264965700) + "-Wl,-mllvm,-disable-check-noreturn-call", } deviceGlobalCppflags = []string{ @@ -315,6 +321,9 @@ var ( } VersionScriptFlagPrefix = "-Wl,--version-script," + + VisibilityHiddenFlag = "-fvisibility=hidden" + VisibilityDefaultFlag = "-fvisibility=default" ) // BazelCcToolchainVars generates bzl file content containing variables for @@ -405,6 +414,9 @@ func init() { exportedVars.ExportString("VersionScriptFlagPrefix", VersionScriptFlagPrefix) + exportedVars.ExportString("VisibilityHiddenFlag", VisibilityHiddenFlag) + exportedVars.ExportString("VisibilityDefaultFlag", VisibilityDefaultFlag) + // Everything in these lists is a crime against abstraction and dependency tracking. // Do not add anything to this list. commonGlobalIncludes := []string{ diff --git a/cc/library.go b/cc/library.go index a9ada97d9..7504302fd 100644 --- a/cc/library.go +++ b/cc/library.go @@ -26,7 +26,6 @@ import ( "android/soong/android" "android/soong/bazel" "android/soong/bazel/cquery" - "android/soong/cc/config" "github.com/google/blueprint" "github.com/google/blueprint/pathtools" @@ -2261,8 +2260,7 @@ func (library *libraryDecorator) install(ctx ModuleContext, file android.Path) { !ctx.useVndk() && !ctx.inRamdisk() && !ctx.inVendorRamdisk() && !ctx.inRecovery() && ctx.Device() && library.baseLinker.sanitize.isUnsanitizedVariant() && ctx.isForPlatform() && !ctx.isPreventInstall() { - installPath := getNdkSysrootBase(ctx).Join( - ctx, "usr/lib", config.NDKTriple(ctx.toolchain()), file.Base()) + installPath := getUnversionedLibraryInstallPath(ctx).Join(ctx, file.Base()) ctx.ModuleBuild(pctx, android.ModuleBuildParams{ Rule: android.Cp, diff --git a/cc/ndk_library.go b/cc/ndk_library.go index 2473ba2a3..a82436135 100644 --- a/cc/ndk_library.go +++ b/cc/ndk_library.go @@ -528,17 +528,20 @@ func (stub *stubDecorator) nativeCoverage() bool { return false } -func (stub *stubDecorator) install(ctx ModuleContext, path android.Path) { - arch := ctx.Target().Arch.ArchType.Name - // arm64 isn't actually a multilib toolchain, so unlike the other LP64 - // architectures it's just installed to lib. - libDir := "lib" - if ctx.toolchain().Is64Bit() && arch != "arm64" { - libDir = "lib64" - } +// Returns the install path for unversioned NDK libraries (currently only static +// libraries). +func getUnversionedLibraryInstallPath(ctx ModuleContext) android.InstallPath { + return getNdkSysrootBase(ctx).Join(ctx, "usr/lib", config.NDKTriple(ctx.toolchain())) +} - installDir := getNdkInstallBase(ctx).Join(ctx, fmt.Sprintf( - "platforms/android-%s/arch-%s/usr/%s", stub.apiLevel, arch, libDir)) +// Returns the install path for versioned NDK libraries. These are most often +// stubs, but the same paths are used for CRT objects. +func getVersionedLibraryInstallPath(ctx ModuleContext, apiLevel android.ApiLevel) android.InstallPath { + return getUnversionedLibraryInstallPath(ctx).Join(ctx, apiLevel.String()) +} + +func (stub *stubDecorator) install(ctx ModuleContext, path android.Path) { + installDir := getVersionedLibraryInstallPath(ctx, stub.apiLevel) stub.installPath = ctx.InstallFile(installDir, path.Base(), path) } diff --git a/cc/ndk_sysroot.go b/cc/ndk_sysroot.go index 622558edf..dffc6c614 100644 --- a/cc/ndk_sysroot.go +++ b/cc/ndk_sysroot.go @@ -142,6 +142,13 @@ func (n *ndkSingleton) GenerateBuildActions(ctx android.SingletonContext) { staticLibInstallPaths, library.ndkSysrootPath) } } + + if object, ok := m.linker.(*objectLinker); ok { + if object.ndkSysrootPath != nil { + staticLibInstallPaths = append( + staticLibInstallPaths, object.ndkSysrootPath) + } + } } }) diff --git a/cc/object.go b/cc/object.go index ef4446746..d65cdea74 100644 --- a/cc/object.go +++ b/cc/object.go @@ -44,6 +44,10 @@ var ccObjectSdkMemberType = &librarySdkMemberType{ type objectLinker struct { *baseLinker Properties ObjectLinkerProperties + + // Location of the object in the sysroot. Empty if the object is not + // included in the NDK. + ndkSysrootPath android.Path } type objectBazelHandler struct { @@ -99,6 +103,10 @@ type ObjectLinkerProperties struct { // Indicates that this module is a CRT object. CRT objects will be split // into a variant per-API level between min_sdk_version and current. Crt *bool + + // Indicates that this module should not be included in the NDK sysroot. + // Only applies to CRT objects. Defaults to false. + Exclude_from_ndk_sysroot *bool } func newObject(hod android.HostOrDeviceSupported) *Module { @@ -268,17 +276,28 @@ func (object *objectLinker) link(ctx ModuleContext, objs = objs.Append(deps.Objs) - var outputFile android.Path + var output android.WritablePath builderFlags := flagsToBuilderFlags(flags) outputName := ctx.ModuleName() if !strings.HasSuffix(outputName, objectExtension) { outputName += objectExtension } - if len(objs.objFiles) == 1 && String(object.Properties.Linker_script) == "" { - output := android.PathForModuleOut(ctx, outputName) - outputFile = output + // isForPlatform is terribly named and actually means isNotApex. + if Bool(object.Properties.Crt) && + !Bool(object.Properties.Exclude_from_ndk_sysroot) && ctx.useSdk() && + ctx.isSdkVariant() && ctx.isForPlatform() { + output = getVersionedLibraryInstallPath(ctx, + nativeApiLevelOrPanic(ctx, ctx.sdkVersion())).Join(ctx, outputName) + object.ndkSysrootPath = output + } else { + output = android.PathForModuleOut(ctx, outputName) + } + + outputFile := output + + if len(objs.objFiles) == 1 && String(object.Properties.Linker_script) == "" { if String(object.Properties.Prefix_symbols) != "" { transformBinaryPrefixSymbols(ctx, String(object.Properties.Prefix_symbols), objs.objFiles[0], builderFlags, output) @@ -290,9 +309,6 @@ func (object *objectLinker) link(ctx ModuleContext, }) } } else { - output := android.PathForModuleOut(ctx, outputName) - outputFile = output - if String(object.Properties.Prefix_symbols) != "" { input := android.PathForModuleOut(ctx, "unprefixed", outputName) transformBinaryPrefixSymbols(ctx, String(object.Properties.Prefix_symbols), input, diff --git a/cc/object_test.go b/cc/object_test.go index 5359a357a..b1e2a0fd2 100644 --- a/cc/object_test.go +++ b/cc/object_test.go @@ -65,7 +65,7 @@ func TestUseCrtObjectOfCorrectVersion(t *testing.T) { variant := "android_arm64_armv8-a_sdk" crt := ctx.ModuleForTests("bin", variant).Rule("ld").Args["crtBegin"] android.AssertStringDoesContain(t, "crt dep of sdk variant", crt, - variant+"_29/crtbegin_dynamic.o") + "29/crtbegin_dynamic.o") // platform variant uses the crt object built for platform variant = "android_arm64_armv8-a" diff --git a/cc/vndk.go b/cc/vndk.go index 3b7c87dea..be66cd79f 100644 --- a/cc/vndk.go +++ b/cc/vndk.go @@ -674,8 +674,12 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex snapshotArchDir := filepath.Join(snapshotDir, ctx.DeviceConfig().DeviceArch()) configsDir := filepath.Join(snapshotArchDir, "configs") + noticeDir := filepath.Join(snapshotArchDir, "NOTICE_FILES") includeDir := filepath.Join(snapshotArchDir, "include") + // set of notice files copied. + noticeBuilt := make(map[string]bool) + // paths of VNDK modules for GPL license checking modulePaths := make(map[string]string) @@ -700,28 +704,36 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, "shared", vndkType, libPath.Base()) ret = append(ret, snapshot.CopyFileRule(pctx, ctx, libPath, snapshotLibOut)) + // json struct to export snapshot information + prop := struct { + LicenseKinds []string `json:",omitempty"` + LicenseTexts []string `json:",omitempty"` + ExportedDirs []string `json:",omitempty"` + ExportedSystemDirs []string `json:",omitempty"` + ExportedFlags []string `json:",omitempty"` + RelativeInstallPath string `json:",omitempty"` + }{} + + prop.LicenseKinds = m.EffectiveLicenseKinds() + prop.LicenseTexts = m.EffectiveLicenseFiles().Strings() + if ctx.Config().VndkSnapshotBuildArtifacts() { - prop := struct { - ExportedDirs []string `json:",omitempty"` - ExportedSystemDirs []string `json:",omitempty"` - ExportedFlags []string `json:",omitempty"` - RelativeInstallPath string `json:",omitempty"` - }{} exportedInfo := ctx.ModuleProvider(m, FlagExporterInfoProvider).(FlagExporterInfo) prop.ExportedFlags = exportedInfo.Flags prop.ExportedDirs = exportedInfo.IncludeDirs.Strings() prop.ExportedSystemDirs = exportedInfo.SystemIncludeDirs.Strings() prop.RelativeInstallPath = m.RelativeInstallPath() + } - propOut := snapshotLibOut + ".json" + propOut := snapshotLibOut + ".json" - j, err := json.Marshal(prop) - if err != nil { - ctx.Errorf("json marshal to %q failed: %#v", propOut, err) - return nil, false - } - ret = append(ret, snapshot.WriteStringToFileRule(ctx, string(j), propOut)) + j, err := json.Marshal(prop) + if err != nil { + ctx.Errorf("json marshal to %q failed: %#v", propOut, err) + return nil, false } + ret = append(ret, snapshot.WriteStringToFileRule(ctx, string(j), propOut)) + return ret, true } @@ -761,6 +773,14 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex moduleNames[stem] = ctx.ModuleName(m) modulePaths[stem] = ctx.ModuleDir(m) + for _, notice := range m.EffectiveLicenseFiles() { + if _, ok := noticeBuilt[notice.String()]; !ok { + noticeBuilt[notice.String()] = true + snapshotOutputs = append(snapshotOutputs, snapshot.CopyFileRule( + pctx, ctx, notice, filepath.Join(noticeDir, notice.String()))) + } + } + if ctx.Config().VndkSnapshotBuildArtifacts() { headers = append(headers, m.SnapshotHeaders()...) } diff --git a/tests/sbom_test.sh b/tests/sbom_test.sh index a507349b8..2f154cde5 100755 --- a/tests/sbom_test.sh +++ b/tests/sbom_test.sh @@ -98,19 +98,15 @@ diff_excludes[system]=\ -I /system/lib64/libkm_compat.so \ -I /system/lib64/vndk-29 \ -I /system/lib64/vndk-sp-29 \ - -I /system/lib/modules \ -I /system/lib/vndk-29 \ -I /system/lib/vndk-sp-29 \ - -I /system/product \ - -I /system/system_ext \ -I /system/usr/icu \ - -I /system/vendor \ -I /vendor_dlkm/etc" - function diff_files { - file_list_file="$1"; - files_in_spdx_file="$2" - partition_name="$3" +function diff_files { + file_list_file="$1"; shift + files_in_spdx_file="$1"; shift + partition_name="$1"; shift exclude= if [ -v 'diff_excludes[$partition_name]' ]; then exclude=${diff_excludes[$partition_name]} @@ -168,9 +164,9 @@ for f in $EROFS_IMAGES; do all_dirs=$(echo "$all_dirs" | cut -d ' ' -f1 --complement -s) entries=$($dump_erofs --ls --path "$dir" $f | tail -n +11) while read -r entry; do - type=$(echo $entry | awk -F ' ' '{print $2}') + inode_type=$(echo $entry | awk -F ' ' '{print $2}') name=$(echo $entry | awk -F ' ' '{print $3}') - case $type in + case $inode_type in "2") # directory all_dirs=$(echo "$all_dirs $dir/$name" | sed 's/^\s*//') ;; @@ -204,6 +200,11 @@ for f in $RAMDISK_IMAGES; do partition_name=$(basename $f | cut -d. -f1) file_list_file="${sbom_test}/sbom-${partition_name}-files.txt" files_in_spdx_file="${sbom_test}/sbom-${partition_name}-files-in-spdx.txt" + # lz4 decompress $f to stdout + # cpio list all entries like ls -l + # grep filter normal files and symlinks + # awk get entry names + # sed remove partition name from entry names $lz4 -c -d $f | cpio -tv 2>/dev/null | grep '^[-l]' | awk -F ' ' '{print $9}' | sed "s:^:/$partition_name/:" | sort -n > "$file_list_file" grep "FileName: /${partition_name}/" $product_out/sbom.spdx | sed 's/^FileName: //' | sort -n > "$files_in_spdx_file" |