• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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