blob: b2792a08e6ccf94f5ea1b8511862907595a7d464 [file] [log] [blame]
Thiébaud Weksteenf24b4572021-11-26 09:12:41 +11001# 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
Jeff Vander Stoepbdfc0302017-05-25 09:53:47 -070015from optparse import OptionParser
16from optparse import Option, OptionValueError
17import os
Dan Cashman91d398d2017-09-26 12:58:29 -070018import mini_parser
Inseob Kim4912a242022-07-25 11:30:02 +090019import pkgutil
Jeff Vander Stoepbdfc0302017-05-25 09:53:47 -070020import policy
Dan Cashman91d398d2017-09-26 12:58:29 -070021from policy import MatchPathPrefix
Jeff Vander Stoepbdfc0302017-05-25 09:53:47 -070022import re
Inseob Kim4912a242022-07-25 11:30:02 +090023import shutil
Jeff Vander Stoepbdfc0302017-05-25 09:53:47 -070024import sys
Inseob Kim4912a242022-07-25 11:30:02 +090025import tempfile
Jeff Vander Stoepbdfc0302017-05-25 09:53:47 -070026
Jeff Vander Stoep1fc06822017-05-31 15:36:07 -070027DEBUG=False
Inseob Kim3a9ac6f2022-07-19 14:27:36 +090028SHARED_LIB_EXTENSION = '.dylib' if sys.platform == 'darwin' else '.so'
Jeff Vander Stoep1fc06822017-05-31 15:36:07 -070029
Jeff Vander Stoepbdfc0302017-05-25 09:53:47 -070030'''
Inseob Kimeb0d40a2023-09-04 19:02:53 +090031Verify that Treble compatibility are not broken.
Jeff Vander Stoepbdfc0302017-05-25 09:53:47 -070032'''
Thiébaud Weksteendab3b1a2023-03-06 13:54:07 +110033
Dan Cashman91d398d2017-09-26 12:58:29 -070034
Jeff Vander Stoepbdfc0302017-05-25 09:53:47 -070035#############################################################
36# Tests
37#############################################################
Jeff Vander Stoepbdfc0302017-05-25 09:53:47 -070038
39###
Tri Voe3f4f772018-09-28 17:21:08 -070040# Make sure that any new public type introduced in the new policy that was not
41# present in the old policy has been recorded in the mapping file.
Thiébaud Weksteendab3b1a2023-03-06 13:54:07 +110042def TestNoUnmappedNewTypes(test_policy):
43 newt = test_policy.alltypes - test_policy.oldalltypes
Dan Cashman91d398d2017-09-26 12:58:29 -070044 ret = ""
45 violators = []
46
47 for n in newt:
Thiébaud Weksteendab3b1a2023-03-06 13:54:07 +110048 if n in test_policy.pubtypes and test_policy.compatMapping.rTypeattributesets.get(n) is None:
Dan Cashman91d398d2017-09-26 12:58:29 -070049 violators.append(n)
50
51 if len(violators) > 0:
Tri Voe3f4f772018-09-28 17:21:08 -070052 ret += "SELinux: The following public types were found added to the "
53 ret += "policy without an entry into the compatibility mapping file(s) "
Tri Vo438684b2018-09-29 17:47:10 -070054 ret += "found in private/compat/V.v/V.v[.ignore].cil, where V.v is the "
55 ret += "latest API level.\n"
Tri Vo14519382019-01-06 18:17:32 -080056 ret += " ".join(str(x) for x in sorted(violators)) + "\n\n"
57 ret += "See examples of how to fix this:\n"
Tri Vo462c9c42019-08-09 10:27:46 -070058 ret += "https://android-review.googlesource.com/c/platform/system/sepolicy/+/781036\n"
59 ret += "https://android-review.googlesource.com/c/platform/system/sepolicy/+/852612\n"
Dan Cashman91d398d2017-09-26 12:58:29 -070060 return ret
61
62###
63# Make sure that any public type removed in the current policy has its
64# declaration added to the mapping file for use in non-platform policy
Thiébaud Weksteendab3b1a2023-03-06 13:54:07 +110065def TestNoUnmappedRmTypes(test_policy):
66 rmt = test_policy.oldalltypes - test_policy.alltypes
Dan Cashman91d398d2017-09-26 12:58:29 -070067 ret = ""
68 violators = []
69
70 for o in rmt:
Thiébaud Weksteendab3b1a2023-03-06 13:54:07 +110071 if o in test_policy.compatMapping.pubtypes and not o in test_policy.compatMapping.types:
Dan Cashman91d398d2017-09-26 12:58:29 -070072 violators.append(o)
73
74 if len(violators) > 0:
75 ret += "SELinux: The following formerly public types were removed from "
76 ret += "policy without a declaration in the compatibility mapping "
Tri Vo438684b2018-09-29 17:47:10 -070077 ret += "found in private/compat/V.v/V.v[.ignore].cil, where V.v is the "
78 ret += "latest API level.\n"
Tri Vo14519382019-01-06 18:17:32 -080079 ret += " ".join(str(x) for x in sorted(violators)) + "\n\n"
80 ret += "See examples of how to fix this:\n"
Tri Vo462c9c42019-08-09 10:27:46 -070081 ret += "https://android-review.googlesource.com/c/platform/system/sepolicy/+/822743\n"
Dan Cashman91d398d2017-09-26 12:58:29 -070082 return ret
83
Thiébaud Weksteendab3b1a2023-03-06 13:54:07 +110084def TestTrebleCompatMapping(test_policy):
85 ret = TestNoUnmappedNewTypes(test_policy)
86 ret += TestNoUnmappedRmTypes(test_policy)
Dan Cashman91d398d2017-09-26 12:58:29 -070087 return ret
88
Dan Cashman91d398d2017-09-26 12:58:29 -070089###
Jeff Vander Stoepbdfc0302017-05-25 09:53:47 -070090# extend OptionParser to allow the same option flag to be used multiple times.
91# This is used to allow multiple file_contexts files and tests to be
92# specified.
93#
94class MultipleOption(Option):
95 ACTIONS = Option.ACTIONS + ("extend",)
96 STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",)
97 TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",)
98 ALWAYS_TYPED_ACTIONS = Option.ALWAYS_TYPED_ACTIONS + ("extend",)
99
100 def take_action(self, action, dest, opt, value, values, parser):
101 if action == "extend":
102 values.ensure_value(dest, []).append(value)
103 else:
104 Option.take_action(self, action, dest, opt, value, values, parser)
105
Inseob Kim4912a242022-07-25 11:30:02 +0900106def do_main(libpath):
107 """
108 Args:
109 libpath: string, path to libsepolwrap.so
110 """
Inseob Kimeb0d40a2023-09-04 19:02:53 +0900111 test_policy = policy.TestPolicy()
Inseob Kim4912a242022-07-25 11:30:02 +0900112
Inseob Kim6fa8efd2021-12-29 13:56:14 +0900113 usage = "treble_sepolicy_tests "
Dan Cashman91d398d2017-09-26 12:58:29 -0700114 usage += "-p curr_policy -b base_policy -o old_policy "
Inseob Kimeb0d40a2023-09-04 19:02:53 +0900115 usage += "-m mapping file [--test test] [--help]"
Jeff Vander Stoepbdfc0302017-05-25 09:53:47 -0700116 parser = OptionParser(option_class=MultipleOption, usage=usage)
Dan Cashman91d398d2017-09-26 12:58:29 -0700117 parser.add_option("-b", "--basepolicy", dest="basepolicy", metavar="FILE")
Tri Voe3f4f772018-09-28 17:21:08 -0700118 parser.add_option("-u", "--base-pub-policy", dest="base_pub_policy",
119 metavar="FILE")
Dan Cashman91d398d2017-09-26 12:58:29 -0700120 parser.add_option("-m", "--mapping", dest="mapping", metavar="FILE")
121 parser.add_option("-o", "--oldpolicy", dest="oldpolicy", metavar="FILE")
122 parser.add_option("-p", "--policy", dest="policy", metavar="FILE")
Jeff Vander Stoepbdfc0302017-05-25 09:53:47 -0700123
124 (options, args) = parser.parse_args()
125
126 if not options.policy:
Dan Cashman91d398d2017-09-26 12:58:29 -0700127 sys.exit("Must specify current monolithic policy file\n" + parser.usage)
Jeff Vander Stoepbdfc0302017-05-25 09:53:47 -0700128 if not os.path.exists(options.policy):
129 sys.exit("Error: policy file " + options.policy + " does not exist\n"
130 + parser.usage)
Jeff Vander Stoepbdfc0302017-05-25 09:53:47 -0700131
Tri Voe3f4f772018-09-28 17:21:08 -0700132 # Mapping files and public platform policy are only necessary for the
133 # TrebleCompatMapping test.
Inseob Kimeb0d40a2023-09-04 19:02:53 +0900134 if not options.basepolicy:
135 sys.exit("Must specify the current platform-only policy file\n"
136 + parser.usage)
137 if not options.mapping:
138 sys.exit("Must specify a compatibility mapping file\n"
139 + parser.usage)
140 if not options.oldpolicy:
141 sys.exit("Must specify the previous monolithic policy file\n"
142 + parser.usage)
143 if not options.base_pub_policy:
144 sys.exit("Must specify the current platform-only public policy "
145 + ".cil file\n" + parser.usage)
146 basepol = policy.Policy(options.basepolicy, None, libpath)
147 oldpol = policy.Policy(options.oldpolicy, None, libpath)
148 mapping = mini_parser.MiniCilParser(options.mapping)
149 pubpol = mini_parser.MiniCilParser(options.base_pub_policy)
150 test_policy.compatSetup(basepol, oldpol, mapping, pubpol.types)
Jeff Vander Stoepfe0910c2017-11-20 13:25:47 -0800151
Inseob Kimeb0d40a2023-09-04 19:02:53 +0900152 pol = policy.Policy(options.policy, None, libpath)
Thiébaud Weksteendab3b1a2023-03-06 13:54:07 +1100153 test_policy.setup(pol)
Jeff Vander Stoepbdfc0302017-05-25 09:53:47 -0700154
Jeff Vander Stoep1fc06822017-05-31 15:36:07 -0700155 if DEBUG:
Thiébaud Weksteendab3b1a2023-03-06 13:54:07 +1100156 test_policy.PrintScontexts()
Jeff Vander Stoep1fc06822017-05-31 15:36:07 -0700157
Inseob Kimeb0d40a2023-09-04 19:02:53 +0900158 results = TestTrebleCompatMapping(test_policy)
Jeff Vander Stoepbdfc0302017-05-25 09:53:47 -0700159
160 if len(results) > 0:
161 sys.exit(results)
Inseob Kim4912a242022-07-25 11:30:02 +0900162
163if __name__ == '__main__':
164 temp_dir = tempfile.mkdtemp()
165 try:
166 libname = "libsepolwrap" + SHARED_LIB_EXTENSION
167 libpath = os.path.join(temp_dir, libname)
168 with open(libpath, "wb") as f:
169 blob = pkgutil.get_data("treble_sepolicy_tests", libname)
170 if not blob:
171 sys.exit("Error: libsepolwrap does not exist. Is this binary corrupted?\n")
172 f.write(blob)
173 do_main(libpath)
174 finally:
175 shutil.rmtree(temp_dir)