Merge "APEX file_context should have valid labels" into main am: 84b9b076ab

Original change: https://android-review.googlesource.com/c/platform/system/sepolicy/+/2745099

Change-Id: If8170d47783132e432e34b41e5f84afc42611777
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Jooyung Han 2023-09-11 22:59:01 +00:00 committed by Automerger Merge Worker
commit 0cde24b1d4
2 changed files with 38 additions and 9 deletions

View file

@ -65,7 +65,13 @@ class AllowRead:
scontext: set[str]
Rule = AllowRead
@dataclass
class ResolveType:
"""Rule checking if type can be resolved"""
pass
Rule = AllowRead | ResolveType
def match_path(path: str, matcher: Matcher) -> bool:
@ -94,10 +100,18 @@ def check_rule(pol, path: str, tcontext: str, rule: Rule) -> List[str]:
continue # no errors
errors.append(f"Error: {path}: {s} can't read. (tcontext={tcontext})")
case ResolveType():
if tcontext not in pol.GetAllTypes(False):
errors.append(f"Error: {path}: tcontext({tcontext}) is unknown")
return errors
rules = [
target_specific_rules = [
(Glob('*'), ResolveType()),
]
generic_rules = [
# permissions
(Is('./etc/permissions/'), AllowRead('dir', {'system_server'})),
(Glob('./etc/permissions/*.xml'), AllowRead('file', {'system_server'})),
@ -114,7 +128,10 @@ rules = [
]
def check_line(pol: policy.Policy, line: str) -> List[str]:
all_rules = target_specific_rules + generic_rules
def check_line(pol: policy.Policy, line: str, rules) -> List[str]:
"""Parses a file_contexts line and runs checks"""
# skip empty/comment line
line = line.strip()
@ -151,6 +168,7 @@ def extract_data(name, temp_dir):
def do_main(work_dir):
"""Do testing"""
parser = argparse.ArgumentParser()
parser.add_argument('--all', action='store_true', help='tests ALL aspects')
parser.add_argument('-f', '--file_contexts', help='output of "deapexer list -Z"')
args = parser.parse_args()
@ -158,10 +176,15 @@ def do_main(work_dir):
policy_path = extract_data('precompiled_sepolicy', work_dir)
pol = policy.Policy(policy_path, None, lib_path)
if args.all:
rules = all_rules
else:
rules = generic_rules
errors = []
with open(args.file_contexts, 'rt', encoding='utf-8') as file_contexts:
for line in file_contexts:
errors.extend(check_line(pol, line))
errors.extend(check_line(pol, line, rules))
if len(errors) > 0:
sys.exit('\n'.join(errors))

View file

@ -43,12 +43,12 @@ class ApexSepolicyTests(unittest.TestCase):
return self.__class__.pol
def assert_ok(self, line: str):
errors = apex.check_line(self.pol, line)
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)
errors = apex.check_line(self.pol, line, apex.all_rules)
for err in errors:
if re.search(pattern, err):
return
@ -76,17 +76,19 @@ class ApexSepolicyTests(unittest.TestCase):
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:unknown: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:unknown: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:unknown: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')
@ -96,5 +98,9 @@ class ApexSepolicyTests(unittest.TestCase):
self.assert_error('./ u:object_r:apex_data_file:s0',
r'Error: .*linkerconfig.* can\'t read')
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)