apex_sepolicy_tests: check system/vendor attr
APEX file_contexts are checked against Treble boundary. Eg. vendor apex
can't use system types.
Bug: 387192232
Test: apex_sepolicy_tests -f fc -p vendor
fails if fc contains system types.
Change-Id: I3773daa8acc4d38a9df869e0d0017f84ce9055da
diff --git a/tests/apex_sepolicy_tests.py b/tests/apex_sepolicy_tests.py
index 26082cb..d8c5c2b 100644
--- a/tests/apex_sepolicy_tests.py
+++ b/tests/apex_sepolicy_tests.py
@@ -29,7 +29,7 @@
import sys
import tempfile
from dataclasses import dataclass
-from typing import List
+from typing import Callable, List
import policy
@@ -61,7 +61,12 @@
pass
-Matcher = Is | Glob | Regex | BinaryFile
+@dataclass
+class MatchPred:
+ pred: Callable[[str], bool]
+
+
+Matcher = Is | Glob | Regex | BinaryFile | MatchPred
# predicate functions for Func matcher
@@ -87,7 +92,13 @@
labels: set[str]
-Rule = AllowPerm | ResolveType | NotAnyOf
+@dataclass
+class HasAttr:
+ """Rule checking if the context has the specified attribute"""
+ attr: str
+
+
+Rule = AllowPerm | ResolveType | NotAnyOf | HasAttr
# Helper for 'read'
@@ -104,8 +115,10 @@
return pathlib.PurePath(path).match(pattern)
case Regex(pattern):
return re.match(pattern, path)
- case BinaryFile:
+ case BinaryFile():
return path.startswith('./bin/') and not path.endswith('/')
+ case MatchPred(pred):
+ return pred(path)
def check_rule(pol, path: str, tcontext: str, rule: Rule) -> List[str]:
@@ -129,6 +142,9 @@
case NotAnyOf(labels):
if tcontext in labels:
errors.append(f"Error: {path}: can't be labelled as '{tcontext}'")
+ case HasAttr(attr):
+ if tcontext not in pol.QueryTypeAttribute(attr, True):
+ errors.append(f"Error: {path}: tcontext({tcontext}) must be associated with {attr}")
return errors
@@ -139,7 +155,7 @@
generic_rules = [
# binaries should be executable
- (BinaryFile, NotAnyOf({'vendor_file'})),
+ (BinaryFile(), NotAnyOf({'vendor_file'})),
# permissions
(Is('./etc/permissions/'), AllowRead('dir', {'system_server'})),
(Glob('./etc/permissions/*.xml'), AllowRead('file', {'system_server'})),
@@ -159,6 +175,25 @@
all_rules = target_specific_rules + generic_rules
+def base_attr_for(partition):
+ if partition in ['system', 'system_ext', 'product']:
+ return 'system_file_type'
+ elif partition in ['vendor', 'odm']:
+ return 'vendor_file_type'
+ else:
+ sys.exit(f"Error: invalid partition: {partition}\n")
+
+
+def system_vendor_rule(partition):
+ exceptions = [
+ "./etc/linkerconfig.pb"
+ ]
+ def pred(path):
+ return path not in exceptions
+
+ return pred, HasAttr(base_attr_for(partition))
+
+
def check_line(pol: policy.Policy, line: str, rules) -> List[str]:
"""Parses a file_contexts line and runs checks"""
# skip empty/comment line
@@ -197,7 +232,8 @@
"""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"')
+ parser.add_argument('-f', '--file_contexts', required=True, help='output of "deapexer list -Z"')
+ parser.add_argument('-p', '--partition', help='partition to check Treble violations')
args = parser.parse_args()
lib_path = extract_data(LIBSEPOLWRAP, work_dir)
@@ -209,6 +245,9 @@
else:
rules = generic_rules
+ if args.partition:
+ rules.append(system_vendor_rule(args.partition))
+
errors = []
with open(args.file_contexts, 'rt', encoding='utf-8') as file_contexts:
for line in file_contexts:
diff --git a/tests/apex_sepolicy_tests_test.py b/tests/apex_sepolicy_tests_test.py
index 727a023..2a92aee 100644
--- a/tests/apex_sepolicy_tests_test.py
+++ b/tests/apex_sepolicy_tests_test.py
@@ -106,7 +106,7 @@
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\'")
+ r'Error: .*svc: can\'t be labelled as \'vendor_file\'')
if __name__ == '__main__':
unittest.main(verbosity=2)