Check if ./bin entries are not vendor_file

This can detect a common mistake of not labeling binaries in APEX.

Note - we can't simply check if the lable has exec_type attribute
because there're many exceptions.

Bug: 324005965
Test: atest apex_sepolicy_tests_test
Change-Id: Ib643e8b73fac1a3b8851804e58e69b19d32b997d
This commit is contained in:
Jooyung Han 2024-02-07 15:41:25 +09:00
parent 49a519234b
commit c945a104c0
2 changed files with 30 additions and 2 deletions

View file

@ -56,7 +56,16 @@ class Regex:
pattern: str
Matcher = Is | Glob | Regex
@dataclass
class BinaryFile:
pass
Matcher = Is | Glob | Regex | BinaryFile
# predicate functions for Func matcher
@dataclass
class AllowPerm:
@ -72,7 +81,13 @@ class ResolveType:
pass
Rule = AllowPerm | ResolveType
@dataclass
class NotAnyOf:
"""Rule checking if entity is not labelled as any of the given labels"""
labels: set[str]
Rule = AllowPerm | ResolveType | NotAnyOf
# Helper for 'read'
@ -89,6 +104,8 @@ def match_path(path: str, matcher: Matcher) -> bool:
return pathlib.PurePath(path).match(pattern)
case Regex(pattern):
return re.match(pattern, path)
case BinaryFile:
return path.startswith('./bin/') and not path.endswith('/')
def check_rule(pol, path: str, tcontext: str, rule: Rule) -> List[str]:
@ -109,6 +126,9 @@ def check_rule(pol, path: str, tcontext: str, rule: Rule) -> List[str]:
case ResolveType():
if tcontext not in pol.GetAllTypes(False):
errors.append(f"Error: {path}: tcontext({tcontext}) is unknown")
case NotAnyOf(labels):
if tcontext in labels:
errors.append(f"Error: {path}: can't be labelled as '{tcontext}'")
return errors
@ -118,6 +138,8 @@ target_specific_rules = [
generic_rules = [
# binaries should be executable
(BinaryFile, NotAnyOf({'vendor_file'})),
# permissions
(Is('./etc/permissions/'), AllowRead('dir', {'system_server'})),
(Glob('./etc/permissions/*.xml'), AllowRead('file', {'system_server'})),

View file

@ -102,5 +102,11 @@ class ApexSepolicyTests(unittest.TestCase):
self.assert_error('./bin/hw/foo u:object_r:foo_exec:s0',
r'Error: \./bin/hw/foo: tcontext\(foo_exec\) is unknown')
def test_binaries(self):
self.assert_ok('./bin/init u:object_r:init_exec:s0')
self.assert_ok('./bin/hw/svc u:object_r:init_exec:s0')
self.assert_error('./bin/hw/svc u:object_r:vendor_file:s0',
r"Error: .*svc: can\'t be labelled as \'vendor_file\'")
if __name__ == '__main__':
unittest.main(verbosity=2)