blob: 9ae782638ce5667373baa8997fa49b709cde36c8 [file] [log] [blame]
Inseob Kimd5816612021-09-15 03:01:05 +00001// Copyright 2021 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
15package selinux
16
17import (
18 "path/filepath"
19 "sort"
20
21 "android/soong/android"
22)
23
24func init() {
25 ctx := android.InitRegistrationContext
LaMont Jones3ee89842023-05-16 16:59:17 +000026 ctx.RegisterParallelSingletonModuleType("se_freeze_test", freezeTestFactory)
Inseob Kimd5816612021-09-15 03:01:05 +000027}
28
29// se_freeze_test compares the plat sepolicy with the prebuilt sepolicy. Additional directories can
30// be specified via Makefile variables: SEPOLICY_FREEZE_TEST_EXTRA_DIRS and
31// SEPOLICY_FREEZE_TEST_EXTRA_PREBUILT_DIRS.
32func freezeTestFactory() android.SingletonModule {
33 f := &freezeTestModule{}
34 android.InitAndroidModule(f)
35 return f
36}
37
38type freezeTestModule struct {
39 android.SingletonModuleBase
40 freezeTestTimestamp android.ModuleOutPath
41}
42
43func (f *freezeTestModule) GenerateSingletonBuildActions(ctx android.SingletonContext) {
44 // does nothing; se_freeze_test is a singeton because two freeze test modules don't make sense.
45}
46
47func (f *freezeTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
48 platformVersion := ctx.DeviceConfig().PlatformSepolicyVersion()
49 totVersion := ctx.DeviceConfig().TotSepolicyVersion()
50
51 extraDirs := ctx.DeviceConfig().SepolicyFreezeTestExtraDirs()
52 extraPrebuiltDirs := ctx.DeviceConfig().SepolicyFreezeTestExtraPrebuiltDirs()
53 f.freezeTestTimestamp = android.PathForModuleOut(ctx, "freeze_test")
54
55 if platformVersion == totVersion {
56 if len(extraDirs) > 0 || len(extraPrebuiltDirs) > 0 {
57 ctx.ModuleErrorf("SEPOLICY_FREEZE_TEST_EXTRA_DIRS or SEPOLICY_FREEZE_TEST_EXTRA_PREBUILT_DIRS cannot be set before system/sepolicy freezes.")
58 return
59 }
60
61 // we still build a rule to prevent possible regression
62 android.WriteFileRule(ctx, f.freezeTestTimestamp, ";; no freeze tests needed before system/sepolicy freezes")
63 return
64 }
65
66 if len(extraDirs) != len(extraPrebuiltDirs) {
67 ctx.ModuleErrorf("SEPOLICY_FREEZE_TEST_EXTRA_DIRS and SEPOLICY_FREEZE_TEST_EXTRA_PREBUILT_DIRS must have the same number of directories.")
68 return
69 }
70
71 platPublic := filepath.Join(ctx.ModuleDir(), "public")
72 platPrivate := filepath.Join(ctx.ModuleDir(), "private")
73 prebuiltPublic := filepath.Join(ctx.ModuleDir(), "prebuilts", "api", platformVersion, "public")
74 prebuiltPrivate := filepath.Join(ctx.ModuleDir(), "prebuilts", "api", platformVersion, "private")
75
76 sourceDirs := append(extraDirs, platPublic, platPrivate)
77 prebuiltDirs := append(extraPrebuiltDirs, prebuiltPublic, prebuiltPrivate)
78
79 var implicits []string
80 for _, dir := range append(sourceDirs, prebuiltDirs...) {
81 glob, err := ctx.GlobWithDeps(dir+"/**/*", []string{"bug_map"} /* exclude */)
82 if err != nil {
83 ctx.ModuleErrorf("failed to glob sepolicy dir %q: %s", dir, err.Error())
84 return
85 }
86 implicits = append(implicits, glob...)
87 }
88 sort.Strings(implicits)
89
90 rule := android.NewRuleBuilder(pctx, ctx)
91
92 for idx, _ := range sourceDirs {
93 rule.Command().Text("diff").
94 Flag("-r").
95 Flag("-q").
96 FlagWithArg("-x ", "bug_map"). // exclude
97 Text(sourceDirs[idx]).
98 Text(prebuiltDirs[idx])
99 }
100
101 rule.Command().Text("touch").
102 Output(f.freezeTestTimestamp).
103 Implicits(android.PathsForSource(ctx, implicits))
104
105 rule.Build("sepolicy_freeze_test", "sepolicy_freeze_test")
106}
107
108func (f *freezeTestModule) AndroidMkEntries() []android.AndroidMkEntries {
109 return []android.AndroidMkEntries{android.AndroidMkEntries{
110 Class: "FAKE",
111 // OutputFile is needed, even though BUILD_PHONY_PACKAGE doesn't use it.
112 // Without OutputFile this module won't be exported to Makefile.
113 OutputFile: android.OptionalPathForPath(f.freezeTestTimestamp),
114 Include: "$(BUILD_PHONY_PACKAGE)",
115 ExtraEntries: []android.AndroidMkExtraEntriesFunc{
116 func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
117 entries.SetString("LOCAL_ADDITIONAL_DEPENDENCIES", f.freezeTestTimestamp.String())
118 },
119 },
120 }}
121}