1# Copyright (c) 2022 Huawei Device Co., Ltd.
2# Licensed under the Apache License, Version 2.0 (the "License");
3# you may not use this file except in compliance with the License.
4# You may obtain a copy of the License at
5#
6#     http://www.apache.org/licenses/LICENSE-2.0
7#
8# Unless required by applicable law or agreed to in writing, software
9# distributed under the License is distributed on an "AS IS" BASIS,
10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11# See the License for the specific language governing permissions and
12# limitations under the License.
13
14import("//build/config/python.gni")
15import("//build/ohos.gni")
16
17template("ohos_prebuilt_seccomp") {
18  if (!build_seccomp) {
19    group(target_name) {
20      not_needed(invoker, "*")
21    }
22  } else {
23    assert(defined(invoker.sources),
24           "source must be defined for ${target_name}.")
25    assert(defined(invoker.filtername),
26           "source must be defined for ${target_name}.")
27    assert(
28        defined(invoker.process_type) &&
29            (invoker.process_type == "app" || invoker.process_type == "system"),
30        "process_type must be defined for ${target_name}, and the type must be app or system")
31
32    _seccomp_filter_target = "gen_${target_name}"
33    _output_name = "${invoker.filtername}_filter"
34    _seccomp_filter_file = target_gen_dir + "/${_output_name}.c"
35    _syscall_to_nr_arm_name = "${target_name}_syscall_to_nr_arm"
36    _syscall_to_nr_arm64_name = "${target_name}_syscall_to_nr_arm64"
37    _syscall_to_nr_riscv64_name = "${target_name}_syscall_to_nr_riscv64"
38    _blocklist_file_name = "//base/startup/init/services/modules/seccomp/seccomp_policy/${invoker.process_type}.blocklist.seccomp.policy"
39    _key_process_file_name = "//base/startup/init/services/modules/seccomp/seccomp_policy/privileged_process.seccomp.policy"
40
41    action(_syscall_to_nr_arm_name) {
42      script = "${clang_base_path}/bin/clang"
43      output_dir =
44          target_gen_dir + "/${_seccomp_filter_target}/libsyscall_to_nr_arm"
45      args = [
46        "-I",
47        rebase_path(
48            "//kernel/linux/patches/${linux_kernel_version}/prebuilts/usr/include/asm-arm"),
49        "-I",
50        rebase_path(
51            "//kernel/linux/patches/${linux_kernel_version}/prebuilts/usr/include"),
52        "-dD",
53        "-E",
54        "-Wall",
55        "-nostdinc",
56        "-o",
57        rebase_path(output_dir),
58        rebase_path(
59            "//base/startup/init/services/modules/seccomp/gen_syscall_name_nrs.c"),
60      ]
61
62      outputs = [ output_dir ]
63    }
64
65    action(_syscall_to_nr_arm64_name) {
66      script = "${clang_base_path}/bin/clang"
67      output_dir =
68          target_gen_dir + "/${_seccomp_filter_target}/libsyscall_to_nr_arm64"
69      args = [
70        "-I",
71        rebase_path(
72            "//kernel/linux/patches/${linux_kernel_version}/prebuilts/usr/include/asm-arm64"),
73        "-I",
74        rebase_path(
75            "//kernel/linux/patches/${linux_kernel_version}/prebuilts/usr/include"),
76        "-dD",
77        "-E",
78        "-Wall",
79        "-nostdinc",
80        "-o",
81        rebase_path(output_dir),
82        rebase_path(
83            "//base/startup/init/services/modules/seccomp/gen_syscall_name_nrs.c"),
84      ]
85
86      outputs = [ output_dir ]
87    }
88    action(_syscall_to_nr_riscv64_name) {
89      script = "${clang_base_path}/bin/clang"
90      output_dir =
91          target_gen_dir + "/${_seccomp_filter_target}/libsyscall_to_nr_riscv64"
92      args = [
93        "-I",
94        rebase_path(
95            "//kernel/linux/patches/${linux_kernel_version}/prebuilts/usr/include/asm-riscv"),
96        "-I",
97        rebase_path(
98            "//kernel/linux/patches/${linux_kernel_version}/prebuilts/usr/include"),
99        "-dD",
100        "-E",
101        "-Wall",
102        "-nostdinc",
103        "-o",
104        rebase_path(output_dir),
105        rebase_path(
106            "//base/startup/init/services/modules/seccomp/gen_syscall_name_nrs.c"),
107      ]
108      outputs = [ output_dir ]
109    }
110    action(_seccomp_filter_target) {
111      script = "//base/startup/init/services/modules/seccomp/scripts/generate_code_from_policy.py"
112
113      sources = invoker.sources
114      sources += get_target_outputs(":${_syscall_to_nr_arm_name}")
115      sources += get_target_outputs(":${_syscall_to_nr_arm64_name}")
116      sources += get_target_outputs(":${_syscall_to_nr_riscv64_name}")
117      uid_is_root = false
118      if (defined(invoker.uid_is_root)) {
119        uid_is_root = invoker.uid_is_root
120      } else {
121        uid_is_root = false
122      }
123      if (invoker.process_type == "system" &&
124          invoker.filtername != "appspawn" &&
125          invoker.filtername != "nwebspawn" && uid_is_root == false) {
126        sources += [ "//base/startup/init/services/modules/seccomp/seccomp_policy/system_uid_filter.seccomp.policy" ]
127      }
128
129      deps = [
130        ":${_syscall_to_nr_arm64_name}",
131        ":${_syscall_to_nr_arm_name}",
132        ":${_syscall_to_nr_riscv64_name}",
133      ]
134
135      if (build_variant == "root") {
136        seccomp_is_debug = "true"
137      } else {
138        seccomp_is_debug = "false"
139      }
140
141      args = []
142      foreach(source, sources) {
143        args += [
144          "--src-files",
145          rebase_path(source),
146        ]
147      }
148      args += [
149        "--blocklist-file",
150        rebase_path(_blocklist_file_name),
151        "--dst-file",
152        rebase_path(_seccomp_filter_file),
153        "--filter-name",
154        invoker.filtername,
155        "--target-cpu",
156        invoker.target_cpu,
157        "--keyprocess-file",
158        rebase_path(_key_process_file_name),
159        "--is-debug",
160        seccomp_is_debug,
161      ]
162
163      outputs = [ _seccomp_filter_file ]
164    }
165
166    ohos_shared_library(target_name) {
167      output_name = _output_name
168      deps = [ ":${_seccomp_filter_target}" ]
169      sources = get_target_outputs(":${_seccomp_filter_target}")
170      sanitize = {
171        cfi = true
172        cfi_cross_dso = true
173        debug = false
174      }
175
176      relative_install_dir = "seccomp"
177
178      if (defined(invoker.include_dirs)) {
179        include_dirs = invoker.include_dirs
180      }
181
182      if (defined(invoker.install_enable)) {
183        install_enable = invoker.install_enable
184      }
185
186      if (defined(invoker.part_name)) {
187        part_name = invoker.part_name
188      }
189
190      if (defined(invoker.subsystem_name)) {
191        subsystem_name = invoker.subsystem_name
192      }
193
194      if (defined(invoker.install_images)) {
195        install_images = invoker.install_images
196      }
197    }
198  }
199}
200