xref: /aosp_15_r20/system/sepolicy/tests/apex_sepolicy_tests_test.py (revision e4a36f4174b17bbab9dc043f4a65dc8d87377290)
1# Copyright 2023 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"""Tests for apex_sepolicy_tests"""
15
16import re
17import shutil
18import tempfile
19import unittest
20
21import apex_sepolicy_tests as apex
22import policy
23
24
25# pylint: disable=missing-docstring
26class ApexSepolicyTests(unittest.TestCase):
27
28    @classmethod
29    def setUpClass(cls) -> None:
30        cls.temp_dir = tempfile.mkdtemp()
31        lib_path = apex.extract_data(apex.LIBSEPOLWRAP, cls.temp_dir)
32        policy_path = apex.extract_data('precompiled_sepolicy', cls.temp_dir)
33        cls.pol = policy.Policy(policy_path, None,  lib_path)
34
35    @classmethod
36    def tearDownClass(cls) -> None:
37        shutil.rmtree(cls.temp_dir)
38
39    # helpers
40
41    @property
42    def pol(self):
43        return self.__class__.pol
44
45    def assert_ok(self, line: str):
46        errors = apex.check_line(self.pol, line, apex.all_rules)
47        self.assertEqual(errors, [], "Should be no errors")
48
49    def assert_error(self, line: str, expected_error: str):
50        pattern = re.compile(expected_error)
51        errors = apex.check_line(self.pol, line, apex.all_rules)
52        for err in errors:
53            if re.search(pattern, err):
54                return
55        self.fail(f"Expected error '{expected_error}' is not found in {errors}")
56
57    # tests
58
59    def test_parse_lines(self):
60        self.assert_ok('# commented line')
61        self.assert_ok('') # empty line
62        self.assert_error('./path1 invalid_contexts',
63                          r'Error: invalid file_contexts: .*')
64        self.assert_error('./path1 u:object_r:vendor_file',
65                          r'Error: invalid file_contexts: .*')
66        self.assert_ok('./path1 u:object_r:vendor_file:s0')
67
68    def test_vintf(self):
69        self.assert_ok('./etc/vintf/fragment.xml u:object_r:vendor_configs_file:s0')
70        self.assert_error('./etc/vintf/fragment.xml u:object_r:vendor_file:s0',
71                          r'Error: \./etc/vintf/fragment\.xml: .* can\'t read')
72
73    def test_permissions(self):
74        self.assert_ok('./etc/permissions/permisssion.xml u:object_r:vendor_configs_file:s0')
75        self.assert_error('./etc/permissions/permisssion.xml u:object_r:vendor_file:s0',
76                          r'Error: \./etc/permissions/permisssion.xml: .* can\'t read')
77
78    def test_initscripts(self):
79        # here, netd_service is chosen randomly for invalid label for a file
80
81        # init reads .rc file
82        self.assert_ok('./etc/init.rc u:object_r:vendor_file:s0')
83        self.assert_error('./etc/init.rc u:object_r:netd_service:s0',
84                          r'Error: .* can\'t read')
85        # init reads .#rc file
86        self.assert_ok('./etc/init.32rc u:object_r:vendor_file:s0')
87        self.assert_error('./etc/init.32rc u:object_r:netd_service:s0',
88                          r'Error: .* can\'t read')
89        # init skips file with unknown extension => no errors
90        self.assert_ok('./etc/init.x32rc u:object_r:vendor_file:s0')
91        self.assert_ok('./etc/init.x32rc u:object_r:netd_service:s0')
92
93    def test_linkerconfig(self):
94        self.assert_ok('./etc/linker.config.pb u:object_r:system_file:s0')
95        self.assert_ok('./etc/linker.config.pb u:object_r:linkerconfig_file:s0')
96        self.assert_error('./etc/linker.config.pb u:object_r:vendor_file:s0',
97                        r'Error: .*linkerconfig.* can\'t read')
98        self.assert_error('./ u:object_r:apex_data_file:s0',
99                        r'Error: .*linkerconfig.* can\'t search')
100
101    def test_unknown_label(self):
102        self.assert_error('./bin/hw/foo u:object_r:foo_exec:s0',
103                        r'Error: \./bin/hw/foo: tcontext\(foo_exec\) is unknown')
104
105    def test_binaries(self):
106        self.assert_ok('./bin/init u:object_r:init_exec:s0')
107        self.assert_ok('./bin/hw/svc u:object_r:init_exec:s0')
108        self.assert_error('./bin/hw/svc u:object_r:vendor_file:s0',
109                          r"Error: .*svc: can\'t be labelled as \'vendor_file\'")
110
111if __name__ == '__main__':
112    unittest.main(verbosity=2)
113