Inseob Kim | d581661 | 2021-09-15 03:01:05 +0000 | [diff] [blame] | 1 | // 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 | |
| 15 | package selinux |
| 16 | |
| 17 | import ( |
Inseob Kim | d581661 | 2021-09-15 03:01:05 +0000 | [diff] [blame] | 18 | "sort" |
| 19 | |
| 20 | "android/soong/android" |
| 21 | ) |
| 22 | |
Inseob Kim | 36d9d39 | 2023-09-04 17:40:03 +0900 | [diff] [blame] | 23 | var currentCilTag = dependencyTag{name: "current_cil"} |
| 24 | var prebuiltCilTag = dependencyTag{name: "prebuilt_cil"} |
| 25 | |
Inseob Kim | d581661 | 2021-09-15 03:01:05 +0000 | [diff] [blame] | 26 | func init() { |
| 27 | ctx := android.InitRegistrationContext |
LaMont Jones | 3ee8984 | 2023-05-16 16:59:17 +0000 | [diff] [blame] | 28 | ctx.RegisterParallelSingletonModuleType("se_freeze_test", freezeTestFactory) |
Inseob Kim | d581661 | 2021-09-15 03:01:05 +0000 | [diff] [blame] | 29 | } |
| 30 | |
| 31 | // se_freeze_test compares the plat sepolicy with the prebuilt sepolicy. Additional directories can |
| 32 | // be specified via Makefile variables: SEPOLICY_FREEZE_TEST_EXTRA_DIRS and |
| 33 | // SEPOLICY_FREEZE_TEST_EXTRA_PREBUILT_DIRS. |
| 34 | func freezeTestFactory() android.SingletonModule { |
| 35 | f := &freezeTestModule{} |
| 36 | android.InitAndroidModule(f) |
Inseob Kim | 36d9d39 | 2023-09-04 17:40:03 +0900 | [diff] [blame] | 37 | android.AddLoadHook(f, func(ctx android.LoadHookContext) { |
| 38 | f.loadHook(ctx) |
| 39 | }) |
Inseob Kim | d581661 | 2021-09-15 03:01:05 +0000 | [diff] [blame] | 40 | return f |
| 41 | } |
| 42 | |
| 43 | type freezeTestModule struct { |
| 44 | android.SingletonModuleBase |
| 45 | freezeTestTimestamp android.ModuleOutPath |
| 46 | } |
| 47 | |
Inseob Kim | 3e34b72 | 2023-12-11 18:15:42 +0900 | [diff] [blame] | 48 | func (f *freezeTestModule) shouldRunTest(ctx android.EarlyModuleContext) bool { |
| 49 | val, _ := ctx.Config().GetBuildFlag("RELEASE_BOARD_API_LEVEL_FROZEN") |
| 50 | return val == "true" |
Inseob Kim | 36d9d39 | 2023-09-04 17:40:03 +0900 | [diff] [blame] | 51 | } |
| 52 | |
| 53 | func (f *freezeTestModule) loadHook(ctx android.LoadHookContext) { |
Inseob Kim | d581661 | 2021-09-15 03:01:05 +0000 | [diff] [blame] | 54 | extraDirs := ctx.DeviceConfig().SepolicyFreezeTestExtraDirs() |
| 55 | extraPrebuiltDirs := ctx.DeviceConfig().SepolicyFreezeTestExtraPrebuiltDirs() |
Inseob Kim | d581661 | 2021-09-15 03:01:05 +0000 | [diff] [blame] | 56 | |
Inseob Kim | 3e34b72 | 2023-12-11 18:15:42 +0900 | [diff] [blame] | 57 | if !f.shouldRunTest(ctx) { |
Inseob Kim | d581661 | 2021-09-15 03:01:05 +0000 | [diff] [blame] | 58 | if len(extraDirs) > 0 || len(extraPrebuiltDirs) > 0 { |
| 59 | ctx.ModuleErrorf("SEPOLICY_FREEZE_TEST_EXTRA_DIRS or SEPOLICY_FREEZE_TEST_EXTRA_PREBUILT_DIRS cannot be set before system/sepolicy freezes.") |
| 60 | return |
| 61 | } |
| 62 | |
Inseob Kim | d581661 | 2021-09-15 03:01:05 +0000 | [diff] [blame] | 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 | } |
Inseob Kim | 36d9d39 | 2023-09-04 17:40:03 +0900 | [diff] [blame] | 70 | } |
Inseob Kim | d581661 | 2021-09-15 03:01:05 +0000 | [diff] [blame] | 71 | |
Inseob Kim | 36d9d39 | 2023-09-04 17:40:03 +0900 | [diff] [blame] | 72 | func (f *freezeTestModule) prebuiltCilModuleName(ctx android.EarlyModuleContext) string { |
| 73 | return ctx.DeviceConfig().PlatformSepolicyVersion() + "_plat_pub_policy.cil" |
| 74 | } |
Inseob Kim | d581661 | 2021-09-15 03:01:05 +0000 | [diff] [blame] | 75 | |
Inseob Kim | 36d9d39 | 2023-09-04 17:40:03 +0900 | [diff] [blame] | 76 | func (f *freezeTestModule) DepsMutator(ctx android.BottomUpMutatorContext) { |
Inseob Kim | 3e34b72 | 2023-12-11 18:15:42 +0900 | [diff] [blame] | 77 | if !f.shouldRunTest(ctx) { |
Inseob Kim | 36d9d39 | 2023-09-04 17:40:03 +0900 | [diff] [blame] | 78 | return |
| 79 | } |
| 80 | |
| 81 | ctx.AddDependency(f, currentCilTag, "base_plat_pub_policy.cil") |
| 82 | ctx.AddDependency(f, prebuiltCilTag, f.prebuiltCilModuleName(ctx)) |
| 83 | } |
| 84 | |
| 85 | func (f *freezeTestModule) GenerateSingletonBuildActions(ctx android.SingletonContext) { |
| 86 | // does nothing; se_freeze_test is a singeton because two freeze test modules don't make sense. |
| 87 | } |
| 88 | |
| 89 | func (f *freezeTestModule) outputFileOfDep(ctx android.ModuleContext, depTag dependencyTag) android.Path { |
| 90 | deps := ctx.GetDirectDepsWithTag(depTag) |
| 91 | if len(deps) != 1 { |
| 92 | ctx.ModuleErrorf("%d deps having tag %q; expected only one dep", len(deps), depTag) |
| 93 | return nil |
| 94 | } |
| 95 | |
| 96 | dep := deps[0] |
mrziwang | dc268a7 | 2024-06-06 14:42:10 -0700 | [diff] [blame^] | 97 | output := android.OutputFilesForModule(ctx, dep, "") |
Inseob Kim | 36d9d39 | 2023-09-04 17:40:03 +0900 | [diff] [blame] | 98 | if len(output) != 1 { |
| 99 | ctx.ModuleErrorf("module %q produced %d outputs; expected only one output", dep.String(), len(output)) |
| 100 | return nil |
| 101 | } |
| 102 | |
| 103 | return output[0] |
| 104 | } |
| 105 | |
| 106 | func (f *freezeTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { |
| 107 | f.freezeTestTimestamp = android.PathForModuleOut(ctx, "freeze_test") |
| 108 | |
Inseob Kim | 3e34b72 | 2023-12-11 18:15:42 +0900 | [diff] [blame] | 109 | if !f.shouldRunTest(ctx) { |
Inseob Kim | 36d9d39 | 2023-09-04 17:40:03 +0900 | [diff] [blame] | 110 | // we still build a rule to prevent possible regression |
| 111 | android.WriteFileRule(ctx, f.freezeTestTimestamp, ";; no freeze tests needed before system/sepolicy freezes") |
| 112 | return |
| 113 | } |
| 114 | |
| 115 | // Freeze test 1: compare ToT sepolicy and prebuilt sepolicy |
| 116 | currentCil := f.outputFileOfDep(ctx, currentCilTag) |
| 117 | prebuiltCil := f.outputFileOfDep(ctx, prebuiltCilTag) |
| 118 | if ctx.Failed() { |
| 119 | return |
| 120 | } |
| 121 | |
| 122 | rule := android.NewRuleBuilder(pctx, ctx) |
| 123 | rule.Command().BuiltTool("sepolicy_freeze_test"). |
| 124 | FlagWithInput("-c ", currentCil). |
| 125 | FlagWithInput("-p ", prebuiltCil) |
| 126 | |
| 127 | // Freeze test 2: compare extra directories |
| 128 | // We don't know the exact structure of extra directories, so just directly compare them |
| 129 | extraDirs := ctx.DeviceConfig().SepolicyFreezeTestExtraDirs() |
| 130 | extraPrebuiltDirs := ctx.DeviceConfig().SepolicyFreezeTestExtraPrebuiltDirs() |
Inseob Kim | d581661 | 2021-09-15 03:01:05 +0000 | [diff] [blame] | 131 | |
| 132 | var implicits []string |
Inseob Kim | 36d9d39 | 2023-09-04 17:40:03 +0900 | [diff] [blame] | 133 | for _, dir := range append(extraDirs, extraPrebuiltDirs...) { |
Inseob Kim | d581661 | 2021-09-15 03:01:05 +0000 | [diff] [blame] | 134 | glob, err := ctx.GlobWithDeps(dir+"/**/*", []string{"bug_map"} /* exclude */) |
| 135 | if err != nil { |
| 136 | ctx.ModuleErrorf("failed to glob sepolicy dir %q: %s", dir, err.Error()) |
| 137 | return |
| 138 | } |
| 139 | implicits = append(implicits, glob...) |
| 140 | } |
| 141 | sort.Strings(implicits) |
| 142 | |
Inseob Kim | 36d9d39 | 2023-09-04 17:40:03 +0900 | [diff] [blame] | 143 | for idx, _ := range extraDirs { |
Inseob Kim | d581661 | 2021-09-15 03:01:05 +0000 | [diff] [blame] | 144 | rule.Command().Text("diff"). |
| 145 | Flag("-r"). |
| 146 | Flag("-q"). |
| 147 | FlagWithArg("-x ", "bug_map"). // exclude |
Inseob Kim | 36d9d39 | 2023-09-04 17:40:03 +0900 | [diff] [blame] | 148 | Text(extraDirs[idx]). |
| 149 | Text(extraPrebuiltDirs[idx]) |
Inseob Kim | d581661 | 2021-09-15 03:01:05 +0000 | [diff] [blame] | 150 | } |
| 151 | |
| 152 | rule.Command().Text("touch"). |
| 153 | Output(f.freezeTestTimestamp). |
| 154 | Implicits(android.PathsForSource(ctx, implicits)) |
| 155 | |
| 156 | rule.Build("sepolicy_freeze_test", "sepolicy_freeze_test") |
| 157 | } |
| 158 | |
| 159 | func (f *freezeTestModule) AndroidMkEntries() []android.AndroidMkEntries { |
| 160 | return []android.AndroidMkEntries{android.AndroidMkEntries{ |
| 161 | Class: "FAKE", |
| 162 | // OutputFile is needed, even though BUILD_PHONY_PACKAGE doesn't use it. |
| 163 | // Without OutputFile this module won't be exported to Makefile. |
| 164 | OutputFile: android.OptionalPathForPath(f.freezeTestTimestamp), |
| 165 | Include: "$(BUILD_PHONY_PACKAGE)", |
| 166 | ExtraEntries: []android.AndroidMkExtraEntriesFunc{ |
| 167 | func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { |
| 168 | entries.SetString("LOCAL_ADDITIONAL_DEPENDENCIES", f.freezeTestTimestamp.String()) |
| 169 | }, |
| 170 | }, |
| 171 | }} |
| 172 | } |