1#!/usr/bin/env python3 2 3# Copyright 2021 The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17import argparse 18import re 19import sys 20 21# A line should look like: 22# {prop_name} u:object_r:{context_name}:s0 23line_regex = re.compile(r'^(\S+)\s+u:object_r:([^:]+):s0.*$') 24 25# Parses a line in property_contexts and return a (prop, ctx) tuple. 26# Raises an error for any malformed entries. 27def parse_line(line): 28 matched = line_regex.match(line) 29 if not matched: 30 raise ValueError('malformed entry "' + line + '" in property_contexts') 31 32 return matched.group(1, 2) 33 34def parse_args(): 35 parser = argparse.ArgumentParser( 36 description="Finds any violations in property_contexts, with given allowed prefixes. " 37 "If any violations are found, return a nonzero (failure) exit code.") 38 parser.add_argument("--property-contexts", help="Path to property_contexts file.") 39 parser.add_argument("--allowed-property-prefix", action="extend", nargs="*", 40 help="Allowed property prefixes. If empty, any properties are allowed.") 41 parser.add_argument("--allowed-context-prefix", action="extend", nargs="*", 42 help="Allowed context prefixes. If empty, any contexts are allowed.") 43 parser.add_argument('--strict', action='store_true', 44 help="Make the script fail if any violations are found.") 45 46 return parser.parse_args() 47 48args = parse_args() 49 50violations = [] 51 52with open(args.property_contexts, 'r') as f: 53 lines = f.read().split('\n') 54 55for line in lines: 56 tokens = line.strip() 57 # if this line empty or a comment, skip 58 if tokens == '' or tokens[0] == '#': 59 continue 60 61 prop, context = parse_line(line) 62 63 violated = False 64 65 if args.allowed_property_prefix and not prop.startswith(tuple(args.allowed_property_prefix)): 66 violated = True 67 68 if args.allowed_context_prefix and not context.startswith(tuple(args.allowed_context_prefix)): 69 violated = True 70 71 if violated: 72 violations.append(line) 73 74if len(violations) > 0: 75 print('******************************') 76 print('%d violations found:' % len(violations)) 77 print('\n'.join(violations)) 78 print('******************************') 79 print('%s contains properties which are not properly namespaced.' % args.property_contexts) 80 print('This is enforced by VTS, so please fix such offending properties.') 81 if args.allowed_property_prefix: 82 print('Allowed property prefixes for %s: %s' % (args.property_contexts, args.allowed_property_prefix)) 83 if args.allowed_context_prefix: 84 print('Allowed context prefixes for %s: %s' % (args.property_contexts, args.allowed_context_prefix)) 85 if args.strict: 86 print('You can temporarily disable this check with setting BUILD_BROKEN_VENDOR_PROPERTY_NAMESPACE := true in BoardConfig.mk.') 87 print('But property namespace is enforced by VTS, and you will need to fix such violations to pass VTS.') 88 print('See test/vts-testcase/security/system_property/vts_treble_sys_prop_test.py for the detail of the VTS.') 89 sys.exit(1) 90