0d49b9bc28
Rationale for this change: 1) Vendors use only public files, so we should be able to use only public cil files for compatibility test. 2) treble_sepolicy_tests_for_release.mk is too complex, because it requires compiled sepolicy. Reducing the complexity will help migrate into REL build. 3) This fixes a tiny bug of treble_sepolicy_tests that it can't catch public types being moved to private types, and then removed. 29.0.cil and 30.0.cil change contains such missing public types. Bug: 296875906 Test: m selinux_policy (with/without intentional breakage) Change-Id: Ia2c0733176df898f268b5680195da25b588b09c7
134 lines
5.2 KiB
Python
134 lines
5.2 KiB
Python
# Copyright 2021 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
|
|
from optparse import Option, OptionValueError
|
|
import os
|
|
import mini_parser
|
|
import re
|
|
import shutil
|
|
import sys
|
|
import tempfile
|
|
|
|
'''
|
|
Verify that Treble compatibility are not broken.
|
|
'''
|
|
|
|
|
|
#############################################################
|
|
# Tests
|
|
#############################################################
|
|
|
|
###
|
|
# Make sure that any new public type introduced in the new policy that was not
|
|
# present in the old policy has been recorded in the mapping file.
|
|
def TestNoUnmappedNewTypes(base_pub_policy, old_pub_policy, mapping):
|
|
newt = base_pub_policy.types - old_pub_policy.types
|
|
ret = ""
|
|
violators = []
|
|
|
|
for n in newt:
|
|
if mapping.rTypeattributesets.get(n) is None:
|
|
violators.append(n)
|
|
|
|
if len(violators) > 0:
|
|
ret += "SELinux: The following public types were found added to the "
|
|
ret += "policy without an entry into the compatibility mapping file(s) "
|
|
ret += "found in private/compat/V.v/V.v[.ignore].cil, where V.v is the "
|
|
ret += "latest API level.\n"
|
|
ret += " ".join(str(x) for x in sorted(violators)) + "\n\n"
|
|
ret += "See examples of how to fix this:\n"
|
|
ret += "https://android-review.googlesource.com/c/platform/system/sepolicy/+/781036\n"
|
|
ret += "https://android-review.googlesource.com/c/platform/system/sepolicy/+/852612\n"
|
|
return ret
|
|
|
|
###
|
|
# Make sure that any public type removed in the current policy has its
|
|
# declaration added to the mapping file for use in non-platform policy
|
|
def TestNoUnmappedRmTypes(base_pub_policy, old_pub_policy, mapping):
|
|
rmt = old_pub_policy.types - base_pub_policy.types
|
|
ret = ""
|
|
violators = []
|
|
|
|
for o in rmt:
|
|
if o in mapping.pubtypes and not o in mapping.types:
|
|
violators.append(o)
|
|
|
|
if len(violators) > 0:
|
|
ret += "SELinux: The following formerly public types were removed from "
|
|
ret += "policy without a declaration in the compatibility mapping "
|
|
ret += "found in private/compat/V.v/V.v[.ignore].cil, where V.v is the "
|
|
ret += "latest API level.\n"
|
|
ret += " ".join(str(x) for x in sorted(violators)) + "\n\n"
|
|
ret += "See examples of how to fix this:\n"
|
|
ret += "https://android-review.googlesource.com/c/platform/system/sepolicy/+/822743\n"
|
|
return ret
|
|
|
|
def TestTrebleCompatMapping(base_pub_policy, old_pub_policy, mapping):
|
|
ret = TestNoUnmappedNewTypes(base_pub_policy, old_pub_policy, mapping)
|
|
ret += TestNoUnmappedRmTypes(base_pub_policy, old_pub_policy, mapping)
|
|
return ret
|
|
|
|
###
|
|
# extend OptionParser to allow the same option flag to be used multiple times.
|
|
# This is used to allow multiple file_contexts files and tests to be
|
|
# specified.
|
|
#
|
|
class MultipleOption(Option):
|
|
ACTIONS = Option.ACTIONS + ("extend",)
|
|
STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",)
|
|
TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",)
|
|
ALWAYS_TYPED_ACTIONS = Option.ALWAYS_TYPED_ACTIONS + ("extend",)
|
|
|
|
def take_action(self, action, dest, opt, value, values, parser):
|
|
if action == "extend":
|
|
values.ensure_value(dest, []).append(value)
|
|
else:
|
|
Option.take_action(self, action, dest, opt, value, values, parser)
|
|
|
|
def do_main():
|
|
usage = "treble_sepolicy_tests "
|
|
usage += "-b base_pub_policy -o old_pub_policy "
|
|
usage += "-m mapping file [--test test] [--help]"
|
|
parser = OptionParser(option_class=MultipleOption, usage=usage)
|
|
parser.add_option("-b", "--base-pub-policy", dest="base_pub_policy",
|
|
metavar="FILE")
|
|
parser.add_option("-m", "--mapping", dest="mapping", metavar="FILE")
|
|
parser.add_option("-o", "--old-pub-policy", dest="old_pub_policy",
|
|
metavar="FILE")
|
|
|
|
(options, args) = parser.parse_args()
|
|
|
|
# Mapping files and public platform policy are only necessary for the
|
|
# TrebleCompatMapping test.
|
|
if not options.mapping:
|
|
sys.exit("Must specify a compatibility mapping file\n"
|
|
+ parser.usage)
|
|
if not options.old_pub_policy:
|
|
sys.exit("Must specify the previous public policy .cil file\n"
|
|
+ parser.usage)
|
|
if not options.base_pub_policy:
|
|
sys.exit("Must specify the current platform-only public policy "
|
|
+ ".cil file\n" + parser.usage)
|
|
mapping = mini_parser.MiniCilParser(options.mapping)
|
|
base_pub_policy = mini_parser.MiniCilParser(options.base_pub_policy)
|
|
old_pub_policy = mini_parser.MiniCilParser(options.old_pub_policy)
|
|
|
|
results = TestTrebleCompatMapping(base_pub_policy, old_pub_policy, mapping)
|
|
|
|
if len(results) > 0:
|
|
sys.exit(results)
|
|
|
|
if __name__ == '__main__':
|
|
do_main()
|