• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Seccomp Policy Development
2## Overview
3### Introduction
4Secure computing mode (Seccomp) is a security mechanism provided by the Linux kernel. In the Linux system, a large number of system calls can be opened to user-mode programs without any restrictions. However, not all of these system calls are necessarily needed for user-mode programs. In this case, abuse of system calls can lead to system threats. For example, if a process has a security vulnerability, an attacker can run a shellcode segment to trigger system calls that are not triggered during normal execution, resulting in privilege escalation or private information leakage. To prevent such security risks, Seccomp limits the scope of system calls that can be used by programs, so as to reduce system exposure and improve security.
5
6### Operating Mechanism
71. Basic mechanism
8
9    Seccomp policies exist in the form of policy files. During compilation and building, a policy file is parsed to generate a source file that contains the BPF instruction policies, and then the source file is compiled into a dynamic policy library. During startup of a user-mode process, Seccomp system calls are invoked to load the BPF instruction policies into the kernel through the dynamic policy library.
10
112. Basic features
12    - A child process inherits the Seccomp policies of its parent process.
13    - After a Seccomp policy is loaded to the kernel during process running, the policy exists in the memory as a singly linked list and cannot be modified.
14    - Seccomp policies can be set for a process for multiple times. When a process executes a system call, the kernel traverses the policies specified for the nodes in the singly linked list, and then compares the policies to obtain the policy with the highest priority.
15
16
17### Constraints
18- System restrictions<br>The system used must be a standard system, and the options listed below must be enabled in the kernel. You can find the kernel option configuration file of the product in **//kernel/linux/config/{linux_version}/arch/{target_cpu}/configs/**.
19    ```shell
20    CONFIG_HAVE_ARCH_SECCOMP=y
21    CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
22    CONFIG_SECCOMP=y
23    CONFIG_SECCOMP_FILTER=y
24    ```
25
26- Feature restrictions
27    - The Seccomp policy for non-privileged processes complies with the baseline blocklist mechanism.
28    - If a process needs to use system calls in the baseline blocklist, the system calls must be declared in the privileged process policy file.
29    - The same Seccomp policy is enabled for all application processes.
30    - The same Seccomp policy is enabled for most of system service processes.
31    - Personalized Seccomp policies can be enabled for the native service processes incubated by the init process.
32
33## Enabling Seccomp
34### When to Use
35To meet product security requirements, you can enable Seccomp to limit the scope of system calls that can be invoked by processes. The development procedure below describes how to enable the basic functions and policies of Seccomp. Note that the basic functions must meet the feature restrictions described in [Constraints](#constraints). For details about the basic policy file, see [Policy File Overview](#policy-file-overview).
36### How to Develop
371. Add the following field to **vendor/Product vendor/Product name/config.json**:
38    ```c
39    "build_seccomp": true
40    ```
41    The following is an example of adding the **build_seccomp** field to the product configuration file:
42    ```c
43    {
44        "product_name": "MyProduct",
45        "version": "3.0",
46        "type": "standard",
47        "target_cpu": "arm",
48        "ohos_version": "OpenHarmony 1.0",
49        "device_company": "MyProductVendor",
50        "board": "MySOC",
51        "enable_ramdisk": true,
52        "build_seccomp": true
53        "subsystems": [
54        {
55            "subsystem": "ace",
56            "components": [
57            { "component": "ace_engine_lite","features":[""] }
58            ]
59        },
60        ...
61        ]
62    }
63    ```
642. Perform a full build on the product code to generate an image.
65    ```
66    ./build.sh --product-name *product name* --ccache --build-target make_all --target-cpu *specified CPU*
67    ```
683. Burn the image into the device.
69
70### Debugging and Verification
71Check whether Seccomp is enabled for application processes and system service processes.
721. Run the shell command to obtain the process ID (that is, **target pid**) of the target process.
73    ```
74    ps -ef | grep xxx
75    ```
76    Information similar to the following is displayed, in which **target pid** is **1686**:
77    ```
78    media         1686     1 0 08:16:12 ?     00:00:00 xxx
79    root          1869  1678 4 10:32:29 pts/0 00:00:00 grep xxx
80    ```
81
822. Check the process status to determine whether Seccomp is enabled.
83    ```shell
84    cat /proc/[target pid]/status | grep Seccomp
85    ```
86    Information similar to the following is displayed:
87    ```
88    Seccomp:        2
89    Seccomp_filters:        1
90    ```
91    **Table 1** Description of the Seccomp status
92    |  Parameter |  Description |
93    |  ---  |  ---  |
94    |  Seccomp  |  - **0**: disabled.<br>- **1**: enabled with the strict mode. Only the read, write, exit, and sigreturn system calls are allowed.<br>- **2**: enabled with the filter mode. The customized policies can be enabled by loading BPF instruction sets. |
95    |  Seccomp_filters  |  Number of Seccomp policies set for a process.|
96
97## Customizing Seccomp Policies for a Process
98### When to Use
99If the basic Seccomp policy has been enabled for a product, you can customize Seccomp policies for native service processes incubated by the init process to adapt to diversified security requirements. In this case, the Seccomp policies of other native service processes remain unchanged.
100### How to Develop
1011. Collect statistics on the system calls required by the 32-bit and 64-bit systems by using the static analysis and Strace statistics methods described in [System Call Statistic Methods](#system-call-statistic-methods). In this way, you will obtain the initial Seccomp policy.
1022. Write a policy file. For details, see [How to Write a Common Policy File](#how-to-write-a-common-policy-file).
1033. Write and build the **BUILD.gn** file.
104
105    1.  Store the policy file in the code repository of the service subsystem and create a **BUILD.gn** file. For example, create the **seccomp_policy** folder in the service code repository, and create the policy file and **BUILD.gn** file in the folder.
106
107        ```shell
108        //path/to/code/seccomp_policy
109        ├── BUILD.gn
110        └── example.seccomp.policy
111        ```
112    2. To parse the policy file and build the policy dynamic library, use the **ohos_prebuilt_seccomp** template to declare the Seccomp policy file path of the process in the **BUILD.gn** file. The **ohos_prebuilt_seccomp** template is defined in the **//base/startup/init/services/modules/seccomp/scripts/seccomp_policy_fixer.gni** file. The following table describes the parameters in the template.
113
114        **Table 2** Parameters in the ohos_prebuilt_seccomp template
115        |  Parameter |  Description |
116        |  ---  |  ---  |
117        |  sources  |  Path of the policy configuration file, mandatory.|
118        |  filtername  |  Filter name, mandatory. The value must be the same as the value of **Services name** in the [boot configuration file](subsys-boot-init-cfg.md) of the process. Otherwise, the attempt to enable Seccomp will fail. This parameter determines the name of the dynamic policy library generated after the build. For example, if **filtername** is set to **xxx**, the name of the dynamic policy library is **libxxx_filter.z.so**. |
119        |  process_type  |  Process type, mandatory. If the process is one incubated by the init process, set this parameter to **system**; if the process is an application process, set this parameter to **app**.|
120        |  part_name  |  Part name, mandatory. |
121        |  subsystem_name  |  Subsystem name, mandatory. |
122        |  install_enable  |  Option specifying whether to install the policy file to the image, mandatory. Set the value to **true**. |
123        |  install_images  |  Installation location in the image, mandatory. |
124
125        Example
126        ```python
127        #Import the template file.
128        import("//base/startup/init/services/modules/seccomp/scripts/seccomp_policy_fixer.gni")
129
130        #Use the ohos_prebuilt_seccomp template.
131        ohos_prebuilt_seccomp("xxxx_seccomp_filter") {
132            sources = [ "xxxx.seccomp.policy" ]
133
134            filtername = "xxx"
135
136            process_type = "system"
137
138            part_name = "xx_part_name"
139            subsystem_name = "x_subsystem_name"
140
141            install_enable = true
142            install_images = [ "xxxxx" ]
143        }
144        ```
145    3. Add the build target of **xxxx_seccomp_filter** to other **BUILD.gn** files.
146        ```python
147        if (build_seccomp) {
148            deps += [ "path:xxxx_seccomp_filter" ]
149        }
150        ```
1514. Build the dynamic policy library **libxxx_filter.z.so**.
152    ```shell
153    ./build.sh --product-name *product name* --ccache --build-target xxxx_seccomp_filter --target-cpu *specified CPU*
154    ```
155    If an error message that contains the following information is reported, the process needs to use the system calls in the baseline blocklist. In such a case, you need to declare the corresponding system call in **privileged_process.seccomp.policy**. For details, see [How to Write a Privileged Process Policy File](#how-to-write-a-privileged-process-policy-file). After the declaration is done, try again until the build is successful.
156    ```shell
157    xx of allow list is in block list
158    ```
1595. Use the hdc tool to push the dynamic policy library to the device and restart the device.
160    ```shell
161    # Push an appropriate library path based on the installation location in the image. For example, if the image is **system** and the system architecture is 32-bit, the path of the dynamic policy library is **/system/lib/seccomp/**.
162    hdc shell mount -rw -o remount /
163    hdc file send /path/to/libxxx_filter.z.so /path/to/lib(or lib64)/seccomp/
164    hdc shell reboot
165    ```
1666. Use the [audit statistics](#audit-statistics) method to check and supplement the Seccomp policies. Repeat steps 4 to 6 until the process can run properly.
167
168### Debugging and Verification
1691. If Seccomp is not enabled for the target process, [check the Seccomp status](#debugging-and-verification) of the target process.
1702. If the process is terminated and audit log information is present in the kernel logs, the Seccomp policy is enabled but the policy list is incomplete. You can find an example audit log in [Audit Statistics](#audit-statistics).
1713. If the process is not terminated, comment out the system calls (for example, **setuid**) related to the specified uid in the Seccomp policy file. Rebuild the dynamic policy library, push the library to the image, and restart the process. Then, check whether the process is terminated by Seccomp. If the process is terminated, Seccomp has been enabled.
172
173## FAQs
174### How do I determine whether a process termination is caused by Seccomp?
175**Symptom**
176
177If a process is terminated under certain conditions, how do I determine whether the issue is caused by Seccomp?
178
179**Solution**
180
181Use either of the following methods:
182
183- Check the crash stack backtrace log of the process. If the signal in the log is **SIGSYS**, the process termination is caused by the Seccomp mechanism. To view the crash stack backtrace content, run the following shell command:
184    ```shell
185    cat /data/log/faultlog/faultlogger/crash stack backtrace log
186    ```
187    Example output:
188    ```shell
189    Generated by HiviewDFX@OpenHarmony
190    ================================================================
191    Device info:xxx
192    Build info:xxx
193    Module name:xxx
194    Pid:xxxx
195    Uid:xxxxx
196    Reason:Signal:SIGSYS(UNKNOWN)
197    ...
198    ```
199- Check whether the process is still terminated after Seccomp is disabled. If the process runs properly after Seccomp is disabled, the process termination is caused by Seccomp.
200
201    Seccomp is enabled by default. When the device operation mode is set to **root**, you can run the shell command to set the corresponding system parameter to disable Seccomp of the entire system.
202    ```shell
203    # Set the system parameter to disable Seccomp and restart the process.
204    param set persist.init.debug.seccomp.enable 0; reboot
205    # Set the system parameter to enable Seccomp and restart the process.
206    param set persist.init.debug.seccomp.enable 1; reboot
207    ```
208
209## Reference
210### Seccomp source code directory
211```
212base/startup/init/services/modules/seccomp
213├── BUILD.gn
214├── gen_syscall_name_nrs.c
215├── scripts
216│   ├── generate_code_from_policy.py        # Policy file parsing script
217│   ├── seccomp_policy_fixer.gni            # Template definition in the BUILD.gn file for generating the dynamic policy library
218│   └── tools                               # Scripts for collecting system call statistics
219├── seccomp_policy                          # Basic policy files
220│   ├── app.blocklist.seccomp.policy
221│   ├── app.seccomp.policy
222│   ├── privileged_process.seccomp.policy
223│   ├── renderer.seccomp.policy
224│   ├── spawn.seccomp.policy
225│   ├── system.blocklist.seccomp.policy
226│   └── system.seccomp.policy
227├── seccomp_policy.c                        # Core Seccomp implementation code
228└── seccomp_policy_static.c                 # Seccomp plug-in code
229```
230
231### Policy File Overview
232- Location<br>Basic policy files are stored in **//base/startup/init/services/modules/seccomp/seccomp_policy**.
233- Basic policy files
234
235    **Table 3** Description of policy files
236    |  Policy File |  Description |
237    |  ---  |  ---  |
238    |  system.seccomp.policy  | Seccomp policy enabled for most of system service processes.|
239    |  system.blocklist.seccomp.policy  | System call baseline blocklist for system processes, that is, the list of system calls that cannot be invoked by non-privileged processes.|
240    |  app.seccomp.policy  | Seccomp policy enabled for all application processes.|
241    |  app.blocklist.seccomp.policy  | System call baseline blocklist for application processes, that is, the list of system calls that cannot be invoked by application processes.|
242    |  spawn.seccomp.policy  | Seccomp policy enabled for the appspawn and nwebspawn processes.|
243    |  renderer.seccomp.policy  | Seccomp policy enabled for the rendering processes incubated by the nwebspawn process.|
244    |  privileged_process.seccomp.policy  | Privileged process policy file. If certain processes need to use the system calls on the baseline blocklist, you need to declare the corresponding process identifiers and baseline blocklists in this file.|
245
246### How to Write a Common Policy File
247- To declare a configuration item, write **@** followed by the configuration item, for example, **@returnValue**.
248- Add the content of a configuration item from the next line of this configuration item to the beginning of the next configuration item.
249- To comment out a line, add a pound sign (#) at the beginning of this line.
250- Set the system architecture to **arm** or **arm64**. Only these two system architectures are supported currently.
251- Separate system calls from the system architecture by a semicolon (;). The value **all** indicates that the system calls will be used by all supported system architectures.
252- Set other parameters as needed. Except **returnValue**, all the other parameters are optional.
253
254**Table 4** Configuration items in the policy file
255
256|  Item |  Description | Configuration Rule |
257|  ---  |  ---  |  --  |
258|  returnValue  |  Return value. |  This parameter is mandatory. Value range:<br>- **LOG**: tolerant mode, in which only audit logs are recorded and the process is not terminated.<br>- **TRAP**: a mode in which the process is terminated and can be passed on to the faultloggerd process.<br>- **KILL_PROCESS**: a mode in which the process is terminated.<br>- **KILL_THREAD**: a mode in which the thread is terminated. |
259|  headFiles  |  Header file, which is used to declare the macros in the **allowListWithArgs** and **priorityWithArgs** parameters.|  Use **""** and **<>** to include the file name, for example, **<abc.h>** and **"cde.h"**. The default header files are **<linux/filter.h>**, **<stddef.h>**, **<linux/seccomp.h>**, and **<audit.h>**. |
260|  priority  |  Allowlist of frequently used system calls. |  System calls on the list are treated with a higher priority to improve the performance. |
261|  priorityWithArgs  |  Allowlist of frequently used system calls with arguments. |  System calls on the list are treated with a higher priority to improve the performance. |
262|  allowList  |  Allowlist |  List of system calls that can be invoked by a process. |
263|  allowListWithArgs  |  List of system calls with arguments that can be invoked by a process. |  Separate the system call name and argument by a colon (:). Supported relational operators include **<**, **<=**, **>**, **>=**, **==**, **!=**, and **&**, and supported logical operators include **&&** and \.|\|.<br>Use **arg***n* to specify the SN of the argument in the system. The value of **n** ranges from **0** to **5**. A judgment statement starts with **if** and ends with **else**. Declare the return value after the statement ends, and use a semicolon (;) to separate the judgment statement from the return value.<br>The return value must be in the format of **return xxx**, where the value range of **xxx** is the same as that of **returnValue**. If there are multiple conditions in the judgment statement, separate them with **elif**.|
264|  blockList  |  Blocklist of system calls. |  Before generating BPF instructions during policy file parsing, the system checks whether the system calls on the allowlist exist in the blocklist. If yes, a parsing error occurs.|
265|  selfDefineSyscall  |  Customized system call. |  Set the value of this parameter to a number. |
266
267Example: example.seccomp.policy
268
269```
270@returnValue
271TRAP
272
273@headFiles
274"time.h"
275
276@priority
277ioctl;all
278
279@allowList
280openat;all
281close;all
282lseek;all
283read;all
284write;all
285setresuid;arm64
286setresgid;arm64
287setresuid32;arm
288setresgid32;arm
289
290@allowListWithArgs
291clock_getres:if arg0 >= CLOCK_REALTIME && arg0 <= CLOCK_BOOTTIME; return ALLOW; else return TRAP;all
292
293@blockList
294swapon;all
295
296@selfDefineSyscall
297787
298```
299
300### How to Write a Privileged Process Policy File
301- To declare a configuration item, write **@** followed by the configuration item, for example, **@allowBlockList**.
302- Add the content of a configuration item from the next line of this configuration item to the beginning of the next configuration item.
303- To comment out a line, add a pound sign (#) at the beginning of this line.
304- Set the system architecture to **arm** or **arm64**. Only these two system architectures are supported currently.
305- Separate system calls from the system architecture by a semicolon (;). The value **all** indicates that the system calls will be used by all supported system architectures.
306
307**Table 5** Configuration items in the privileged process policy file
308|  Item |  Description | Configuration Rule |
309|  ---  |  ---  |  --  |
310|  privilegedProcessName  |  Process name identifier. |  Character string corresponding to **name** in the **services** parameter in the boot file of the native service process.|
311|  allowBlockList  |  Available baseline blocklist. |  Fill in the system call and the system architecture.|
312
313The following example shows how to enable process1 and process2 to use the swapon system call in the baseline blocklist.
314```
315@privilegedProcessName
316process1
317
318@allowBlockList
319swapon;all
320
321@privilegedProcessName
322process2
323
324@allowBlockList
325swapon;all
326```
327
328### System Call Statistic Methods
329**Table 6** Comparison of statistic methods
330|  Statistic Method |  Description |  Advantage |  Disadvantage |
331|  ---  |  ---  |  ---  |  ---  |
332|  <div style="width: 50pt">Static analysis | <div style="width: 300pt">Analyze the ELF disassembly code to obtain the call relationship, collect statistics on the APIs that call the libc library, and then parse the LibC library to obtain the call relationship between the LibC APIs and the system call numbers. In this way, you will obtain the system call numbers used by the ELF file.|  <div style="width: 100pt">Statistics collection is supported for system calls in abnormal branches. |  <div style="width: 100pt">Parsing of call relationship is not supported for pointer functions. |
333|  Strace statistics | Use Strace to trace service processes when the device is running. During the trace, the invoked system calls are recorded into logs. Collect the logs after the trace is complete, and use a script to parse the logs and generate a Seccomp policy file.|  Easy to use. |  System calls can be completely collected only when all code branches are traversed. |
334|  Audit statistics | After the Seccomp policy is enabled for a process, Seccomp intercepts invalid system calls and records audit log information containing the system call numbers into kernel logs. Collect the logs after the trace is complete, and use a script to parse the logs and generate a Seccomp policy file.|  This method can be used as a supplement to the preceding methods. |  Logs may be lost.<br>System calls can be completely collected only when all code branches are traversed. |
335
336#### Static Analysis
3371. Prepare for the environment.
338    1. Prepare a Linux environment.
339    2. Download the cross compilers arm-linux-musleabi and aarch64-linux-musl.
340        ```shell
341        wget https://musl.cc/arm-linux-musleabi-cross.tgz
342        wget https://musl.cc/aarch64-linux-musl-cross.tgz
343
344        tar -zxvf arm-linux-musleabi-cross.tgz
345        tar -zxvf aarch64-linux-musl-cross.tgz
346
347        # Add the tool execution path to the environment variable.
348        export PATH=$PATH:/path/to/arm-linux-musleabi-cross/bin
349        export PATH=$PATH:/path/to/aarch64-linux-musl-cross/bin
350        ```
351
352    3. Download the OpenHarmony source code. For details, see [Obtaining Source Code](../get-code/sourcecode-acquire.md).
353
3542. Compile **seccomp_filter** to obtain the dependency files **libsyscall_to_nr_arm** and **libsyscall_to_nr_arm64**.
355
356    **seccomp_filter** is declared in **base/startup/init/services/modules/seccomp/BUILD.gn** and is used to build the basic dynamic policy library of Seccomp. After the compilation is complete, dependency files are generated in **//out/Product name /gen/base/startup/init/services/modules/seccomp/gen_system_filter/**.
357    ```shell
358    ./build.sh --product-name *product name* --ccache --build-target seccomp_filter --target-cpu *specified CPU*
359
360    # Copy the dependency files to the tool folder for later use.
361    cp out/*product name* /gen/base/startup/init/services/modules/seccomp/gen_system_filter/libsyscall_to_nr_arm* base/startup/init/services/modules/seccomp/scripts/tools/
362    ```
363
3643. Copy the **generate_code_from_policy.py** script file to the tool folder. This script file is available at **//base/startup/init/services/modules/seccomp/scripts/**.
365    ```shell
366    # Go to the root directory of the OpenHarmony source code.
367    cd /root/to/OpenHarmonyCode;
368    # Go to the directory where the **generate_code_from_policy.py** script file is located.
369    cd base/startup/init/services/modules/seccomp/scripts/;
370    # Copy the **generate_code_from_policy.py** script file.
371    cp generate_code_from_policy.py tools/;
372    ```
373
3744. Compile ELF files related to the service code. In the 32-bit architecture, the implementation of disassembly code redirection for ELF files is complex. Therefore, ELF files are all compiled into 64-bit ELF files to parse the function call relationship.
375    ```shell
376    ./build.sh --product-name *product file* --ccache --target-cpu arm64 --build-target *target file*
377    ```
378
3795. If full build has not been performed before and the dependent dynamic libraries for step 4 are not in the **//out** directory, copy the related dynamic libraries to the **//out** directory. The following code is for reference only. If other dynamic libraries are involved, copy them in a similar way.
380    ```shell
381    # Go to the root directory of the source code.
382    cd /root/to/OpenHarmonyCode
383    # Create the **aarch64-linux-ohos** folder in **out/*product name*/lib.unstripped/** to store the dependent dynamic libraries.
384    mkdir out/*product name*/lib.unstripped/aarch64-linux-ohos
385    # Copy the related dynamic libraries to the //out directory.
386    cp prebuilts/clang/ohos/${host_platform_dir}/llvm/lib/clang/${clang_version}/lib/aarch64-linux-ohos/*.so out/*product name*/lib.unstripped/aarch64-linux-ohos/
387    cp prebuilts/clang/ohos/${host_platform_dir}/${clang_version}/llvm/lib/aarch64-linux-ohos/*.so out/*product name*/lib.unstripped/aarch64-linux-ohos/
388    ```
389
3906. Modify the **collect_elf_syscall.py** script file, and change the paths of the objdump and readelf tools to their absolute paths in the Linux environment. This script file is available at **base/startup/init/services/modules/seccomp/scripts/tools/**. The **objdump** and **readelf** tools available at **//prebuilts**.
391    ```python
392    #modified the path of objdump and readelf path
393    def get_obj_dump_path():
394        obj_dump_path = '/path/to/llvm-objdump'
395        return obj_dump_path
396
397
398    def get_read_elf_path():
399        read_elf_path = '/path/to/llvm-readelf'
400        return read_elf_path
401    ```
402
4037. Use the **strace_log_analysis.py** script file to parse and generate the corresponding policy file **xxx.seccomp.policy**.
404
405    **Table 7** Parameters in the collect_elf_syscall.py script file
406    |  Parameter |  Description |
407    |  ---  |  ---  |
408    |  --src-elf-path  | Folder where the ELF file is located, for example, **~/ohcode/out/rk3568**. Do not end the value with a slash (/).|
409    |  --elf-name| ELF file name, for example, **libmedia_service.z.so**.|
410    |  --src-syscall-path  |  **libsyscall_to_nr_arm** or **libsyscall_to_nr_arm64**, which corresponds to the architecture specified by **--target-cpu**. |
411    |  --target-cpu  |  CPU architecture, that is, the architecture for which system calls are collected. This parameter determines the architecture for libC file parsing. Its value can be **arm** or **arm64**. |
412    |  --filter-name  | Name of the generated policy file. For example, if the input value is **test**, the generated file name is **test.seccomp.policy**. |
413
414    Use **collect_elf_syscall.py** to parse ELF files.
415
416        ```
417        # The following example considers **rk3568** as the product and **libmedia_service.z.so** as the ELF file.
418        python3 collect_elf_syscall.py --src-elf-path ~/ohcode/out/rk3568 --elf-name libmedia_service.z.so --src-syscall-path libsyscall_to_nr_arm64 --target-cpu arm64 --filter-name media_service
419        ```
420
421        Example result of xxx.seccomp.policy
422        ```
423        @allowList
424        getcwd;arm64
425        eventfd2;arm64
426        epoll_create1;arm64
427        epoll_ctl;arm64
428        dup;arm64
429        dup3;arm64
430        fcntl;arm64
431        ioctl;arm64
432        ...
433        ```
434
435#### Strace Statistics
4361. Use the cross compilers arm-linux-musleabi and aarch64-linux-musl to build the Strace tool for the 32-bit and 64-bit architectures, respectively.
4372. [Trace the service process](#tracing-the-service-process) to obtain the Strace logs.
4383. [Parse Strace logs](#parsing-strace-logs) by using scripts to obtain the Seccomp policy file.
439##### Tracing the Service Process
4401. Modify the embedded code in the init repository. Specifically, add the following content to **//base/startup/init/services/init/init_common_service.c** before executing the **SetSystemseccompPolicy** function to set the Seccomp policy.  If the line starts with a plus sign (+), the line is added; if the line starts with a hyphen (-), the line is deleted. **xxxx** must be the same as the value of **Services name** in the [boot configuration file](subsys-boot-init-cfg.md) of the process.
441    ```c
442    --- a/services/init/init_common_service.c
443    +++ b/services/init/init_common_service.c
444    @@ -155,7 +155,19 @@ static int SetPerms(const Service *service)
445        // set seccomp policy before setuid
446        INIT_ERROR_CHECK(SetSystemseccompPolicy(service) == SERVICE_SUCCESS, return SERVICE_FAILURE,
447            "set seccomp policy failed for service %s", service->name);
448    -
449    +    if (strncmp(service->name, "xxxx", strlen("xxxx")) == 0) {
450    +        pid_t pid = getpid();
451    +        pid_t pid_child = fork();
452    +        if (pid_child == 0) {
453    +            char pidStr[9] = {0};
454    +            sprintf_s(pidStr, 6, "%d", pid);
455    +            if (execl("/system/bin/strace", "/system/bin/strace", "-p", (const char *)pidStr, "-ff", "-o", "/data/strace/xxxx.strace.log", NULL) !=0 ) {
456    +                INIT_LOGE("strace failed");
457    +            }
458    +        }
459    +        sleep(5);
460    +    }
461        if (service->servPerm.uID != 0) {
462            if (setuid(service->servPerm.uID) != 0) {
463                INIT_LOGE("setuid of service: %s failed, uid = %d", service->name, service->servPerm.uID);
464    ```
4652. Perform a full build, and burn the image.
4663. Disable SElinux, and push Strace to the device.
467    ```shell
468    hdc shell setenforce 0
469    hdc shell mount -rw -o remount /
470    hdc file send /path/to/strace /system/bin/
471    hdc shell chmod a+x /system/bin/strace
472    ```
4734. Create a folder for storing Strace logs.
474    ```shell
475    hdc shell mkdir -p /data/strace
476    ```
4775. Terminate the service process, and restart it. In the following command, **xxx** indicates the service process name.
478    ```shell
479    kill -9 $(pidof xxx)
480    ```
4816. Perform service operations on the device. Make sure that all code is covered.
4827. Obtain Strace logs from **/data/strace** on the device, and save them to the directory where the parsing script is located.
483    ```shell
484    hdc file recv /data/strace /path/to/base/startup/init/services/modules/seccomp/scripts/tools/
485    ```
486
487##### Parsing Strace Logs
4881. Copy the dependency files to the Strace log folder for later use. The dependency files are those generated in step 2 in [Static Analysis](#static-analysis).
489    ```shell
490    cp out/*product name* /gen/base/startup/init/services/modules/seccomp/gen_system_filter/libsyscall_to_nr_arm* base/startup/init/services/modules/seccomp/scripts/tools/strace/
491    ```
492
4932. Use the **strace_log_analysis.py** script file to parse and generate the corresponding policy file **xxx.seccomp.policy**.
494
495    The script file is available at **//base/startup/init/services/modules/seccomp/scripts/tools/**.
496
497    **Table 8** Parameters in the strace_log_analysis.py script file
498    |  Parameter |  Description |
499    |  ---  |  ---  |
500    |  --src-path  | Folder for storing log files. It must contain **libsyscall_to_nr_arm** and **libsyscall_to_nr_arm64**. The folder name must not end with a slash (/), for example, **./strace**.|
501    |  --target-cpu  |  CPU architecture, which is the same as that of the traced process. Its value can be **arm** or **arm64**. |
502    |  --filter-name  | Name of the generated policy file. For example, if the input value is **test**, the generated file name is **test.seccomp.policy**. |
503
504    Use the **strace_log_analysis.py** script file to parse Strace logs.
505    ```shell
506    cd base/startup/init/services/modules/seccomp/scripts/tools;
507    python3 strace_log_analysis.py --src-path strace --target-cpu *specified CPU* --filter-name xxx
508    ```
509    Example result of xxx.seccomp.policy
510    ```
511    @allowList
512    getcwd;arm64
513    eventfd2;arm64
514    epoll_create1;arm64
515    epoll_ctl;arm64
516    dup;arm64
517    dup3;arm64
518    fcntl;arm64
519    ioctl;arm64
520    ...
521    ```
522
523#### Audit Statistics
5241. Enable the initial Seccomp policy. For details, see [Customizing Seccomp Policies for a Process](#customizing-seccomp-policies-for-a-process).
5252. Obtain logs.
526    1. Create a folder for storing logs.
527        ```shell
528        mkdir -p /data/audit
529        ```
530    2. Obtain Seccomp-related audit log information from kernel logs. The logs end with **.audit.log**.
531        ```shell
532        cat /proc/kmsg | grep type=1326 > /data/audit/media_service.audit.log
533        ```
5343. Perform service-related operations and segment fault triggering operations.
535    1. To trigger a segment fault, add the following code to the service code to call **TriggerSegmentFault** at a certain point to rebuild and burn the image:
536        ```c
537        static void TriggerSegmentFault(void)
538        {
539            pid_t pid_child = fork();
540            if (pid_child == 0) {
541                char *test = (char *)0x1234;
542                *test = 1;
543            }
544        }
545        ```
546    2. After the device is started, run the following shell command to temporarily shut down SELinux and terminate the service process. The process then automatically restarts.
547        ```shell
548        setenforce 0
549        ```
550
5514. Run the hdc command to obtain audit logs from the **/data/audit** on of the device, and save them to the directory where the parsing script is located.
552    ```shell
553    hdc file recv /data/audit /path/to/base/startup/init/services/modules/seccomp/scripts/tools/
554    ```
5555. Parse the audit logs.
556
557    Example audit log:
558    ```shell
559    <5>[  198.963101] audit: type=1326 audit(1659528178.748:27): auid=4294967295 uid=0 gid=1000 ses=4294967295 subj=u:r:appspawn:s0 pid=2704 comm="config_dialog_s" exe="/system/bin/appspawn" sig=31 arch=40000028 syscall=208 compat=1 ip=0xf7b79400 code=0x80000000
560    ```
561    **Table 9** Key parameters in audit logs
562    |  Parameter |  Description |
563    |  ---  |  ---  |
564    |  type  |  Type. The value **1326** indicates that the log is of the Seccomp type. |
565    |  sig  |  Semaphore. The value **31** indicates **SIGSYS**, which is the signal sent to the process when Seccomp interception occurs. |
566    |  arch  |  Architecture ID. The value **40000028** indicates **arm**, and the value **c00000b7** indicates **arm64**. |
567    |  syscall  |  System call ID. |
568    |  compat  |  The value **1** indicates the compatibility mode, that is, the arm64 kernel uses arm system calls.|
569
570
571    1. Copy the dependency files to the log folder for later use. The dependency files are those generated in step 2 in [Static Analysis](#static-analysis).
572        ```shell
573        cp out/*product name* /gen/base/startup/init/services/modules/seccomp/gen_system_filter/libsyscall_to_nr_arm* base/startup/init/services/modules/seccomp/scripts/tools/audit/
574        ```
575    2. Run the **audit_log_analysis.py** script to parse logs and generate **xxx.seccomp.policy**. The tool is available at **//base/startup/init/services/modules/seccomp/scripts/tools/**.
576
577        **Table 10** Parameters in the audit_log_analysis.py script file
578        |  Parameter |  Description |
579        |  ---  |  ---  |
580        |  --src-path  | Folder for storing log files. It must contain **libsyscall_to_nr_arm** and **libsyscall_to_nr_arm64**. The folder name must not end with a slash (/), for example, **./audit**.|
581        |  --filter-name  | Name of the generated policy file. For example, if the input value is **test**, the generated file name is **test.seccomp.policy**.|
582
583        ```shell
584        cd base/startup/init/services/modules/seccomp/scripts/tools
585        python3 audit_log_analysis.py --src-path audit --filter-name xxx
586        ```
587
588### Combining Multiple Policy Files
589During [colltatistics on system calls](#system-call-statistic-methods), multiple policy files may be generated. In these policy files, system calls may be repeated or disordered. To solve these problems, you can combine policy files to sort system calls by arm64/arm and by system call number in ascending order.
590
591**Table 11** Parameters in the merge_policy.py script file
592|  Parameter |  Description |
593|  ---  |  ---  |
594|  --src-files  | Files to be processed, including **libsyscall_to_nr_arm** and **libsyscall_to_nr_arm64**.|
595|  --filter-name  | Name of the generated policy file. For example, if the input value is **test**, the generated file name is **test.seccomp.policy**. |
5961. Copy the dependency files to the log folder for later use.
597    ```shell
598    cp out/*product name* /gen/base/startup/init/services/modules/seccomp/gen_system_filter/libsyscall_to_nr_arm* base/startup/init/services/modules/seccomp/scripts/tools/
599    ```
6002. Run the **merge_policy.py** script to merge **policy1.seccomp.policy** and **policy2.seccomp.policy** into **xxxx.seccomp.policy**.
601    ```shell
602    python3 merge_policy.py --src-files libsyscall_to_nr_arm --src-files libsyscall_to_nr_arm64 --src-files policy1.seccomp.policy --src-files policy2.seccomp.policy --filter-name xxxx
603    ```
604