diff --git a/apex/apex.go b/apex/apex.go index 24cfb5438..c330f8254 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -16,7 +16,6 @@ package apex import ( "fmt" - "path" "path/filepath" "sort" "strings" @@ -1242,7 +1241,7 @@ type apexBundle struct { 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 @@ -2195,22 +2194,6 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { 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 @@ -2234,6 +2217,8 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { // 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 7b72fe6fc..f1638c3bc 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -3480,110 +3480,104 @@ func TestApexInVariousPartition(t *testing.T) { } } -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 cef956f31..ede11d05e 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -17,6 +17,7 @@ package apex import ( "encoding/json" "fmt" + "path" "path/filepath" "runtime" "sort" @@ -231,6 +232,38 @@ func (a *apexBundle) buildManifest(ctx android.ModuleContext, provideNativeLibs, }) } +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