| # Copyright 2023 The Android Open Source Project |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| """Tests for apex_sepolicy_tests""" |
| |
| import re |
| import shutil |
| import tempfile |
| import unittest |
| |
| import apex_sepolicy_tests as apex |
| import policy |
| |
| |
| # pylint: disable=missing-docstring |
| class ApexSepolicyTests(unittest.TestCase): |
| |
| @classmethod |
| def setUpClass(cls) -> None: |
| cls.temp_dir = tempfile.mkdtemp() |
| lib_path = apex.extract_data(apex.LIBSEPOLWRAP, cls.temp_dir) |
| policy_path = apex.extract_data('precompiled_sepolicy', cls.temp_dir) |
| cls.pol = policy.Policy(policy_path, None, lib_path) |
| |
| @classmethod |
| def tearDownClass(cls) -> None: |
| shutil.rmtree(cls.temp_dir) |
| |
| # helpers |
| |
| @property |
| def pol(self): |
| return self.__class__.pol |
| |
| def assert_ok(self, line: str): |
| errors = apex.check_line(self.pol, line, apex.all_rules) |
| self.assertEqual(errors, [], "Should be no errors") |
| |
| def assert_error(self, line: str, expected_error: str): |
| pattern = re.compile(expected_error) |
| errors = apex.check_line(self.pol, line, apex.all_rules) |
| for err in errors: |
| if re.search(pattern, err): |
| return |
| self.fail(f"Expected error '{expected_error}' is not found in {errors}") |
| |
| # tests |
| |
| def test_parse_lines(self): |
| self.assert_ok('# commented line') |
| self.assert_ok('') # empty line |
| self.assert_error('./path1 invalid_contexts', |
| r'Error: invalid file_contexts: .*') |
| self.assert_error('./path1 u:object_r:vendor_file', |
| r'Error: invalid file_contexts: .*') |
| self.assert_ok('./path1 u:object_r:vendor_file:s0') |
| |
| def test_vintf(self): |
| self.assert_ok('./etc/vintf/fragment.xml u:object_r:vendor_configs_file:s0') |
| self.assert_error('./etc/vintf/fragment.xml u:object_r:vendor_file:s0', |
| r'Error: \./etc/vintf/fragment\.xml: .* can\'t read') |
| |
| def test_permissions(self): |
| self.assert_ok('./etc/permissions/permisssion.xml u:object_r:vendor_configs_file:s0') |
| self.assert_error('./etc/permissions/permisssion.xml u:object_r:vendor_file:s0', |
| r'Error: \./etc/permissions/permisssion.xml: .* can\'t read') |
| |
| def test_initscripts(self): |
| # here, netd_service is chosen randomly for invalid label for a file |
| |
| # init reads .rc file |
| self.assert_ok('./etc/init.rc u:object_r:vendor_file:s0') |
| self.assert_error('./etc/init.rc u:object_r:netd_service:s0', |
| r'Error: .* can\'t read') |
| # init reads .#rc file |
| self.assert_ok('./etc/init.32rc u:object_r:vendor_file:s0') |
| self.assert_error('./etc/init.32rc u:object_r:netd_service:s0', |
| r'Error: .* can\'t read') |
| # init skips file with unknown extension => no errors |
| self.assert_ok('./etc/init.x32rc u:object_r:vendor_file:s0') |
| self.assert_ok('./etc/init.x32rc u:object_r:netd_service:s0') |
| |
| def test_linkerconfig(self): |
| self.assert_ok('./etc/linker.config.pb u:object_r:system_file:s0') |
| self.assert_ok('./etc/linker.config.pb u:object_r:linkerconfig_file:s0') |
| self.assert_error('./etc/linker.config.pb u:object_r:vendor_file:s0', |
| r'Error: .*linkerconfig.* can\'t read') |
| self.assert_error('./ u:object_r:apex_data_file:s0', |
| r'Error: .*linkerconfig.* can\'t search') |
| |
| def test_unknown_label(self): |
| self.assert_error('./bin/hw/foo u:object_r:foo_exec:s0', |
| r'Error: \./bin/hw/foo: tcontext\(foo_exec\) is unknown') |
| |
| if __name__ == '__main__': |
| unittest.main(verbosity=2) |