Merge "Relax freeze_test to check only compatibility" into main
This commit is contained in:
commit
b316f8bf95
11 changed files with 334 additions and 24 deletions
|
@ -913,7 +913,7 @@ se_neverallow_test {
|
|||
// SEPOLICY_FREEZE_TEST_EXTRA_DIRS and SEPOLICY_FREEZE_TEST_EXTRA_PREBUILT_DIRS.
|
||||
//////////////////////////////////
|
||||
se_freeze_test {
|
||||
name: "sepolicy_freeze_test",
|
||||
name: "se_freeze_test",
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
|
|
|
@ -16,6 +16,7 @@ package selinux
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
|
@ -103,8 +104,15 @@ func (b *buildFiles) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||
b.srcs[".vendor"] = b.findSrcsInDirs(ctx, ctx.DeviceConfig().VendorSepolicyDirs()...)
|
||||
b.srcs[".odm"] = b.findSrcsInDirs(ctx, ctx.DeviceConfig().OdmSepolicyDirs()...)
|
||||
|
||||
prebuilt_directories, err := ctx.GlobWithDeps("system/sepolicy/prebuilts/api/*", nil)
|
||||
if err != nil {
|
||||
ctx.ModuleErrorf("error while globbing: %w", err)
|
||||
return
|
||||
}
|
||||
|
||||
// directories used for compat tests and Treble tests
|
||||
for _, ver := range ctx.DeviceConfig().PlatformSepolicyCompatVersions() {
|
||||
for _, dir := range prebuilt_directories {
|
||||
ver := path.Base(dir)
|
||||
b.srcs[".plat_public_"+ver] = b.findSrcsInDirs(ctx, filepath.Join("system", "sepolicy", "prebuilts", "api", ver, "public"))
|
||||
b.srcs[".plat_private_"+ver] = b.findSrcsInDirs(ctx, filepath.Join("system", "sepolicy", "prebuilts", "api", ver, "private"))
|
||||
b.srcs[".system_ext_public_"+ver] = b.findSrcsInDirs(ctx, filepath.Join(ctx.DeviceConfig().SystemExtSepolicyPrebuiltApiDir(), "prebuilts", "api", ver, "public"))
|
||||
|
|
|
@ -15,12 +15,14 @@
|
|||
package selinux
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"sort"
|
||||
|
||||
"android/soong/android"
|
||||
)
|
||||
|
||||
var currentCilTag = dependencyTag{name: "current_cil"}
|
||||
var prebuiltCilTag = dependencyTag{name: "prebuilt_cil"}
|
||||
|
||||
func init() {
|
||||
ctx := android.InitRegistrationContext
|
||||
ctx.RegisterParallelSingletonModuleType("se_freeze_test", freezeTestFactory)
|
||||
|
@ -32,6 +34,9 @@ func init() {
|
|||
func freezeTestFactory() android.SingletonModule {
|
||||
f := &freezeTestModule{}
|
||||
android.InitAndroidModule(f)
|
||||
android.AddLoadHook(f, func(ctx android.LoadHookContext) {
|
||||
f.loadHook(ctx)
|
||||
})
|
||||
return f
|
||||
}
|
||||
|
||||
|
@ -40,26 +45,23 @@ type freezeTestModule struct {
|
|||
freezeTestTimestamp android.ModuleOutPath
|
||||
}
|
||||
|
||||
func (f *freezeTestModule) GenerateSingletonBuildActions(ctx android.SingletonContext) {
|
||||
// does nothing; se_freeze_test is a singeton because two freeze test modules don't make sense.
|
||||
}
|
||||
|
||||
func (f *freezeTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||
func (f *freezeTestModule) shouldSkip(ctx android.EarlyModuleContext) bool {
|
||||
platformVersion := ctx.DeviceConfig().PlatformSepolicyVersion()
|
||||
totVersion := ctx.DeviceConfig().TotSepolicyVersion()
|
||||
|
||||
return platformVersion == totVersion
|
||||
}
|
||||
|
||||
func (f *freezeTestModule) loadHook(ctx android.LoadHookContext) {
|
||||
extraDirs := ctx.DeviceConfig().SepolicyFreezeTestExtraDirs()
|
||||
extraPrebuiltDirs := ctx.DeviceConfig().SepolicyFreezeTestExtraPrebuiltDirs()
|
||||
f.freezeTestTimestamp = android.PathForModuleOut(ctx, "freeze_test")
|
||||
|
||||
if platformVersion == totVersion {
|
||||
if f.shouldSkip(ctx) {
|
||||
if len(extraDirs) > 0 || len(extraPrebuiltDirs) > 0 {
|
||||
ctx.ModuleErrorf("SEPOLICY_FREEZE_TEST_EXTRA_DIRS or SEPOLICY_FREEZE_TEST_EXTRA_PREBUILT_DIRS cannot be set before system/sepolicy freezes.")
|
||||
return
|
||||
}
|
||||
|
||||
// we still build a rule to prevent possible regression
|
||||
android.WriteFileRule(ctx, f.freezeTestTimestamp, ";; no freeze tests needed before system/sepolicy freezes")
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -67,17 +69,80 @@ func (f *freezeTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext
|
|||
ctx.ModuleErrorf("SEPOLICY_FREEZE_TEST_EXTRA_DIRS and SEPOLICY_FREEZE_TEST_EXTRA_PREBUILT_DIRS must have the same number of directories.")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
platPublic := filepath.Join(ctx.ModuleDir(), "public")
|
||||
platPrivate := filepath.Join(ctx.ModuleDir(), "private")
|
||||
prebuiltPublic := filepath.Join(ctx.ModuleDir(), "prebuilts", "api", platformVersion, "public")
|
||||
prebuiltPrivate := filepath.Join(ctx.ModuleDir(), "prebuilts", "api", platformVersion, "private")
|
||||
func (f *freezeTestModule) prebuiltCilModuleName(ctx android.EarlyModuleContext) string {
|
||||
return ctx.DeviceConfig().PlatformSepolicyVersion() + "_plat_pub_policy.cil"
|
||||
}
|
||||
|
||||
sourceDirs := append(extraDirs, platPublic, platPrivate)
|
||||
prebuiltDirs := append(extraPrebuiltDirs, prebuiltPublic, prebuiltPrivate)
|
||||
func (f *freezeTestModule) DepsMutator(ctx android.BottomUpMutatorContext) {
|
||||
if f.shouldSkip(ctx) {
|
||||
return
|
||||
}
|
||||
|
||||
ctx.AddDependency(f, currentCilTag, "base_plat_pub_policy.cil")
|
||||
ctx.AddDependency(f, prebuiltCilTag, f.prebuiltCilModuleName(ctx))
|
||||
}
|
||||
|
||||
func (f *freezeTestModule) GenerateSingletonBuildActions(ctx android.SingletonContext) {
|
||||
// does nothing; se_freeze_test is a singeton because two freeze test modules don't make sense.
|
||||
}
|
||||
|
||||
func (f *freezeTestModule) outputFileOfDep(ctx android.ModuleContext, depTag dependencyTag) android.Path {
|
||||
deps := ctx.GetDirectDepsWithTag(depTag)
|
||||
if len(deps) != 1 {
|
||||
ctx.ModuleErrorf("%d deps having tag %q; expected only one dep", len(deps), depTag)
|
||||
return nil
|
||||
}
|
||||
|
||||
dep := deps[0]
|
||||
outputFileProducer, ok := dep.(android.OutputFileProducer)
|
||||
if !ok {
|
||||
ctx.ModuleErrorf("module %q is not an output file producer", dep.String())
|
||||
return nil
|
||||
}
|
||||
|
||||
output, err := outputFileProducer.OutputFiles("")
|
||||
if err != nil {
|
||||
ctx.ModuleErrorf("module %q failed to produce output: %w", dep.String(), err)
|
||||
return nil
|
||||
}
|
||||
if len(output) != 1 {
|
||||
ctx.ModuleErrorf("module %q produced %d outputs; expected only one output", dep.String(), len(output))
|
||||
return nil
|
||||
}
|
||||
|
||||
return output[0]
|
||||
}
|
||||
|
||||
func (f *freezeTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||
f.freezeTestTimestamp = android.PathForModuleOut(ctx, "freeze_test")
|
||||
|
||||
if f.shouldSkip(ctx) {
|
||||
// we still build a rule to prevent possible regression
|
||||
android.WriteFileRule(ctx, f.freezeTestTimestamp, ";; no freeze tests needed before system/sepolicy freezes")
|
||||
return
|
||||
}
|
||||
|
||||
// Freeze test 1: compare ToT sepolicy and prebuilt sepolicy
|
||||
currentCil := f.outputFileOfDep(ctx, currentCilTag)
|
||||
prebuiltCil := f.outputFileOfDep(ctx, prebuiltCilTag)
|
||||
if ctx.Failed() {
|
||||
return
|
||||
}
|
||||
|
||||
rule := android.NewRuleBuilder(pctx, ctx)
|
||||
rule.Command().BuiltTool("sepolicy_freeze_test").
|
||||
FlagWithInput("-c ", currentCil).
|
||||
FlagWithInput("-p ", prebuiltCil)
|
||||
|
||||
// Freeze test 2: compare extra directories
|
||||
// We don't know the exact structure of extra directories, so just directly compare them
|
||||
extraDirs := ctx.DeviceConfig().SepolicyFreezeTestExtraDirs()
|
||||
extraPrebuiltDirs := ctx.DeviceConfig().SepolicyFreezeTestExtraPrebuiltDirs()
|
||||
|
||||
var implicits []string
|
||||
for _, dir := range append(sourceDirs, prebuiltDirs...) {
|
||||
for _, dir := range append(extraDirs, extraPrebuiltDirs...) {
|
||||
glob, err := ctx.GlobWithDeps(dir+"/**/*", []string{"bug_map"} /* exclude */)
|
||||
if err != nil {
|
||||
ctx.ModuleErrorf("failed to glob sepolicy dir %q: %s", dir, err.Error())
|
||||
|
@ -87,15 +152,13 @@ func (f *freezeTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext
|
|||
}
|
||||
sort.Strings(implicits)
|
||||
|
||||
rule := android.NewRuleBuilder(pctx, ctx)
|
||||
|
||||
for idx, _ := range sourceDirs {
|
||||
for idx, _ := range extraDirs {
|
||||
rule.Command().Text("diff").
|
||||
Flag("-r").
|
||||
Flag("-q").
|
||||
FlagWithArg("-x ", "bug_map"). // exclude
|
||||
Text(sourceDirs[idx]).
|
||||
Text(prebuiltDirs[idx])
|
||||
Text(extraDirs[idx]).
|
||||
Text(extraPrebuiltDirs[idx])
|
||||
}
|
||||
|
||||
rule.Command().Text("touch").
|
||||
|
|
28
prebuilts/api/29.0/Android.bp
Normal file
28
prebuilts/api/29.0/Android.bp
Normal file
|
@ -0,0 +1,28 @@
|
|||
// Copyright (C) 2023 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
se_policy_conf {
|
||||
name: "29.0_plat_pub_policy.conf",
|
||||
srcs: [":se_build_files{.plat_public_29.0}", ":se_build_files{.reqd_mask}"],
|
||||
installable: false,
|
||||
build_variant: "user",
|
||||
}
|
||||
|
||||
se_policy_cil {
|
||||
name: "29.0_plat_pub_policy.cil",
|
||||
src: ":29.0_plat_pub_policy.conf",
|
||||
filter_out: [":reqd_policy_mask.cil"],
|
||||
secilc_check: false,
|
||||
installable: false,
|
||||
}
|
28
prebuilts/api/30.0/Android.bp
Normal file
28
prebuilts/api/30.0/Android.bp
Normal file
|
@ -0,0 +1,28 @@
|
|||
// Copyright (C) 2023 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
se_policy_conf {
|
||||
name: "30.0_plat_pub_policy.conf",
|
||||
srcs: [":se_build_files{.plat_public_30.0}", ":se_build_files{.reqd_mask}"],
|
||||
installable: false,
|
||||
build_variant: "user",
|
||||
}
|
||||
|
||||
se_policy_cil {
|
||||
name: "30.0_plat_pub_policy.cil",
|
||||
src: ":30.0_plat_pub_policy.conf",
|
||||
filter_out: [":reqd_policy_mask.cil"],
|
||||
secilc_check: false,
|
||||
installable: false,
|
||||
}
|
28
prebuilts/api/31.0/Android.bp
Normal file
28
prebuilts/api/31.0/Android.bp
Normal file
|
@ -0,0 +1,28 @@
|
|||
// Copyright (C) 2023 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
se_policy_conf {
|
||||
name: "31.0_plat_pub_policy.conf",
|
||||
srcs: [":se_build_files{.plat_public_31.0}", ":se_build_files{.reqd_mask}"],
|
||||
installable: false,
|
||||
build_variant: "user",
|
||||
}
|
||||
|
||||
se_policy_cil {
|
||||
name: "31.0_plat_pub_policy.cil",
|
||||
src: ":31.0_plat_pub_policy.conf",
|
||||
filter_out: [":reqd_policy_mask.cil"],
|
||||
secilc_check: false,
|
||||
installable: false,
|
||||
}
|
28
prebuilts/api/32.0/Android.bp
Normal file
28
prebuilts/api/32.0/Android.bp
Normal file
|
@ -0,0 +1,28 @@
|
|||
// Copyright (C) 2023 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
se_policy_conf {
|
||||
name: "32.0_plat_pub_policy.conf",
|
||||
srcs: [":se_build_files{.plat_public_32.0}", ":se_build_files{.reqd_mask}"],
|
||||
installable: false,
|
||||
build_variant: "user",
|
||||
}
|
||||
|
||||
se_policy_cil {
|
||||
name: "32.0_plat_pub_policy.cil",
|
||||
src: ":32.0_plat_pub_policy.conf",
|
||||
filter_out: [":reqd_policy_mask.cil"],
|
||||
secilc_check: false,
|
||||
installable: false,
|
||||
}
|
28
prebuilts/api/33.0/Android.bp
Normal file
28
prebuilts/api/33.0/Android.bp
Normal file
|
@ -0,0 +1,28 @@
|
|||
// Copyright (C) 2023 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
se_policy_conf {
|
||||
name: "33.0_plat_pub_policy.conf",
|
||||
srcs: [":se_build_files{.plat_public_33.0}", ":se_build_files{.reqd_mask}"],
|
||||
installable: false,
|
||||
build_variant: "user",
|
||||
}
|
||||
|
||||
se_policy_cil {
|
||||
name: "33.0_plat_pub_policy.cil",
|
||||
src: ":33.0_plat_pub_policy.conf",
|
||||
filter_out: [":reqd_policy_mask.cil"],
|
||||
secilc_check: false,
|
||||
installable: false,
|
||||
}
|
28
prebuilts/api/34.0/Android.bp
Normal file
28
prebuilts/api/34.0/Android.bp
Normal file
|
@ -0,0 +1,28 @@
|
|||
// Copyright (C) 2023 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
se_policy_conf {
|
||||
name: "34.0_plat_pub_policy.conf",
|
||||
srcs: [":se_build_files{.plat_public_34.0}", ":se_build_files{.reqd_mask}"],
|
||||
installable: false,
|
||||
build_variant: "user",
|
||||
}
|
||||
|
||||
se_policy_cil {
|
||||
name: "34.0_plat_pub_policy.cil",
|
||||
src: ":34.0_plat_pub_policy.conf",
|
||||
filter_out: [":reqd_policy_mask.cil"],
|
||||
secilc_check: false,
|
||||
installable: false,
|
||||
}
|
|
@ -146,3 +146,18 @@ python_binary_host {
|
|||
name: "check_prop_prefix",
|
||||
srcs: ["check_prop_prefix.py"],
|
||||
}
|
||||
|
||||
python_binary_host {
|
||||
name: "sepolicy_freeze_test",
|
||||
srcs: [
|
||||
"sepolicy_freeze_test.py",
|
||||
],
|
||||
version: {
|
||||
py3: {
|
||||
embedded_launcher: true,
|
||||
},
|
||||
},
|
||||
libs: [
|
||||
"mini_cil_parser",
|
||||
],
|
||||
}
|
||||
|
|
56
tests/sepolicy_freeze_test.py
Normal file
56
tests/sepolicy_freeze_test.py
Normal file
|
@ -0,0 +1,56 @@
|
|||
# Copyright 2023 The Android Open Source Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from optparse import OptionParser
|
||||
import mini_parser
|
||||
import os
|
||||
import sys
|
||||
|
||||
def do_main():
|
||||
usage = "sepolicy_freeze_test "
|
||||
usage += "-c current_cil -p prebuilt_cil [--help]"
|
||||
parser = OptionParser(usage=usage)
|
||||
parser.add_option("-c", "--current", dest="current", metavar="FILE")
|
||||
parser.add_option("-p", "--prebuilt", dest="prebuilt", metavar="FILE")
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
if not options.current or not options.prebuilt:
|
||||
sys.exit("Must specify both current and prebuilt\n" + parser.usage)
|
||||
if not os.path.exists(options.current):
|
||||
sys.exit("Current policy " + options.current + " does not exist\n"
|
||||
+ parser.usage)
|
||||
if not os.path.exists(options.prebuilt):
|
||||
sys.exit("Prebuilt policy " + options.prebuilt + " does not exist\n"
|
||||
+ parser.usage)
|
||||
|
||||
current_policy = mini_parser.MiniCilParser(options.current)
|
||||
prebuilt_policy = mini_parser.MiniCilParser(options.prebuilt)
|
||||
|
||||
results = ""
|
||||
removed_types = prebuilt_policy.types - current_policy.types
|
||||
removed_attributes = prebuilt_policy.typeattributes - current_policy.typeattributes
|
||||
removed_attributes = set(filter(lambda x: "base_typeattr_" not in x, removed_attributes))
|
||||
|
||||
if removed_types:
|
||||
results += "The following public types were removed:\n" + ", ".join(removed_types) + "\n"
|
||||
|
||||
if removed_attributes:
|
||||
results += "The following public attributes were removed:\n" + ", ".join(removed_attributes) + "\n"
|
||||
|
||||
if len(results) > 0:
|
||||
sys.exit(results)
|
||||
|
||||
if __name__ == '__main__':
|
||||
do_main()
|
Loading…
Reference in a new issue