apex: add apex_manifest.pb in file_contexts
apex_manifest.pb is added to payload.img by the build system and is
supposed to be read by apexd during activation.
So, it should be labeled as "system_file" so that apexd can read it
regardless of how file_contexts is defined.
Bug: 159767275
Test: add an apex with file_contexts with everything as vendor_file
apexd should activate the apex.
Change-Id: Ie34eb7ad905828976152d67a7dfabf0add0a5de4
diff --git a/apex/apex.go b/apex/apex.go
index 58cbb13..ced8a6c 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -16,7 +16,6 @@
import (
"fmt"
- "path"
"path/filepath"
"sort"
"strings"
@@ -1242,7 +1241,7 @@
container_certificate_file android.Path
container_private_key_file android.Path
- fileContexts android.Path
+ fileContexts android.WritablePath
// list of files to be included in this apex
filesInfo []apexFile
@@ -2174,22 +2173,6 @@
a.installDir = android.PathForModuleInstall(ctx, "apex")
a.filesInfo = filesInfo
- if a.properties.ApexType != zipApex {
- if a.properties.File_contexts == nil {
- a.fileContexts = android.PathForSource(ctx, "system/sepolicy/apex", ctx.ModuleName()+"-file_contexts")
- } else {
- a.fileContexts = android.PathForModuleSrc(ctx, *a.properties.File_contexts)
- if a.Platform() {
- if matched, err := path.Match("system/sepolicy/**/*", a.fileContexts.String()); err != nil || !matched {
- ctx.PropertyErrorf("file_contexts", "should be under system/sepolicy, but %q", a.fileContexts)
- }
- }
- }
- if !android.ExistentPathForSource(ctx, a.fileContexts.String()).Valid() {
- ctx.PropertyErrorf("file_contexts", "cannot find file_contexts file: %q", a.fileContexts)
- return
- }
- }
// Optimization. If we are building bundled APEX, for the files that are gathered due to the
// transitive dependencies, don't place them inside the APEX, but place a symlink pointing
// the same library in the system partition, thus effectively sharing the same libraries
@@ -2213,6 +2196,8 @@
// prepare apex_manifest.json
a.buildManifest(ctx, provideNativeLibs, requireNativeLibs)
+ a.buildFileContexts(ctx)
+
a.setCertificateAndPrivateKey(ctx)
if a.properties.ApexType == flattenedApex {
a.buildFlattenedApex(ctx)
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 38c8489..910e53a 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -3275,110 +3275,104 @@
}
}
-func TestFileContexts(t *testing.T) {
+func TestFileContexts_FindInDefaultLocationIfNotSet(t *testing.T) {
ctx, _ := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- }
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
`)
module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
- apexRule := module.Rule("apexRule")
- actual := apexRule.Args["file_contexts"]
- expected := "system/sepolicy/apex/myapex-file_contexts"
- if actual != expected {
- t.Errorf("wrong file_contexts. expected %q. actual %q", expected, actual)
- }
+ rule := module.Output("file_contexts")
+ ensureContains(t, rule.RuleParams.Command, "cat system/sepolicy/apex/myapex-file_contexts")
+}
+func TestFileContexts_ShouldBeUnderSystemSepolicyForSystemApexes(t *testing.T) {
testApexError(t, `"myapex" .*: file_contexts: should be under system/sepolicy`, `
- apex {
- name: "myapex",
- key: "myapex.key",
- file_contexts: "my_own_file_contexts",
- }
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ file_contexts: "my_own_file_contexts",
+ }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
`, withFiles(map[string][]byte{
"my_own_file_contexts": nil,
}))
+}
+func TestFileContexts_ProductSpecificApexes(t *testing.T) {
testApexError(t, `"myapex" .*: file_contexts: cannot find`, `
- apex {
- name: "myapex",
- key: "myapex.key",
- product_specific: true,
- file_contexts: "product_specific_file_contexts",
- }
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ product_specific: true,
+ file_contexts: "product_specific_file_contexts",
+ }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
`)
- ctx, _ = testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- product_specific: true,
- file_contexts: "product_specific_file_contexts",
- }
+ ctx, _ := testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ product_specific: true,
+ file_contexts: "product_specific_file_contexts",
+ }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
`, withFiles(map[string][]byte{
"product_specific_file_contexts": nil,
}))
- module = ctx.ModuleForTests("myapex", "android_common_myapex_image")
- apexRule = module.Rule("apexRule")
- actual = apexRule.Args["file_contexts"]
- expected = "product_specific_file_contexts"
- if actual != expected {
- t.Errorf("wrong file_contexts. expected %q. actual %q", expected, actual)
- }
+ module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
+ rule := module.Output("file_contexts")
+ ensureContains(t, rule.RuleParams.Command, "cat product_specific_file_contexts")
+}
- ctx, _ = testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- product_specific: true,
- file_contexts: ":my-file-contexts",
- }
+func TestFileContexts_SetViaFileGroup(t *testing.T) {
+ ctx, _ := testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ product_specific: true,
+ file_contexts: ":my-file-contexts",
+ }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
- filegroup {
- name: "my-file-contexts",
- srcs: ["product_specific_file_contexts"],
- }
+ filegroup {
+ name: "my-file-contexts",
+ srcs: ["product_specific_file_contexts"],
+ }
`, withFiles(map[string][]byte{
"product_specific_file_contexts": nil,
}))
- module = ctx.ModuleForTests("myapex", "android_common_myapex_image")
- apexRule = module.Rule("apexRule")
- actual = apexRule.Args["file_contexts"]
- expected = "product_specific_file_contexts"
- if actual != expected {
- t.Errorf("wrong file_contexts. expected %q. actual %q", expected, actual)
- }
+ module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
+ rule := module.Output("file_contexts")
+ ensureContains(t, rule.RuleParams.Command, "cat product_specific_file_contexts")
}
func TestApexKeyFromOtherModule(t *testing.T) {
diff --git a/apex/builder.go b/apex/builder.go
index af43417..ac3e640 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -17,6 +17,7 @@
import (
"encoding/json"
"fmt"
+ "path"
"path/filepath"
"runtime"
"sort"
@@ -231,6 +232,38 @@
})
}
+func (a *apexBundle) buildFileContexts(ctx android.ModuleContext) {
+ if a.properties.ApexType == zipApex {
+ return
+ }
+ var fileContexts android.Path
+ if a.properties.File_contexts == nil {
+ fileContexts = android.PathForSource(ctx, "system/sepolicy/apex", ctx.ModuleName()+"-file_contexts")
+ } else {
+ fileContexts = android.PathForModuleSrc(ctx, *a.properties.File_contexts)
+ }
+ if a.Platform() {
+ if matched, err := path.Match("system/sepolicy/**/*", fileContexts.String()); err != nil || !matched {
+ ctx.PropertyErrorf("file_contexts", "should be under system/sepolicy, but %q", fileContexts)
+ return
+ }
+ }
+ if !android.ExistentPathForSource(ctx, fileContexts.String()).Valid() {
+ ctx.PropertyErrorf("file_contexts", "cannot find file_contexts file: %q", a.fileContexts)
+ return
+ }
+
+ output := android.PathForModuleOut(ctx, "file_contexts")
+ rule := android.NewRuleBuilder()
+ rule.Command().Text("rm").FlagWithOutput("-f ", output)
+ rule.Command().Text("cat").Input(fileContexts).Text(">>").Output(output)
+ rule.Command().Text("echo").Text(">>").Output(output)
+ rule.Command().Text("echo").Flag("/apex_manifest\\\\.pb u:object_r:system_file:s0").Text(">>").Output(output)
+ rule.Build(pctx, ctx, "file_contexts."+a.Name(), "Generate file_contexts")
+
+ a.fileContexts = output.OutputPath
+}
+
func (a *apexBundle) buildNoticeFiles(ctx android.ModuleContext, apexFileName string) android.NoticeOutputs {
var noticeFiles android.Paths