1#!/usr/bin/env python 2# coding: utf-8 3 4""" 5Copyright (c) 2021-2022 Huawei Device Co., Ltd. 6Licensed under the Apache License, Version 2.0 (the "License"); 7you may not use this file except in compliance with the License. 8You may obtain a copy of the License at 9 10 http://www.apache.org/licenses/LICENSE-2.0 11 12Unless required by applicable law or agreed to in writing, software 13distributed under the License is distributed on an "AS IS" BASIS, 14WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15See the License for the specific language governing permissions and 16limitations under the License. 17 18""" 19 20import os 21import argparse 22import subprocess 23 24# list of all macros and te for sepolicy build 25SEPOLICY_TYPE_LIST = ["security_classes", 26 "initial_sids", 27 "access_vectors", 28 "glb_perm_def.spt", 29 "glb_never_def.spt", 30 "mls", 31 "policy_cap", 32 "glb_te_def.spt", 33 "attributes", 34 ".te", 35 "glb_roles.spt", 36 "users", 37 "initial_sid_contexts", 38 "fs_use", 39 "virtfs_contexts", 40 ] 41 42 43def parse_args(): 44 parser = argparse.ArgumentParser() 45 parser.add_argument( 46 '--dst-file', help='the policy dest path', required=True) 47 parser.add_argument('--tool-path', 48 help='the policy tool bin path', required=True) 49 parser.add_argument('--source-root-dir', 50 help='prj root path', required=True) 51 parser.add_argument('--policy_dir_list', 52 help='policy dirs need to be included', required=True) 53 parser.add_argument('--debug-version', 54 help='build for debug target', required=True) 55 parser.add_argument('--updater-version', 56 help='build for updater target', required=True) 57 return parser.parse_args() 58 59 60def traverse_folder_in_dir_name(search_dir, folder_suffix): 61 folder_list = [] 62 for root, dirs, _ in os.walk(search_dir): 63 for dir_i in dirs: 64 if dir_i == folder_suffix: 65 folder_list.append(os.path.join(root, dir_i)) 66 return folder_list 67 68 69def traverse_folder_in_type(search_dir, file_suffix): 70 policy_file_list = [] 71 for root, _, files in os.walk(search_dir): 72 for each_file in files: 73 if each_file.endswith(file_suffix): 74 policy_file_list.append(os.path.join(root, each_file)) 75 policy_file_list.sort() 76 return " ".join(str(x) for x in policy_file_list) 77 78 79def traverse_file_in_each_type(folder_list, sepolicy_type_list): 80 policy_files = "" 81 for policy_type in sepolicy_type_list: 82 for folder in folder_list: 83 str_seq = (policy_files, traverse_folder_in_type(folder, policy_type)) 84 policy_files = " ".join(str_seq) 85 return policy_files 86 87 88def run_command(in_cmd): 89 cmdstr = " ".join(in_cmd) 90 ret = subprocess.run(cmdstr, shell=True).returncode 91 if ret != 0: 92 raise Exception(ret) 93 94 95def build_conf(args, output_conf, input_policy_file_list): 96 m4_args = "-D build_with_debug=" + args.debug_version + " " 97 m4_args += "-D build_with_updater=" + args.updater_version + " " 98 99 build_conf_cmd = ["m4", 100 "--fatal-warnings", m4_args, 101 "-s", input_policy_file_list, ">", output_conf] 102 103 run_command(build_conf_cmd) 104 105 106def build_cil(args, output_cil, input_conf): 107 check_policy_cmd = [os.path.join(args.tool_path, "checkpolicy"), 108 input_conf, 109 "-M -C -c 31", 110 "-o " + output_cil] 111 run_command(check_policy_cmd) 112 113 114def build_policy(args, output_policy, input_cil): 115 build_policy_cmd = [os.path.join(args.tool_path, "secilc"), 116 input_cil, 117 "-m -M true -G -c 31", 118 "-f /dev/null", 119 "-o " + output_policy] 120 run_command(build_policy_cmd) 121 122 123def prepare_build_path(dir_list, root_dir, build_dir_list): 124 125 build_policy_list = ["base/security/selinux/sepolicy/base", "base/security/selinux/sepolicy/ohos_policy"] 126 build_policy_list += dir_list.split(":") 127 128 for i in build_policy_list: 129 if i == "" or i == "default": 130 continue 131 path = os.path.join(root_dir, i) 132 if (os.path.exists(path)): 133 build_dir_list.append(path) 134 else: 135 print("following path not exists!! {}".format(path)) 136 exit(-1) 137 138 139def main(args): 140 output_path = os.path.abspath(os.path.dirname(args.dst_file)) 141 dir_list = [] 142 prepare_build_path(args.policy_dir_list, args.source_root_dir, dir_list) 143 144 system_policy = [] 145 public_policy = [] 146 vendor_policy = [] 147 148 for item in dir_list: 149 public_policy += traverse_folder_in_dir_name(item, "public") 150 system_policy += traverse_folder_in_dir_name(item, "system") 151 vendor_policy += traverse_folder_in_dir_name(item, "vendor") 152 153 # list of all policy folders 154 folder_list = public_policy + system_policy + vendor_policy 155 # add temp dirs base/te folders 156 folder_list.append(os.path.join(args.source_root_dir, "base/security/selinux/sepolicy/base/te")) 157 158 # list of all policy files 159 policy_file_list = traverse_file_in_each_type( 160 folder_list, SEPOLICY_TYPE_LIST) 161 162 # build ohos.conf 163 output_ohos_conf = os.path.join(output_path, "ohos.conf") 164 build_conf(args, output_ohos_conf, policy_file_list) 165 166 # build ohos.cil 167 ohos_cil_path = os.path.join(output_path, "ohos.cil") 168 build_cil(args, ohos_cil_path, output_ohos_conf) 169 170 build_policy(args, args.dst_file, ohos_cil_path) 171 172 173if __name__ == "__main__": 174 input_args = parse_args() 175 main(input_args) 176