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 | |
| 23 | func init() { |
| 24 | ctx := android.InitRegistrationContext |
Cole Faust | 8fe6568 | 2024-11-04 16:31:39 -0800 | [diff] [blame] | 25 | ctx.RegisterModuleType("se_freeze_test", freezeTestFactory) |
Inseob Kim | d581661 | 2021-09-15 03:01:05 +0000 | [diff] [blame] | 26 | } |
| 27 | |
| 28 | // se_freeze_test compares the plat sepolicy with the prebuilt sepolicy. Additional directories can |
| 29 | // be specified via Makefile variables: SEPOLICY_FREEZE_TEST_EXTRA_DIRS and |
| 30 | // SEPOLICY_FREEZE_TEST_EXTRA_PREBUILT_DIRS. |
Cole Faust | 8fe6568 | 2024-11-04 16:31:39 -0800 | [diff] [blame] | 31 | func freezeTestFactory() android.Module { |
Inseob Kim | d581661 | 2021-09-15 03:01:05 +0000 | [diff] [blame] | 32 | f := &freezeTestModule{} |
Inseob Kim | b19ca8d | 2024-12-27 17:00:25 +0900 | [diff] [blame] | 33 | f.AddProperties(&f.properties) |
Cole Faust | dc46228 | 2024-10-30 14:23:16 -0700 | [diff] [blame] | 34 | android.InitAndroidArchModule(f, android.DeviceSupported, android.MultilibCommon) |
Inseob Kim | d581661 | 2021-09-15 03:01:05 +0000 | [diff] [blame] | 35 | return f |
| 36 | } |
| 37 | |
Inseob Kim | b19ca8d | 2024-12-27 17:00:25 +0900 | [diff] [blame] | 38 | type freezeTestProperties struct { |
| 39 | // Frozen SEPolicy version to compare |
| 40 | Board_api_level *string |
| 41 | |
| 42 | // Path to the base platform public policy cil |
| 43 | Current_cil *string `android:"path"` |
| 44 | |
| 45 | // Path to the prebuilt cil of given board API level |
| 46 | Prebuilt_cil *string `android:"path"` |
| 47 | } |
| 48 | |
Inseob Kim | d581661 | 2021-09-15 03:01:05 +0000 | [diff] [blame] | 49 | type freezeTestModule struct { |
Cole Faust | 8fe6568 | 2024-11-04 16:31:39 -0800 | [diff] [blame] | 50 | android.ModuleBase |
Inseob Kim | b19ca8d | 2024-12-27 17:00:25 +0900 | [diff] [blame] | 51 | |
| 52 | properties freezeTestProperties |
| 53 | |
Inseob Kim | d581661 | 2021-09-15 03:01:05 +0000 | [diff] [blame] | 54 | freezeTestTimestamp android.ModuleOutPath |
| 55 | } |
| 56 | |
Inseob Kim | b19ca8d | 2024-12-27 17:00:25 +0900 | [diff] [blame] | 57 | func (f *freezeTestModule) shouldCompareExtraDirs(ctx android.EarlyModuleContext) bool { |
Inseob Kim | 3e34b72 | 2023-12-11 18:15:42 +0900 | [diff] [blame] | 58 | val, _ := ctx.Config().GetBuildFlag("RELEASE_BOARD_API_LEVEL_FROZEN") |
| 59 | return val == "true" |
Inseob Kim | 36d9d39 | 2023-09-04 17:40:03 +0900 | [diff] [blame] | 60 | } |
| 61 | |
Inseob Kim | 36d9d39 | 2023-09-04 17:40:03 +0900 | [diff] [blame] | 62 | func (f *freezeTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { |
Cole Faust | 8fe6568 | 2024-11-04 16:31:39 -0800 | [diff] [blame] | 63 | if ctx.ModuleName() != "se_freeze_test" || ctx.ModuleDir() != "system/sepolicy" { |
| 64 | // two freeze test modules don't make sense. |
| 65 | ctx.ModuleErrorf("There can only be 1 se_freeze_test module named se_freeze_test in system/sepolicy") |
| 66 | } |
| 67 | |
Inseob Kim | 36d9d39 | 2023-09-04 17:40:03 +0900 | [diff] [blame] | 68 | f.freezeTestTimestamp = android.PathForModuleOut(ctx, "freeze_test") |
| 69 | |
Inseob Kim | 36d9d39 | 2023-09-04 17:40:03 +0900 | [diff] [blame] | 70 | // Freeze test 1: compare ToT sepolicy and prebuilt sepolicy |
Inseob Kim | b19ca8d | 2024-12-27 17:00:25 +0900 | [diff] [blame] | 71 | currentCil := android.PathForModuleSrc(ctx, String(f.properties.Current_cil)) |
| 72 | prebuiltCil := android.PathForModuleSrc(ctx, String(f.properties.Prebuilt_cil)) |
Inseob Kim | 36d9d39 | 2023-09-04 17:40:03 +0900 | [diff] [blame] | 73 | if ctx.Failed() { |
| 74 | return |
| 75 | } |
| 76 | |
| 77 | rule := android.NewRuleBuilder(pctx, ctx) |
| 78 | rule.Command().BuiltTool("sepolicy_freeze_test"). |
| 79 | FlagWithInput("-c ", currentCil). |
| 80 | FlagWithInput("-p ", prebuiltCil) |
| 81 | |
| 82 | // Freeze test 2: compare extra directories |
| 83 | // We don't know the exact structure of extra directories, so just directly compare them |
| 84 | extraDirs := ctx.DeviceConfig().SepolicyFreezeTestExtraDirs() |
| 85 | extraPrebuiltDirs := ctx.DeviceConfig().SepolicyFreezeTestExtraPrebuiltDirs() |
Inseob Kim | d581661 | 2021-09-15 03:01:05 +0000 | [diff] [blame] | 86 | |
| 87 | var implicits []string |
Inseob Kim | b19ca8d | 2024-12-27 17:00:25 +0900 | [diff] [blame] | 88 | if f.shouldCompareExtraDirs(ctx) { |
| 89 | if len(extraDirs) != len(extraPrebuiltDirs) { |
| 90 | ctx.ModuleErrorf("SEPOLICY_FREEZE_TEST_EXTRA_DIRS and SEPOLICY_FREEZE_TEST_EXTRA_PREBUILT_DIRS must have the same number of directories.") |
Inseob Kim | d581661 | 2021-09-15 03:01:05 +0000 | [diff] [blame] | 91 | return |
| 92 | } |
Inseob Kim | d581661 | 2021-09-15 03:01:05 +0000 | [diff] [blame] | 93 | |
Inseob Kim | b19ca8d | 2024-12-27 17:00:25 +0900 | [diff] [blame] | 94 | for _, dir := range append(extraDirs, extraPrebuiltDirs...) { |
| 95 | glob, err := ctx.GlobWithDeps(dir+"/**/*", []string{"bug_map"} /* exclude */) |
| 96 | if err != nil { |
| 97 | ctx.ModuleErrorf("failed to glob sepolicy dir %q: %s", dir, err.Error()) |
| 98 | return |
| 99 | } |
| 100 | implicits = append(implicits, glob...) |
| 101 | } |
| 102 | sort.Strings(implicits) |
| 103 | |
| 104 | for idx, _ := range extraDirs { |
| 105 | rule.Command().Text("diff"). |
| 106 | Flag("-r"). |
| 107 | Flag("-q"). |
| 108 | FlagWithArg("-x ", "bug_map"). // exclude |
| 109 | Text(extraDirs[idx]). |
| 110 | Text(extraPrebuiltDirs[idx]) |
| 111 | } |
| 112 | } else { |
| 113 | if len(extraDirs) > 0 || len(extraPrebuiltDirs) > 0 { |
| 114 | ctx.ModuleErrorf("SEPOLICY_FREEZE_TEST_EXTRA_DIRS or SEPOLICY_FREEZE_TEST_EXTRA_PREBUILT_DIRS cannot be set before system/sepolicy freezes.") |
| 115 | return |
| 116 | } |
Inseob Kim | d581661 | 2021-09-15 03:01:05 +0000 | [diff] [blame] | 117 | } |
| 118 | |
| 119 | rule.Command().Text("touch"). |
| 120 | Output(f.freezeTestTimestamp). |
| 121 | Implicits(android.PathsForSource(ctx, implicits)) |
| 122 | |
| 123 | rule.Build("sepolicy_freeze_test", "sepolicy_freeze_test") |
| 124 | } |
| 125 | |
| 126 | func (f *freezeTestModule) AndroidMkEntries() []android.AndroidMkEntries { |
| 127 | return []android.AndroidMkEntries{android.AndroidMkEntries{ |
| 128 | Class: "FAKE", |
| 129 | // OutputFile is needed, even though BUILD_PHONY_PACKAGE doesn't use it. |
| 130 | // Without OutputFile this module won't be exported to Makefile. |
| 131 | OutputFile: android.OptionalPathForPath(f.freezeTestTimestamp), |
| 132 | Include: "$(BUILD_PHONY_PACKAGE)", |
| 133 | ExtraEntries: []android.AndroidMkExtraEntriesFunc{ |
| 134 | func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { |
| 135 | entries.SetString("LOCAL_ADDITIONAL_DEPENDENCIES", f.freezeTestTimestamp.String()) |
| 136 | }, |
| 137 | }, |
| 138 | }} |
| 139 | } |