1*e4a36f41SAndroid Build Coastguard Worker# Copyright 2021 The Android Open Source Project 2*e4a36f41SAndroid Build Coastguard Worker# 3*e4a36f41SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 4*e4a36f41SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 5*e4a36f41SAndroid Build Coastguard Worker# You may obtain a copy of the License at 6*e4a36f41SAndroid Build Coastguard Worker# 7*e4a36f41SAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 8*e4a36f41SAndroid Build Coastguard Worker# 9*e4a36f41SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*e4a36f41SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 11*e4a36f41SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*e4a36f41SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 13*e4a36f41SAndroid Build Coastguard Worker# limitations under the License. 14*e4a36f41SAndroid Build Coastguard Worker 15*e4a36f41SAndroid Build Coastguard Workerfrom optparse import OptionParser 16*e4a36f41SAndroid Build Coastguard Workerfrom optparse import Option, OptionValueError 17*e4a36f41SAndroid Build Coastguard Workerimport os 18*e4a36f41SAndroid Build Coastguard Workerimport mini_parser 19*e4a36f41SAndroid Build Coastguard Workerimport re 20*e4a36f41SAndroid Build Coastguard Workerimport shutil 21*e4a36f41SAndroid Build Coastguard Workerimport sys 22*e4a36f41SAndroid Build Coastguard Workerimport tempfile 23*e4a36f41SAndroid Build Coastguard Worker 24*e4a36f41SAndroid Build Coastguard Worker''' 25*e4a36f41SAndroid Build Coastguard WorkerVerify that Treble compatibility are not broken. 26*e4a36f41SAndroid Build Coastguard Worker''' 27*e4a36f41SAndroid Build Coastguard Worker 28*e4a36f41SAndroid Build Coastguard Worker 29*e4a36f41SAndroid Build Coastguard Worker############################################################# 30*e4a36f41SAndroid Build Coastguard Worker# Tests 31*e4a36f41SAndroid Build Coastguard Worker############################################################# 32*e4a36f41SAndroid Build Coastguard Worker 33*e4a36f41SAndroid Build Coastguard Worker### 34*e4a36f41SAndroid Build Coastguard Worker# Make sure that any new public type introduced in the new policy that was not 35*e4a36f41SAndroid Build Coastguard Worker# present in the old policy has been recorded in the mapping file. 36*e4a36f41SAndroid Build Coastguard Workerdef TestNoUnmappedNewTypes(base_pub_policy, old_pub_policy, mapping): 37*e4a36f41SAndroid Build Coastguard Worker newt = base_pub_policy.types - old_pub_policy.types 38*e4a36f41SAndroid Build Coastguard Worker ret = "" 39*e4a36f41SAndroid Build Coastguard Worker violators = [] 40*e4a36f41SAndroid Build Coastguard Worker 41*e4a36f41SAndroid Build Coastguard Worker for n in newt: 42*e4a36f41SAndroid Build Coastguard Worker if mapping.rTypeattributesets.get(n) is None: 43*e4a36f41SAndroid Build Coastguard Worker violators.append(n) 44*e4a36f41SAndroid Build Coastguard Worker 45*e4a36f41SAndroid Build Coastguard Worker if len(violators) > 0: 46*e4a36f41SAndroid Build Coastguard Worker ret += "SELinux: The following public types were found added to the " 47*e4a36f41SAndroid Build Coastguard Worker ret += "policy without an entry into the compatibility mapping file(s) " 48*e4a36f41SAndroid Build Coastguard Worker ret += "found in private/compat/V.v/V.v[.ignore].cil, where V.v is the " 49*e4a36f41SAndroid Build Coastguard Worker ret += "latest API level.\n" 50*e4a36f41SAndroid Build Coastguard Worker ret += " ".join(str(x) for x in sorted(violators)) + "\n\n" 51*e4a36f41SAndroid Build Coastguard Worker ret += "See examples of how to fix this:\n" 52*e4a36f41SAndroid Build Coastguard Worker ret += "https://android-review.googlesource.com/c/platform/system/sepolicy/+/781036\n" 53*e4a36f41SAndroid Build Coastguard Worker ret += "https://android-review.googlesource.com/c/platform/system/sepolicy/+/852612\n" 54*e4a36f41SAndroid Build Coastguard Worker return ret 55*e4a36f41SAndroid Build Coastguard Worker 56*e4a36f41SAndroid Build Coastguard Worker### 57*e4a36f41SAndroid Build Coastguard Worker# Make sure that any public type removed in the current policy has its 58*e4a36f41SAndroid Build Coastguard Worker# declaration added to the mapping file for use in non-platform policy 59*e4a36f41SAndroid Build Coastguard Workerdef TestNoUnmappedRmTypes(base_pub_policy, old_pub_policy, mapping): 60*e4a36f41SAndroid Build Coastguard Worker rmt = old_pub_policy.types - base_pub_policy.types 61*e4a36f41SAndroid Build Coastguard Worker ret = "" 62*e4a36f41SAndroid Build Coastguard Worker violators = [] 63*e4a36f41SAndroid Build Coastguard Worker 64*e4a36f41SAndroid Build Coastguard Worker for o in rmt: 65*e4a36f41SAndroid Build Coastguard Worker if o in mapping.pubtypes and not o in mapping.types: 66*e4a36f41SAndroid Build Coastguard Worker violators.append(o) 67*e4a36f41SAndroid Build Coastguard Worker 68*e4a36f41SAndroid Build Coastguard Worker if len(violators) > 0: 69*e4a36f41SAndroid Build Coastguard Worker ret += "SELinux: The following formerly public types were removed from " 70*e4a36f41SAndroid Build Coastguard Worker ret += "policy without a declaration in the compatibility mapping " 71*e4a36f41SAndroid Build Coastguard Worker ret += "found in private/compat/V.v/V.v[.ignore].cil, where V.v is the " 72*e4a36f41SAndroid Build Coastguard Worker ret += "latest API level.\n" 73*e4a36f41SAndroid Build Coastguard Worker ret += " ".join(str(x) for x in sorted(violators)) + "\n\n" 74*e4a36f41SAndroid Build Coastguard Worker ret += "See examples of how to fix this:\n" 75*e4a36f41SAndroid Build Coastguard Worker ret += "https://android-review.googlesource.com/c/platform/system/sepolicy/+/822743\n" 76*e4a36f41SAndroid Build Coastguard Worker return ret 77*e4a36f41SAndroid Build Coastguard Worker 78*e4a36f41SAndroid Build Coastguard Workerdef TestTrebleCompatMapping(base_pub_policy, old_pub_policy, mapping): 79*e4a36f41SAndroid Build Coastguard Worker ret = TestNoUnmappedNewTypes(base_pub_policy, old_pub_policy, mapping) 80*e4a36f41SAndroid Build Coastguard Worker ret += TestNoUnmappedRmTypes(base_pub_policy, old_pub_policy, mapping) 81*e4a36f41SAndroid Build Coastguard Worker return ret 82*e4a36f41SAndroid Build Coastguard Worker 83*e4a36f41SAndroid Build Coastguard Worker### 84*e4a36f41SAndroid Build Coastguard Worker# extend OptionParser to allow the same option flag to be used multiple times. 85*e4a36f41SAndroid Build Coastguard Worker# This is used to allow multiple file_contexts files and tests to be 86*e4a36f41SAndroid Build Coastguard Worker# specified. 87*e4a36f41SAndroid Build Coastguard Worker# 88*e4a36f41SAndroid Build Coastguard Workerclass MultipleOption(Option): 89*e4a36f41SAndroid Build Coastguard Worker ACTIONS = Option.ACTIONS + ("extend",) 90*e4a36f41SAndroid Build Coastguard Worker STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",) 91*e4a36f41SAndroid Build Coastguard Worker TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",) 92*e4a36f41SAndroid Build Coastguard Worker ALWAYS_TYPED_ACTIONS = Option.ALWAYS_TYPED_ACTIONS + ("extend",) 93*e4a36f41SAndroid Build Coastguard Worker 94*e4a36f41SAndroid Build Coastguard Worker def take_action(self, action, dest, opt, value, values, parser): 95*e4a36f41SAndroid Build Coastguard Worker if action == "extend": 96*e4a36f41SAndroid Build Coastguard Worker values.ensure_value(dest, []).append(value) 97*e4a36f41SAndroid Build Coastguard Worker else: 98*e4a36f41SAndroid Build Coastguard Worker Option.take_action(self, action, dest, opt, value, values, parser) 99*e4a36f41SAndroid Build Coastguard Worker 100*e4a36f41SAndroid Build Coastguard Workerdef do_main(): 101*e4a36f41SAndroid Build Coastguard Worker usage = "treble_sepolicy_tests " 102*e4a36f41SAndroid Build Coastguard Worker usage += "-b base_pub_policy -o old_pub_policy " 103*e4a36f41SAndroid Build Coastguard Worker usage += "-m mapping file [--test test] [--help]" 104*e4a36f41SAndroid Build Coastguard Worker parser = OptionParser(option_class=MultipleOption, usage=usage) 105*e4a36f41SAndroid Build Coastguard Worker parser.add_option("-b", "--base-pub-policy", dest="base_pub_policy", 106*e4a36f41SAndroid Build Coastguard Worker metavar="FILE") 107*e4a36f41SAndroid Build Coastguard Worker parser.add_option("-m", "--mapping", dest="mapping", metavar="FILE") 108*e4a36f41SAndroid Build Coastguard Worker parser.add_option("-o", "--old-pub-policy", dest="old_pub_policy", 109*e4a36f41SAndroid Build Coastguard Worker metavar="FILE") 110*e4a36f41SAndroid Build Coastguard Worker 111*e4a36f41SAndroid Build Coastguard Worker (options, args) = parser.parse_args() 112*e4a36f41SAndroid Build Coastguard Worker 113*e4a36f41SAndroid Build Coastguard Worker # Mapping files and public platform policy are only necessary for the 114*e4a36f41SAndroid Build Coastguard Worker # TrebleCompatMapping test. 115*e4a36f41SAndroid Build Coastguard Worker if not options.mapping: 116*e4a36f41SAndroid Build Coastguard Worker sys.exit("Must specify a compatibility mapping file\n" 117*e4a36f41SAndroid Build Coastguard Worker + parser.usage) 118*e4a36f41SAndroid Build Coastguard Worker if not options.old_pub_policy: 119*e4a36f41SAndroid Build Coastguard Worker sys.exit("Must specify the previous public policy .cil file\n" 120*e4a36f41SAndroid Build Coastguard Worker + parser.usage) 121*e4a36f41SAndroid Build Coastguard Worker if not options.base_pub_policy: 122*e4a36f41SAndroid Build Coastguard Worker sys.exit("Must specify the current platform-only public policy " 123*e4a36f41SAndroid Build Coastguard Worker + ".cil file\n" + parser.usage) 124*e4a36f41SAndroid Build Coastguard Worker mapping = mini_parser.MiniCilParser(options.mapping) 125*e4a36f41SAndroid Build Coastguard Worker base_pub_policy = mini_parser.MiniCilParser(options.base_pub_policy) 126*e4a36f41SAndroid Build Coastguard Worker old_pub_policy = mini_parser.MiniCilParser(options.old_pub_policy) 127*e4a36f41SAndroid Build Coastguard Worker 128*e4a36f41SAndroid Build Coastguard Worker results = TestTrebleCompatMapping(base_pub_policy, old_pub_policy, mapping) 129*e4a36f41SAndroid Build Coastguard Worker 130*e4a36f41SAndroid Build Coastguard Worker if len(results) > 0: 131*e4a36f41SAndroid Build Coastguard Worker sys.exit(results) 132*e4a36f41SAndroid Build Coastguard Worker 133*e4a36f41SAndroid Build Coastguard Workerif __name__ == '__main__': 134*e4a36f41SAndroid Build Coastguard Worker do_main() 135