Inseob Kim | 5339184 | 2024-03-29 17:44:07 +0900 | [diff] [blame] | 1 | // Copyright (C) 2024 The Android Open Source Project |
| 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | // you may not use this file except in compliance with the License. |
| 5 | // You may obtain a copy of the License at |
| 6 | // |
| 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | // |
| 9 | // Unless required by applicable law or agreed to in writing, software |
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | // See the License for the specific language governing permissions and |
| 13 | // limitations under the License. |
| 14 | |
| 15 | package filesystem |
| 16 | |
| 17 | import ( |
| 18 | "path/filepath" |
| 19 | "strings" |
| 20 | |
| 21 | "android/soong/android" |
| 22 | ) |
| 23 | |
| 24 | type fsverityProperties struct { |
| 25 | // Patterns of files for fsverity metadata generation. For each matched file, a .fsv_meta file |
| 26 | // will be generated and included to the filesystem image. |
| 27 | // etc/security/fsverity/BuildManifest.apk will also be generated which contains information |
| 28 | // about generated .fsv_meta files. |
| 29 | Inputs []string |
Inseob Kim | 1e6afed | 2024-04-03 17:24:54 +0900 | [diff] [blame] | 30 | |
| 31 | // APK libraries to link against, for etc/security/fsverity/BuildManifest.apk |
| 32 | Libs []string `android:"path"` |
Inseob Kim | 5339184 | 2024-03-29 17:44:07 +0900 | [diff] [blame] | 33 | } |
| 34 | |
| 35 | func (f *filesystem) writeManifestGeneratorListFile(ctx android.ModuleContext, outputPath android.OutputPath, matchedSpecs []android.PackagingSpec, rebasedDir android.OutputPath) { |
| 36 | var buf strings.Builder |
| 37 | for _, spec := range matchedSpecs { |
| 38 | buf.WriteString(rebasedDir.Join(ctx, spec.RelPathInPackage()).String()) |
| 39 | buf.WriteRune('\n') |
| 40 | } |
| 41 | android.WriteFileRuleVerbatim(ctx, outputPath, buf.String()) |
| 42 | } |
| 43 | |
| 44 | func (f *filesystem) buildFsverityMetadataFiles(ctx android.ModuleContext, builder *android.RuleBuilder, specs map[string]android.PackagingSpec, rootDir android.OutputPath, rebasedDir android.OutputPath) { |
| 45 | match := func(path string) bool { |
| 46 | for _, pattern := range f.properties.Fsverity.Inputs { |
| 47 | if matched, err := filepath.Match(pattern, path); matched { |
| 48 | return true |
| 49 | } else if err != nil { |
| 50 | ctx.PropertyErrorf("fsverity.inputs", "bad pattern %q", pattern) |
| 51 | return false |
| 52 | } |
| 53 | } |
| 54 | return false |
| 55 | } |
| 56 | |
| 57 | var matchedSpecs []android.PackagingSpec |
| 58 | for _, relPath := range android.SortedKeys(specs) { |
| 59 | if match(relPath) { |
| 60 | matchedSpecs = append(matchedSpecs, specs[relPath]) |
| 61 | } |
| 62 | } |
| 63 | |
| 64 | if len(matchedSpecs) == 0 { |
| 65 | return |
| 66 | } |
| 67 | |
| 68 | fsverityBuilderPath := android.PathForModuleOut(ctx, "fsverity_builder.sh") |
| 69 | metadataGeneratorPath := ctx.Config().HostToolPath(ctx, "fsverity_metadata_generator") |
| 70 | fsverityPath := ctx.Config().HostToolPath(ctx, "fsverity") |
| 71 | |
| 72 | cmd := builder.Command().Tool(fsverityBuilderPath) |
| 73 | |
| 74 | // STEP 1: generate .fsv_meta |
| 75 | var sb strings.Builder |
| 76 | sb.WriteString("set -e\n") |
| 77 | cmd.Implicit(metadataGeneratorPath).Implicit(fsverityPath) |
| 78 | for _, spec := range matchedSpecs { |
| 79 | // srcPath is copied by CopySpecsToDir() |
| 80 | srcPath := rebasedDir.Join(ctx, spec.RelPathInPackage()) |
| 81 | destPath := rebasedDir.Join(ctx, spec.RelPathInPackage()+".fsv_meta") |
| 82 | sb.WriteString(metadataGeneratorPath.String()) |
| 83 | sb.WriteString(" --fsverity-path ") |
| 84 | sb.WriteString(fsverityPath.String()) |
| 85 | sb.WriteString(" --signature none --hash-alg sha256 --output ") |
| 86 | sb.WriteString(destPath.String()) |
| 87 | sb.WriteRune(' ') |
| 88 | sb.WriteString(srcPath.String()) |
| 89 | sb.WriteRune('\n') |
| 90 | } |
| 91 | |
| 92 | // STEP 2: generate signed BuildManifest.apk |
| 93 | // STEP 2-1: generate build_manifest.pb |
| 94 | assetsPath := android.PathForModuleOut(ctx, "fsverity_manifest/assets") |
| 95 | manifestPbPath := assetsPath.Join(ctx, "build_manifest.pb") |
| 96 | manifestGeneratorPath := ctx.Config().HostToolPath(ctx, "fsverity_manifest_generator") |
| 97 | cmd.Implicit(manifestGeneratorPath) |
| 98 | sb.WriteString("rm -rf ") |
| 99 | sb.WriteString(assetsPath.String()) |
| 100 | sb.WriteString(" && mkdir -p ") |
| 101 | sb.WriteString(assetsPath.String()) |
| 102 | sb.WriteRune('\n') |
| 103 | sb.WriteString(manifestGeneratorPath.String()) |
| 104 | sb.WriteString(" --fsverity-path ") |
| 105 | sb.WriteString(fsverityPath.String()) |
| 106 | sb.WriteString(" --base-dir ") |
| 107 | sb.WriteString(rootDir.String()) |
| 108 | sb.WriteString(" --output ") |
| 109 | sb.WriteString(manifestPbPath.String()) |
| 110 | sb.WriteRune(' ') |
| 111 | |
| 112 | manifestGeneratorListPath := android.PathForModuleOut(ctx, "fsverity_manifest.list") |
| 113 | f.writeManifestGeneratorListFile(ctx, manifestGeneratorListPath.OutputPath, matchedSpecs, rebasedDir) |
| 114 | sb.WriteRune('@') |
| 115 | sb.WriteString(manifestGeneratorListPath.String()) |
| 116 | sb.WriteRune('\n') |
| 117 | cmd.Implicit(manifestGeneratorListPath) |
| 118 | |
| 119 | // STEP 2-2: generate BuildManifest.apk (unsigned) |
| 120 | aapt2Path := ctx.Config().HostToolPath(ctx, "aapt2") |
| 121 | apkPath := rebasedDir.Join(ctx, "etc", "security", "fsverity", "BuildManifest.apk") |
| 122 | manifestTemplatePath := android.PathForSource(ctx, "system/security/fsverity/AndroidManifest.xml") |
Inseob Kim | 1e6afed | 2024-04-03 17:24:54 +0900 | [diff] [blame] | 123 | libs := android.PathsForModuleSrc(ctx, f.properties.Fsverity.Libs) |
Inseob Kim | 5339184 | 2024-03-29 17:44:07 +0900 | [diff] [blame] | 124 | cmd.Implicit(aapt2Path) |
| 125 | cmd.Implicit(manifestTemplatePath) |
Inseob Kim | 1e6afed | 2024-04-03 17:24:54 +0900 | [diff] [blame] | 126 | cmd.Implicits(libs) |
Inseob Kim | 5339184 | 2024-03-29 17:44:07 +0900 | [diff] [blame] | 127 | |
| 128 | sb.WriteString(aapt2Path.String()) |
| 129 | sb.WriteString(" link -o ") |
| 130 | sb.WriteString(apkPath.String()) |
| 131 | sb.WriteString(" -A ") |
| 132 | sb.WriteString(assetsPath.String()) |
Inseob Kim | 1e6afed | 2024-04-03 17:24:54 +0900 | [diff] [blame] | 133 | for _, lib := range libs { |
| 134 | sb.WriteString(" -I ") |
| 135 | sb.WriteString(lib.String()) |
| 136 | } |
Inseob Kim | 5339184 | 2024-03-29 17:44:07 +0900 | [diff] [blame] | 137 | minSdkVersion := ctx.Config().PlatformSdkCodename() |
| 138 | if minSdkVersion == "REL" { |
| 139 | minSdkVersion = ctx.Config().PlatformSdkVersion().String() |
| 140 | } |
| 141 | sb.WriteString(" --min-sdk-version ") |
| 142 | sb.WriteString(minSdkVersion) |
| 143 | sb.WriteString(" --version-code ") |
| 144 | sb.WriteString(ctx.Config().PlatformSdkVersion().String()) |
| 145 | sb.WriteString(" --version-name ") |
| 146 | sb.WriteString(ctx.Config().AppsDefaultVersionName()) |
| 147 | sb.WriteString(" --manifest ") |
| 148 | sb.WriteString(manifestTemplatePath.String()) |
| 149 | sb.WriteString(" --rename-manifest-package com.android.security.fsverity_metadata.") |
| 150 | sb.WriteString(f.partitionName()) |
| 151 | sb.WriteRune('\n') |
| 152 | |
| 153 | // STEP 2-3: sign BuildManifest.apk |
| 154 | apksignerPath := ctx.Config().HostToolPath(ctx, "apksigner") |
| 155 | pemPath, keyPath := ctx.Config().DefaultAppCertificate(ctx) |
| 156 | cmd.Implicit(apksignerPath) |
| 157 | cmd.Implicit(pemPath) |
| 158 | cmd.Implicit(keyPath) |
| 159 | sb.WriteString(apksignerPath.String()) |
| 160 | sb.WriteString(" sign --in ") |
| 161 | sb.WriteString(apkPath.String()) |
| 162 | sb.WriteString(" --cert ") |
| 163 | sb.WriteString(pemPath.String()) |
| 164 | sb.WriteString(" --key ") |
| 165 | sb.WriteString(keyPath.String()) |
| 166 | sb.WriteRune('\n') |
| 167 | |
| 168 | android.WriteExecutableFileRuleVerbatim(ctx, fsverityBuilderPath, sb.String()) |
| 169 | } |