xref: /aosp_15_r20/system/sepolicy/tests/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 pkgutil
19*e4a36f41SAndroid Build Coastguard Workerimport policy
20*e4a36f41SAndroid Build Coastguard Workerimport re
21*e4a36f41SAndroid Build Coastguard Workerimport shutil
22*e4a36f41SAndroid Build Coastguard Workerimport sys
23*e4a36f41SAndroid Build Coastguard Workerimport tempfile
24*e4a36f41SAndroid Build Coastguard Worker
25*e4a36f41SAndroid Build Coastguard WorkerSHARED_LIB_EXTENSION = '.dylib' if sys.platform == 'darwin' else '.so'
26*e4a36f41SAndroid Build Coastguard Worker
27*e4a36f41SAndroid Build Coastguard Worker#############################################################
28*e4a36f41SAndroid Build Coastguard Worker# Tests
29*e4a36f41SAndroid Build Coastguard Worker#############################################################
30*e4a36f41SAndroid Build Coastguard Workerdef TestDataTypeViolations(pol):
31*e4a36f41SAndroid Build Coastguard Worker    return pol.AssertPathTypesHaveAttr(["/data/"], [], "data_file_type")
32*e4a36f41SAndroid Build Coastguard Worker
33*e4a36f41SAndroid Build Coastguard Workerdef TestSystemTypeViolations(pol):
34*e4a36f41SAndroid Build Coastguard Worker    partitions = ["/system/", "/system_ext/", "/product/"]
35*e4a36f41SAndroid Build Coastguard Worker    exceptions = [
36*e4a36f41SAndroid Build Coastguard Worker        # devices before treble don't have a vendor partition
37*e4a36f41SAndroid Build Coastguard Worker        "/system/vendor/",
38*e4a36f41SAndroid Build Coastguard Worker
39*e4a36f41SAndroid Build Coastguard Worker        # overlay files are mounted over vendor
40*e4a36f41SAndroid Build Coastguard Worker        "/product/overlay/",
41*e4a36f41SAndroid Build Coastguard Worker        "/product/vendor_overlay/",
42*e4a36f41SAndroid Build Coastguard Worker        "/system/overlay/",
43*e4a36f41SAndroid Build Coastguard Worker        "/system/product/overlay/",
44*e4a36f41SAndroid Build Coastguard Worker        "/system/product/vendor_overlay/",
45*e4a36f41SAndroid Build Coastguard Worker        "/system/system_ext/overlay/",
46*e4a36f41SAndroid Build Coastguard Worker        "/system_ext/overlay/",
47*e4a36f41SAndroid Build Coastguard Worker
48*e4a36f41SAndroid Build Coastguard Worker        # adb_keys_file hasn't been a system_file_type
49*e4a36f41SAndroid Build Coastguard Worker        "/product/etc/security/adb_keys",
50*e4a36f41SAndroid Build Coastguard Worker        "/system/product/etc/security/adb_keys",
51*e4a36f41SAndroid Build Coastguard Worker    ]
52*e4a36f41SAndroid Build Coastguard Worker
53*e4a36f41SAndroid Build Coastguard Worker    return pol.AssertPathTypesHaveAttr(partitions, exceptions, "system_file_type")
54*e4a36f41SAndroid Build Coastguard Worker
55*e4a36f41SAndroid Build Coastguard Workerdef TestBpffsTypeViolations(pol):
56*e4a36f41SAndroid Build Coastguard Worker    return pol.AssertGenfsFilesystemTypesHaveAttr("bpf", "bpffs_type")
57*e4a36f41SAndroid Build Coastguard Worker
58*e4a36f41SAndroid Build Coastguard Workerdef TestProcTypeViolations(pol):
59*e4a36f41SAndroid Build Coastguard Worker    return pol.AssertGenfsFilesystemTypesHaveAttr("proc", "proc_type")
60*e4a36f41SAndroid Build Coastguard Worker
61*e4a36f41SAndroid Build Coastguard Workerdef TestSysfsTypeViolations(pol):
62*e4a36f41SAndroid Build Coastguard Worker    ret = pol.AssertGenfsFilesystemTypesHaveAttr("sysfs", "sysfs_type")
63*e4a36f41SAndroid Build Coastguard Worker    ret += pol.AssertPathTypesHaveAttr(["/sys/"], ["/sys/kernel/debug/",
64*e4a36f41SAndroid Build Coastguard Worker                                    "/sys/kernel/tracing"], "sysfs_type")
65*e4a36f41SAndroid Build Coastguard Worker    return ret
66*e4a36f41SAndroid Build Coastguard Worker
67*e4a36f41SAndroid Build Coastguard Workerdef TestDebugfsTypeViolations(pol):
68*e4a36f41SAndroid Build Coastguard Worker    ret = pol.AssertGenfsFilesystemTypesHaveAttr("debugfs", "debugfs_type")
69*e4a36f41SAndroid Build Coastguard Worker    ret += pol.AssertPathTypesHaveAttr(["/sys/kernel/debug/",
70*e4a36f41SAndroid Build Coastguard Worker                                    "/sys/kernel/tracing"], [], "debugfs_type")
71*e4a36f41SAndroid Build Coastguard Worker    return ret
72*e4a36f41SAndroid Build Coastguard Worker
73*e4a36f41SAndroid Build Coastguard Workerdef TestTracefsTypeViolations(pol):
74*e4a36f41SAndroid Build Coastguard Worker    ret = pol.AssertGenfsFilesystemTypesHaveAttr("tracefs", "tracefs_type")
75*e4a36f41SAndroid Build Coastguard Worker    ret += pol.AssertPathTypesHaveAttr(["/sys/kernel/tracing"], [], "tracefs_type")
76*e4a36f41SAndroid Build Coastguard Worker    ret += pol.AssertPathTypesDoNotHaveAttr(["/sys/kernel/debug"],
77*e4a36f41SAndroid Build Coastguard Worker                                            ["/sys/kernel/debug/tracing"], "tracefs_type",
78*e4a36f41SAndroid Build Coastguard Worker                                            [])
79*e4a36f41SAndroid Build Coastguard Worker    return ret
80*e4a36f41SAndroid Build Coastguard Worker
81*e4a36f41SAndroid Build Coastguard Workerdef TestVendorTypeViolations(pol):
82*e4a36f41SAndroid Build Coastguard Worker    partitions = ["/vendor/", "/odm/"]
83*e4a36f41SAndroid Build Coastguard Worker    exceptions = [
84*e4a36f41SAndroid Build Coastguard Worker        "/vendor/etc/selinux/",
85*e4a36f41SAndroid Build Coastguard Worker        "/vendor/odm/etc/selinux/",
86*e4a36f41SAndroid Build Coastguard Worker        "/odm/etc/selinux/",
87*e4a36f41SAndroid Build Coastguard Worker    ]
88*e4a36f41SAndroid Build Coastguard Worker    return pol.AssertPathTypesHaveAttr(partitions, exceptions, "vendor_file_type")
89*e4a36f41SAndroid Build Coastguard Worker
90*e4a36f41SAndroid Build Coastguard Workerdef TestCoreDataTypeViolations(pol):
91*e4a36f41SAndroid Build Coastguard Worker    ret = pol.AssertPathTypesHaveAttr(["/data/"], ["/data/vendor",
92*e4a36f41SAndroid Build Coastguard Worker            "/data/vendor_ce", "/data/vendor_de"], "core_data_file_type")
93*e4a36f41SAndroid Build Coastguard Worker    ret += pol.AssertPathTypesDoNotHaveAttr(["/data/vendor/", "/data/vendor_ce/",
94*e4a36f41SAndroid Build Coastguard Worker        "/data/vendor_de/"], [], "core_data_file_type")
95*e4a36f41SAndroid Build Coastguard Worker    return ret
96*e4a36f41SAndroid Build Coastguard Worker
97*e4a36f41SAndroid Build Coastguard Workerdef TestPropertyTypeViolations(pol):
98*e4a36f41SAndroid Build Coastguard Worker    return pol.AssertPropertyOwnersAreExclusive()
99*e4a36f41SAndroid Build Coastguard Worker
100*e4a36f41SAndroid Build Coastguard Workerdef TestAppDataTypeViolations(pol):
101*e4a36f41SAndroid Build Coastguard Worker    # Types with the app_data_file_type should only be used for app data files
102*e4a36f41SAndroid Build Coastguard Worker    # (/data/data/package.name etc) via seapp_contexts, and never applied
103*e4a36f41SAndroid Build Coastguard Worker    # explicitly to other files.
104*e4a36f41SAndroid Build Coastguard Worker    partitions = [
105*e4a36f41SAndroid Build Coastguard Worker        "/data/",
106*e4a36f41SAndroid Build Coastguard Worker        "/vendor/",
107*e4a36f41SAndroid Build Coastguard Worker        "/odm/",
108*e4a36f41SAndroid Build Coastguard Worker        "/product/",
109*e4a36f41SAndroid Build Coastguard Worker    ]
110*e4a36f41SAndroid Build Coastguard Worker    exceptions = [
111*e4a36f41SAndroid Build Coastguard Worker        # These are used for app data files for the corresponding user and
112*e4a36f41SAndroid Build Coastguard Worker        # assorted other files.
113*e4a36f41SAndroid Build Coastguard Worker        # TODO(b/172812577): Use different types for the different purposes
114*e4a36f41SAndroid Build Coastguard Worker        "shell_data_file",
115*e4a36f41SAndroid Build Coastguard Worker        "bluetooth_data_file",
116*e4a36f41SAndroid Build Coastguard Worker        "nfc_data_file",
117*e4a36f41SAndroid Build Coastguard Worker        "radio_data_file",
118*e4a36f41SAndroid Build Coastguard Worker    ]
119*e4a36f41SAndroid Build Coastguard Worker    return pol.AssertPathTypesDoNotHaveAttr(partitions, [], "app_data_file_type",
120*e4a36f41SAndroid Build Coastguard Worker                                            exceptions)
121*e4a36f41SAndroid Build Coastguard Workerdef TestDmaHeapDevTypeViolations(pol):
122*e4a36f41SAndroid Build Coastguard Worker    return pol.AssertPathTypesHaveAttr(["/dev/dma_heap/"], [],
123*e4a36f41SAndroid Build Coastguard Worker                                       "dmabuf_heap_device_type")
124*e4a36f41SAndroid Build Coastguard Worker
125*e4a36f41SAndroid Build Coastguard Workerdef TestCoredomainViolations(test_policy):
126*e4a36f41SAndroid Build Coastguard Worker    # verify that all domains launched from /system have the coredomain
127*e4a36f41SAndroid Build Coastguard Worker    # attribute
128*e4a36f41SAndroid Build Coastguard Worker    ret = ""
129*e4a36f41SAndroid Build Coastguard Worker
130*e4a36f41SAndroid Build Coastguard Worker    for d in test_policy.alldomains:
131*e4a36f41SAndroid Build Coastguard Worker        domain = test_policy.alldomains[d]
132*e4a36f41SAndroid Build Coastguard Worker        if domain.fromSystem and domain.fromVendor:
133*e4a36f41SAndroid Build Coastguard Worker            ret += "The following domain is system and vendor: " + d + "\n"
134*e4a36f41SAndroid Build Coastguard Worker
135*e4a36f41SAndroid Build Coastguard Worker    for domain in test_policy.alldomains.values():
136*e4a36f41SAndroid Build Coastguard Worker        ret += domain.error
137*e4a36f41SAndroid Build Coastguard Worker
138*e4a36f41SAndroid Build Coastguard Worker    violators = []
139*e4a36f41SAndroid Build Coastguard Worker    for d in test_policy.alldomains:
140*e4a36f41SAndroid Build Coastguard Worker        domain = test_policy.alldomains[d]
141*e4a36f41SAndroid Build Coastguard Worker        if domain.fromSystem and "coredomain" not in domain.attributes:
142*e4a36f41SAndroid Build Coastguard Worker                violators.append(d);
143*e4a36f41SAndroid Build Coastguard Worker    if len(violators) > 0:
144*e4a36f41SAndroid Build Coastguard Worker        ret += "The following domain(s) must be associated with the "
145*e4a36f41SAndroid Build Coastguard Worker        ret += "\"coredomain\" attribute because they are executed off of "
146*e4a36f41SAndroid Build Coastguard Worker        ret += "/system:\n"
147*e4a36f41SAndroid Build Coastguard Worker        ret += " ".join(str(x) for x in sorted(violators)) + "\n"
148*e4a36f41SAndroid Build Coastguard Worker
149*e4a36f41SAndroid Build Coastguard Worker    # verify that all domains launched form /vendor do not have the coredomain
150*e4a36f41SAndroid Build Coastguard Worker    # attribute
151*e4a36f41SAndroid Build Coastguard Worker    violators = []
152*e4a36f41SAndroid Build Coastguard Worker    for d in test_policy.alldomains:
153*e4a36f41SAndroid Build Coastguard Worker        domain = test_policy.alldomains[d]
154*e4a36f41SAndroid Build Coastguard Worker        if domain.fromVendor and "coredomain" in domain.attributes:
155*e4a36f41SAndroid Build Coastguard Worker            violators.append(d)
156*e4a36f41SAndroid Build Coastguard Worker    if len(violators) > 0:
157*e4a36f41SAndroid Build Coastguard Worker        ret += "The following domains must not be associated with the "
158*e4a36f41SAndroid Build Coastguard Worker        ret += "\"coredomain\" attribute because they are executed off of "
159*e4a36f41SAndroid Build Coastguard Worker        ret += "/vendor or /system/vendor:\n"
160*e4a36f41SAndroid Build Coastguard Worker        ret += " ".join(str(x) for x in sorted(violators)) + "\n"
161*e4a36f41SAndroid Build Coastguard Worker
162*e4a36f41SAndroid Build Coastguard Worker    return ret
163*e4a36f41SAndroid Build Coastguard Worker
164*e4a36f41SAndroid Build Coastguard Workerdef TestViolatorAttribute(test_policy, attribute):
165*e4a36f41SAndroid Build Coastguard Worker    # TODO(b/113124961): re-enable once all violator attributes are removed.
166*e4a36f41SAndroid Build Coastguard Worker    return ""
167*e4a36f41SAndroid Build Coastguard Worker
168*e4a36f41SAndroid Build Coastguard Worker    # ret = ""
169*e4a36f41SAndroid Build Coastguard Worker    # return ret
170*e4a36f41SAndroid Build Coastguard Worker
171*e4a36f41SAndroid Build Coastguard Worker    # violators = test_policy.DomainsWithAttribute(attribute)
172*e4a36f41SAndroid Build Coastguard Worker    # if len(violators) > 0:
173*e4a36f41SAndroid Build Coastguard Worker    #    ret += "SELinux: The following domains violate the Treble ban "
174*e4a36f41SAndroid Build Coastguard Worker    #    ret += "against use of the " + attribute + " attribute: "
175*e4a36f41SAndroid Build Coastguard Worker    #    ret += " ".join(str(x) for x in sorted(violators)) + "\n"
176*e4a36f41SAndroid Build Coastguard Worker    # return ret
177*e4a36f41SAndroid Build Coastguard Worker
178*e4a36f41SAndroid Build Coastguard Workerdef TestViolatorAttributes(test_policy):
179*e4a36f41SAndroid Build Coastguard Worker    ret = ""
180*e4a36f41SAndroid Build Coastguard Worker    ret += TestViolatorAttribute(test_policy, "socket_between_core_and_vendor_violators")
181*e4a36f41SAndroid Build Coastguard Worker    ret += TestViolatorAttribute(test_policy, "vendor_executes_system_violators")
182*e4a36f41SAndroid Build Coastguard Worker    return ret
183*e4a36f41SAndroid Build Coastguard Worker
184*e4a36f41SAndroid Build Coastguard Workerdef TestIsolatedAttributeConsistency(test_policy):
185*e4a36f41SAndroid Build Coastguard Worker    permissionAllowList = {
186*e4a36f41SAndroid Build Coastguard Worker        # access given from technical_debt.cil
187*e4a36f41SAndroid Build Coastguard Worker        "codec2_config_prop" : ["file"],
188*e4a36f41SAndroid Build Coastguard Worker        "device_config_nnapi_native_prop":["file"],
189*e4a36f41SAndroid Build Coastguard Worker        "gpu_device": ["dir"],
190*e4a36f41SAndroid Build Coastguard Worker        "hal_allocator_default":["binder", "fd"],
191*e4a36f41SAndroid Build Coastguard Worker        "hal_codec2": ["binder", "fd"],
192*e4a36f41SAndroid Build Coastguard Worker        "hal_codec2_hwservice":["hwservice_manager"],
193*e4a36f41SAndroid Build Coastguard Worker        "hal_graphics_allocator": ["binder", "fd"],
194*e4a36f41SAndroid Build Coastguard Worker        "hal_graphics_allocator_service":["service_manager"],
195*e4a36f41SAndroid Build Coastguard Worker        "hal_graphics_allocator_hwservice":["hwservice_manager"],
196*e4a36f41SAndroid Build Coastguard Worker        "hal_graphics_allocator_server":["binder", "service_manager"],
197*e4a36f41SAndroid Build Coastguard Worker        "hal_graphics_mapper_hwservice":["hwservice_manager"],
198*e4a36f41SAndroid Build Coastguard Worker        "hal_graphics_mapper_service":["service_manager"],
199*e4a36f41SAndroid Build Coastguard Worker        "hal_neuralnetworks": ["binder", "fd"],
200*e4a36f41SAndroid Build Coastguard Worker        "hal_neuralnetworks_service": ["service_manager"],
201*e4a36f41SAndroid Build Coastguard Worker        "hal_neuralnetworks_hwservice":["hwservice_manager"],
202*e4a36f41SAndroid Build Coastguard Worker        "hal_omx_hwservice":["hwservice_manager"],
203*e4a36f41SAndroid Build Coastguard Worker        "hidl_allocator_hwservice":["hwservice_manager"],
204*e4a36f41SAndroid Build Coastguard Worker        "hidl_manager_hwservice":["hwservice_manager"],
205*e4a36f41SAndroid Build Coastguard Worker        "hidl_memory_hwservice":["hwservice_manager"],
206*e4a36f41SAndroid Build Coastguard Worker        "hidl_token_hwservice":["hwservice_manager"],
207*e4a36f41SAndroid Build Coastguard Worker        "hwservicemanager":["binder"],
208*e4a36f41SAndroid Build Coastguard Worker        "hwservicemanager_prop":["file"],
209*e4a36f41SAndroid Build Coastguard Worker        "mediacodec":["binder", "fd"],
210*e4a36f41SAndroid Build Coastguard Worker        "mediaswcodec":["binder", "fd"],
211*e4a36f41SAndroid Build Coastguard Worker        "media_variant_prop":["file"],
212*e4a36f41SAndroid Build Coastguard Worker        "nnapi_ext_deny_product_prop":["file"],
213*e4a36f41SAndroid Build Coastguard Worker        "servicemanager":["fd"],
214*e4a36f41SAndroid Build Coastguard Worker        "sysfs_gpu": ["file"],
215*e4a36f41SAndroid Build Coastguard Worker        "toolbox_exec": ["file"],
216*e4a36f41SAndroid Build Coastguard Worker        # extra types being granted to isolated_compute_app
217*e4a36f41SAndroid Build Coastguard Worker        "isolated_compute_allowed":["service_manager", "chr_file"],
218*e4a36f41SAndroid Build Coastguard Worker    }
219*e4a36f41SAndroid Build Coastguard Worker
220*e4a36f41SAndroid Build Coastguard Worker    def resolveHalServerSubtype(target):
221*e4a36f41SAndroid Build Coastguard Worker        # permission given as a client in technical_debt.cil
222*e4a36f41SAndroid Build Coastguard Worker        hal_server_attributes = [
223*e4a36f41SAndroid Build Coastguard Worker            "hal_codec2_server",
224*e4a36f41SAndroid Build Coastguard Worker            "hal_graphics_allocator_server",
225*e4a36f41SAndroid Build Coastguard Worker            "hal_neuralnetworks_server"]
226*e4a36f41SAndroid Build Coastguard Worker
227*e4a36f41SAndroid Build Coastguard Worker        for attr in hal_server_attributes:
228*e4a36f41SAndroid Build Coastguard Worker            if target in test_policy.pol.QueryTypeAttribute(Type=attr, IsAttr=True):
229*e4a36f41SAndroid Build Coastguard Worker                return attr.rsplit("_", 1)[0]
230*e4a36f41SAndroid Build Coastguard Worker        return target
231*e4a36f41SAndroid Build Coastguard Worker
232*e4a36f41SAndroid Build Coastguard Worker    def checkIsolatedComputeAllowed(tctx, tclass):
233*e4a36f41SAndroid Build Coastguard Worker        # check if the permission is in isolated_compute_allowed
234*e4a36f41SAndroid Build Coastguard Worker        allowedMemberTypes = test_policy.pol.QueryTypeAttribute(Type="isolated_compute_allowed_service", IsAttr=True) \
235*e4a36f41SAndroid Build Coastguard Worker            .union(test_policy.pol.QueryTypeAttribute(Type="isolated_compute_allowed_device", IsAttr=True))
236*e4a36f41SAndroid Build Coastguard Worker        return tctx in allowedMemberTypes and tclass in permissionAllowList["isolated_compute_allowed"]
237*e4a36f41SAndroid Build Coastguard Worker
238*e4a36f41SAndroid Build Coastguard Worker    def checkPermissions(permissions):
239*e4a36f41SAndroid Build Coastguard Worker        violated_permissions = []
240*e4a36f41SAndroid Build Coastguard Worker        for perm in permissions:
241*e4a36f41SAndroid Build Coastguard Worker            tctx, tclass, p = perm.split(":")
242*e4a36f41SAndroid Build Coastguard Worker            tctx = resolveHalServerSubtype(tctx)
243*e4a36f41SAndroid Build Coastguard Worker            # check unwanted permissions
244*e4a36f41SAndroid Build Coastguard Worker            if not checkIsolatedComputeAllowed(tctx, tclass) and \
245*e4a36f41SAndroid Build Coastguard Worker                ( tctx not in permissionAllowList \
246*e4a36f41SAndroid Build Coastguard Worker                    or tclass not in permissionAllowList[tctx] \
247*e4a36f41SAndroid Build Coastguard Worker                    or ( p == "write") \
248*e4a36f41SAndroid Build Coastguard Worker                    or ( p == "rw_file_perms") ):
249*e4a36f41SAndroid Build Coastguard Worker                violated_permissions += [perm]
250*e4a36f41SAndroid Build Coastguard Worker        return violated_permissions
251*e4a36f41SAndroid Build Coastguard Worker
252*e4a36f41SAndroid Build Coastguard Worker    ret = ""
253*e4a36f41SAndroid Build Coastguard Worker
254*e4a36f41SAndroid Build Coastguard Worker    isolatedMemberTypes = test_policy.pol.QueryTypeAttribute(Type="isolated_app_all", IsAttr=True)
255*e4a36f41SAndroid Build Coastguard Worker    baseRules = test_policy.pol.QueryExpandedTERule(scontext=["isolated_app"])
256*e4a36f41SAndroid Build Coastguard Worker    basePermissionSet = set([":".join([rule.tctx, rule.tclass, perm])
257*e4a36f41SAndroid Build Coastguard Worker                            for rule in baseRules for perm in rule.perms])
258*e4a36f41SAndroid Build Coastguard Worker    for subType in isolatedMemberTypes:
259*e4a36f41SAndroid Build Coastguard Worker        if subType == "isolated_app" : continue
260*e4a36f41SAndroid Build Coastguard Worker        currentTypeRule = test_policy.pol.QueryExpandedTERule(scontext=[subType])
261*e4a36f41SAndroid Build Coastguard Worker        typePermissionSet = set([":".join([rule.tctx, rule.tclass, perm])
262*e4a36f41SAndroid Build Coastguard Worker                                for rule in currentTypeRule for perm in rule.perms
263*e4a36f41SAndroid Build Coastguard Worker                                if not rule.tctx in [subType, subType + "_userfaultfd"]])
264*e4a36f41SAndroid Build Coastguard Worker        deltaPermissionSet = typePermissionSet.difference(basePermissionSet)
265*e4a36f41SAndroid Build Coastguard Worker        violated_permissions = checkPermissions(list(deltaPermissionSet))
266*e4a36f41SAndroid Build Coastguard Worker        for perm in violated_permissions:
267*e4a36f41SAndroid Build Coastguard Worker            ret += "allow %s %s:%s %s \n" % (subType, *perm.split(":"))
268*e4a36f41SAndroid Build Coastguard Worker
269*e4a36f41SAndroid Build Coastguard Worker    if ret:
270*e4a36f41SAndroid Build Coastguard Worker        ret = ("Found prohibited permission granted for isolated like types. " + \
271*e4a36f41SAndroid Build Coastguard Worker            "Please replace your allow statements that involve \"-isolated_app\" with " + \
272*e4a36f41SAndroid Build Coastguard Worker            "\"-isolated_app_all\". Violations are shown as the following: \n")  + ret
273*e4a36f41SAndroid Build Coastguard Worker    return ret
274*e4a36f41SAndroid Build Coastguard Worker
275*e4a36f41SAndroid Build Coastguard Workerdef TestDevTypeViolations(pol):
276*e4a36f41SAndroid Build Coastguard Worker    exceptions = [
277*e4a36f41SAndroid Build Coastguard Worker        "/dev/socket",
278*e4a36f41SAndroid Build Coastguard Worker    ]
279*e4a36f41SAndroid Build Coastguard Worker    exceptionTypes = [
280*e4a36f41SAndroid Build Coastguard Worker        "boringssl_self_test_marker",  # /dev/boringssl/selftest
281*e4a36f41SAndroid Build Coastguard Worker        "cgroup_rc_file",              # /dev/cgroup.rc
282*e4a36f41SAndroid Build Coastguard Worker        "dev_cpu_variant",             # /dev/cpu_variant:{arch}
283*e4a36f41SAndroid Build Coastguard Worker        "fscklogs",                    # /dev/fscklogs
284*e4a36f41SAndroid Build Coastguard Worker        "properties_serial",           # /dev/__properties__/properties_serial
285*e4a36f41SAndroid Build Coastguard Worker        "property_info",               # /dev/__properties__/property_info
286*e4a36f41SAndroid Build Coastguard Worker        "runtime_event_log_tags_file", # /dev/event-log-tags
287*e4a36f41SAndroid Build Coastguard Worker    ]
288*e4a36f41SAndroid Build Coastguard Worker    return pol.AssertPathTypesHaveAttr(["/dev"], exceptions,
289*e4a36f41SAndroid Build Coastguard Worker                                       "dev_type", exceptionTypes)
290*e4a36f41SAndroid Build Coastguard Worker
291*e4a36f41SAndroid Build Coastguard Worker###
292*e4a36f41SAndroid Build Coastguard Worker# extend OptionParser to allow the same option flag to be used multiple times.
293*e4a36f41SAndroid Build Coastguard Worker# This is used to allow multiple file_contexts files and tests to be
294*e4a36f41SAndroid Build Coastguard Worker# specified.
295*e4a36f41SAndroid Build Coastguard Worker#
296*e4a36f41SAndroid Build Coastguard Workerclass MultipleOption(Option):
297*e4a36f41SAndroid Build Coastguard Worker    ACTIONS = Option.ACTIONS + ("extend",)
298*e4a36f41SAndroid Build Coastguard Worker    STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",)
299*e4a36f41SAndroid Build Coastguard Worker    TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",)
300*e4a36f41SAndroid Build Coastguard Worker    ALWAYS_TYPED_ACTIONS = Option.ALWAYS_TYPED_ACTIONS + ("extend",)
301*e4a36f41SAndroid Build Coastguard Worker
302*e4a36f41SAndroid Build Coastguard Worker    def take_action(self, action, dest, opt, value, values, parser):
303*e4a36f41SAndroid Build Coastguard Worker        if action == "extend":
304*e4a36f41SAndroid Build Coastguard Worker            values.ensure_value(dest, []).append(value)
305*e4a36f41SAndroid Build Coastguard Worker        else:
306*e4a36f41SAndroid Build Coastguard Worker            Option.take_action(self, action, dest, opt, value, values, parser)
307*e4a36f41SAndroid Build Coastguard Worker
308*e4a36f41SAndroid Build Coastguard WorkerTEST_NAMES = [ name for name in dir() if name.startswith('Test') ]
309*e4a36f41SAndroid Build Coastguard Worker
310*e4a36f41SAndroid Build Coastguard Workerdef do_main(libpath):
311*e4a36f41SAndroid Build Coastguard Worker    """
312*e4a36f41SAndroid Build Coastguard Worker    Args:
313*e4a36f41SAndroid Build Coastguard Worker        libpath: string, path to libsepolwrap.so
314*e4a36f41SAndroid Build Coastguard Worker    """
315*e4a36f41SAndroid Build Coastguard Worker    usage = "sepolicy_tests -f vendor_file_contexts -f "
316*e4a36f41SAndroid Build Coastguard Worker    usage +="plat_file_contexts -p policy [--test test] [--help]"
317*e4a36f41SAndroid Build Coastguard Worker    parser = OptionParser(option_class=MultipleOption, usage=usage)
318*e4a36f41SAndroid Build Coastguard Worker    parser.add_option("-f", "--file_contexts", dest="file_contexts",
319*e4a36f41SAndroid Build Coastguard Worker            metavar="FILE", action="extend", type="string")
320*e4a36f41SAndroid Build Coastguard Worker    parser.add_option("-p", "--policy", dest="policy", metavar="FILE")
321*e4a36f41SAndroid Build Coastguard Worker    parser.add_option("-t", "--test", dest="test", action="extend",
322*e4a36f41SAndroid Build Coastguard Worker            help="Test options include "+str(TEST_NAMES))
323*e4a36f41SAndroid Build Coastguard Worker
324*e4a36f41SAndroid Build Coastguard Worker    (options, args) = parser.parse_args()
325*e4a36f41SAndroid Build Coastguard Worker
326*e4a36f41SAndroid Build Coastguard Worker    if not options.policy:
327*e4a36f41SAndroid Build Coastguard Worker        sys.exit("Must specify monolithic policy file\n" + parser.usage)
328*e4a36f41SAndroid Build Coastguard Worker    if not os.path.exists(options.policy):
329*e4a36f41SAndroid Build Coastguard Worker        sys.exit("Error: policy file " + options.policy + " does not exist\n"
330*e4a36f41SAndroid Build Coastguard Worker                + parser.usage)
331*e4a36f41SAndroid Build Coastguard Worker
332*e4a36f41SAndroid Build Coastguard Worker    if not options.file_contexts:
333*e4a36f41SAndroid Build Coastguard Worker        sys.exit("Error: Must specify file_contexts file(s)\n" + parser.usage)
334*e4a36f41SAndroid Build Coastguard Worker    for f in options.file_contexts:
335*e4a36f41SAndroid Build Coastguard Worker        if not os.path.exists(f):
336*e4a36f41SAndroid Build Coastguard Worker            sys.exit("Error: File_contexts file " + f + " does not exist\n" +
337*e4a36f41SAndroid Build Coastguard Worker                    parser.usage)
338*e4a36f41SAndroid Build Coastguard Worker
339*e4a36f41SAndroid Build Coastguard Worker    pol = policy.Policy(options.policy, options.file_contexts, libpath)
340*e4a36f41SAndroid Build Coastguard Worker    test_policy = policy.TestPolicy()
341*e4a36f41SAndroid Build Coastguard Worker    test_policy.setup(pol)
342*e4a36f41SAndroid Build Coastguard Worker
343*e4a36f41SAndroid Build Coastguard Worker    results = ""
344*e4a36f41SAndroid Build Coastguard Worker    # If an individual test is not specified, run all tests.
345*e4a36f41SAndroid Build Coastguard Worker    if options.test is None or "TestBpffsTypeViolations" in options.test:
346*e4a36f41SAndroid Build Coastguard Worker        results += TestBpffsTypeViolations(pol)
347*e4a36f41SAndroid Build Coastguard Worker    if options.test is None or "TestDataTypeViolations" in options.test:
348*e4a36f41SAndroid Build Coastguard Worker        results += TestDataTypeViolations(pol)
349*e4a36f41SAndroid Build Coastguard Worker    if options.test is None or "TestProcTypeViolations" in options.test:
350*e4a36f41SAndroid Build Coastguard Worker        results += TestProcTypeViolations(pol)
351*e4a36f41SAndroid Build Coastguard Worker    if options.test is None or "TestSysfsTypeViolations" in options.test:
352*e4a36f41SAndroid Build Coastguard Worker        results += TestSysfsTypeViolations(pol)
353*e4a36f41SAndroid Build Coastguard Worker    if options.test is None or "TestSystemTypeViolations" in options.test:
354*e4a36f41SAndroid Build Coastguard Worker        results += TestSystemTypeViolations(pol)
355*e4a36f41SAndroid Build Coastguard Worker    if options.test is None or "TestDebugfsTypeViolations" in options.test:
356*e4a36f41SAndroid Build Coastguard Worker        results += TestDebugfsTypeViolations(pol)
357*e4a36f41SAndroid Build Coastguard Worker    if options.test is None or "TestTracefsTypeViolations" in options.test:
358*e4a36f41SAndroid Build Coastguard Worker        results += TestTracefsTypeViolations(pol)
359*e4a36f41SAndroid Build Coastguard Worker    if options.test is None or "TestVendorTypeViolations" in options.test:
360*e4a36f41SAndroid Build Coastguard Worker        results += TestVendorTypeViolations(pol)
361*e4a36f41SAndroid Build Coastguard Worker    if options.test is None or "TestCoreDataTypeViolations" in options.test:
362*e4a36f41SAndroid Build Coastguard Worker        results += TestCoreDataTypeViolations(pol)
363*e4a36f41SAndroid Build Coastguard Worker    if options.test is None or "TestPropertyTypeViolations" in options.test:
364*e4a36f41SAndroid Build Coastguard Worker        results += TestPropertyTypeViolations(pol)
365*e4a36f41SAndroid Build Coastguard Worker    if options.test is None or "TestAppDataTypeViolations" in options.test:
366*e4a36f41SAndroid Build Coastguard Worker        results += TestAppDataTypeViolations(pol)
367*e4a36f41SAndroid Build Coastguard Worker    if options.test is None or "TestDmaHeapDevTypeViolations" in options.test:
368*e4a36f41SAndroid Build Coastguard Worker        results += TestDmaHeapDevTypeViolations(pol)
369*e4a36f41SAndroid Build Coastguard Worker    if options.test is None or "TestCoredomainViolations" in options.test:
370*e4a36f41SAndroid Build Coastguard Worker        results += TestCoredomainViolations(test_policy)
371*e4a36f41SAndroid Build Coastguard Worker    if options.test is None or "TestViolatorAttributes" in options.test:
372*e4a36f41SAndroid Build Coastguard Worker        results += TestViolatorAttributes(test_policy)
373*e4a36f41SAndroid Build Coastguard Worker    if options.test is None or "TestIsolatedAttributeConsistency" in options.test:
374*e4a36f41SAndroid Build Coastguard Worker        results += TestIsolatedAttributeConsistency(test_policy)
375*e4a36f41SAndroid Build Coastguard Worker
376*e4a36f41SAndroid Build Coastguard Worker    # dev type test won't be run as default
377*e4a36f41SAndroid Build Coastguard Worker    if options.test and "TestDevTypeViolations" in options.test:
378*e4a36f41SAndroid Build Coastguard Worker        results += TestDevTypeViolations(pol)
379*e4a36f41SAndroid Build Coastguard Worker
380*e4a36f41SAndroid Build Coastguard Worker    if len(results) > 0:
381*e4a36f41SAndroid Build Coastguard Worker        sys.exit(results)
382*e4a36f41SAndroid Build Coastguard Worker
383*e4a36f41SAndroid Build Coastguard Workerif __name__ == '__main__':
384*e4a36f41SAndroid Build Coastguard Worker    temp_dir = tempfile.mkdtemp()
385*e4a36f41SAndroid Build Coastguard Worker    try:
386*e4a36f41SAndroid Build Coastguard Worker        libname = "libsepolwrap" + SHARED_LIB_EXTENSION
387*e4a36f41SAndroid Build Coastguard Worker        libpath = os.path.join(temp_dir, libname)
388*e4a36f41SAndroid Build Coastguard Worker        with open(libpath, "wb") as f:
389*e4a36f41SAndroid Build Coastguard Worker            blob = pkgutil.get_data("sepolicy_tests", libname)
390*e4a36f41SAndroid Build Coastguard Worker            if not blob:
391*e4a36f41SAndroid Build Coastguard Worker                sys.exit("Error: libsepolwrap does not exist. Is this binary corrupted?\n")
392*e4a36f41SAndroid Build Coastguard Worker            f.write(blob)
393*e4a36f41SAndroid Build Coastguard Worker        do_main(libpath)
394*e4a36f41SAndroid Build Coastguard Worker    finally:
395*e4a36f41SAndroid Build Coastguard Worker        shutil.rmtree(temp_dir)
396