xref: /aosp_15_r20/system/sepolicy/tests/treble_sepolicy_tests.py (revision e4a36f4174b17bbab9dc043f4a65dc8d87377290)
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