15f9996aaSopenharmony_ci#!/usr/bin/env python3
25f9996aaSopenharmony_ci# -*- coding: utf-8 -*-
35f9996aaSopenharmony_ci
45f9996aaSopenharmony_ci#
55f9996aaSopenharmony_ci# Copyright (c) 2022 Huawei Device Co., Ltd.
65f9996aaSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License");
75f9996aaSopenharmony_ci# you may not use this file except in compliance with the License.
85f9996aaSopenharmony_ci# You may obtain a copy of the License at
95f9996aaSopenharmony_ci#
105f9996aaSopenharmony_ci#     http://www.apache.org/licenses/LICENSE-2.0
115f9996aaSopenharmony_ci#
125f9996aaSopenharmony_ci# Unless required by applicable law or agreed to in writing, software
135f9996aaSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS,
145f9996aaSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
155f9996aaSopenharmony_ci# See the License for the specific language governing permissions and
165f9996aaSopenharmony_ci# limitations under the License.
175f9996aaSopenharmony_ci#
185f9996aaSopenharmony_ci
195f9996aaSopenharmony_ciimport sys
205f9996aaSopenharmony_ciimport argparse
215f9996aaSopenharmony_ciimport textwrap
225f9996aaSopenharmony_ciimport re
235f9996aaSopenharmony_ciimport os
245f9996aaSopenharmony_ciimport stat
255f9996aaSopenharmony_ci
265f9996aaSopenharmony_cisupported_parse_item = ['labelName', 'priority', 'allowList', 'blockList', 'priorityWithArgs', \
275f9996aaSopenharmony_ci                        'allowListWithArgs', 'headFiles', 'selfDefineSyscall', 'returnValue', \
285f9996aaSopenharmony_ci                        'mode', 'privilegedProcessName', 'allowBlockList']
295f9996aaSopenharmony_ci
305f9996aaSopenharmony_cisupported_architecture = ['arm', 'arm64', 'riscv64']
315f9996aaSopenharmony_ci
325f9996aaSopenharmony_ciBPF_JGE = 'BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, {}, {}, {}),'
335f9996aaSopenharmony_ciBPF_JGT = 'BPF_JUMP(BPF_JMP|BPF_JGT|BPF_K, {}, {}, {}),'
345f9996aaSopenharmony_ciBPF_JEQ = 'BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, {}, {}, {}),'
355f9996aaSopenharmony_ciBPF_JSET = 'BPF_JUMP(BPF_JMP|BPF_JSET|BPF_K, {}, {}, {}),'
365f9996aaSopenharmony_ciBPF_JA = 'BPF_JUMP(BPF_JMP|BPF_JA, {}, 0, 0),'
375f9996aaSopenharmony_ciBPF_LOAD = 'BPF_STMT(BPF_LD|BPF_W|BPF_ABS, {}),'
385f9996aaSopenharmony_ciBPF_LOAD_MEM = 'BPF_STMT(BPF_LD|BPF_MEM, {}),'
395f9996aaSopenharmony_ciBPF_ST = 'BPF_STMT(BPF_ST, {}),'
405f9996aaSopenharmony_ciBPF_AND = 'BPF_STMT(BPF_ALU|BPF_AND|BPF_K, {}),'
415f9996aaSopenharmony_ciBPF_RET_VALUE = 'BPF_STMT(BPF_RET|BPF_K, {}),'
425f9996aaSopenharmony_ci
435f9996aaSopenharmony_cioperation = ['<', '<=', '!=', '==', '>', '>=', '&']
445f9996aaSopenharmony_ci
455f9996aaSopenharmony_ciret_str_to_bpf = {
465f9996aaSopenharmony_ci    'KILL_PROCESS': 'SECCOMP_RET_KILL_PROCESS',
475f9996aaSopenharmony_ci    'KILL_THREAD': 'SECCOMP_RET_KILL_THREAD',
485f9996aaSopenharmony_ci    'TRAP': 'SECCOMP_RET_TRAP',
495f9996aaSopenharmony_ci    'ERRNO': 'SECCOMP_RET_ERRNO',
505f9996aaSopenharmony_ci    'USER_NOTIF': 'SECCOMP_RET_USER_NOTIF',
515f9996aaSopenharmony_ci    'TRACE': 'SECCOMP_RET_TRACE',
525f9996aaSopenharmony_ci    'LOG' : 'SECCOMP_RET_LOG',
535f9996aaSopenharmony_ci    'ALLOW': 'SECCOMP_RET_ALLOW'
545f9996aaSopenharmony_ci}
555f9996aaSopenharmony_ci
565f9996aaSopenharmony_cimode_str = {
575f9996aaSopenharmony_ci    'DEFAULT': 0,
585f9996aaSopenharmony_ci    'ONLY_CHECK_ARGS': 1
595f9996aaSopenharmony_ci}
605f9996aaSopenharmony_ci
615f9996aaSopenharmony_ciarchitecture_to_number = {
625f9996aaSopenharmony_ci    'arm': 'AUDIT_ARCH_ARM',
635f9996aaSopenharmony_ci    'arm64': 'AUDIT_ARCH_AARCH64',
645f9996aaSopenharmony_ci    'riscv64': 'AUDIT_ARCH_RISCV64'
655f9996aaSopenharmony_ci}
665f9996aaSopenharmony_ci
675f9996aaSopenharmony_ci
685f9996aaSopenharmony_ciclass ValidateError(Exception):
695f9996aaSopenharmony_ci    def __init__(self, msg):
705f9996aaSopenharmony_ci        super().__init__(msg)
715f9996aaSopenharmony_ci
725f9996aaSopenharmony_ci
735f9996aaSopenharmony_cidef print_info(info):
745f9996aaSopenharmony_ci    print("[INFO] %s" % info)
755f9996aaSopenharmony_ci
765f9996aaSopenharmony_ci
775f9996aaSopenharmony_cidef is_hex_digit(s):
785f9996aaSopenharmony_ci    try:
795f9996aaSopenharmony_ci        int(s, 16)
805f9996aaSopenharmony_ci        return True
815f9996aaSopenharmony_ci
825f9996aaSopenharmony_ci    except ValueError:
835f9996aaSopenharmony_ci        return False
845f9996aaSopenharmony_ci
855f9996aaSopenharmony_ci
865f9996aaSopenharmony_cidef str_convert_to_int(s):
875f9996aaSopenharmony_ci    number = -1
885f9996aaSopenharmony_ci    digit_flag = False
895f9996aaSopenharmony_ci
905f9996aaSopenharmony_ci    if s.isdigit() :
915f9996aaSopenharmony_ci        number = int(s)
925f9996aaSopenharmony_ci        digit_flag = True
935f9996aaSopenharmony_ci
945f9996aaSopenharmony_ci    elif is_hex_digit(s):
955f9996aaSopenharmony_ci        number = int(s, 16)
965f9996aaSopenharmony_ci        digit_flag = True
975f9996aaSopenharmony_ci
985f9996aaSopenharmony_ci    return number, digit_flag
995f9996aaSopenharmony_ci
1005f9996aaSopenharmony_ci
1015f9996aaSopenharmony_cidef is_function_name_exist(arch, function_name, func_name_nr_table):
1025f9996aaSopenharmony_ci    if function_name in func_name_nr_table:
1035f9996aaSopenharmony_ci        return True
1045f9996aaSopenharmony_ci    else:
1055f9996aaSopenharmony_ci        raise ValidateError('{} not exsit in {} function_name_nr_table Table'.format(function_name, arch))
1065f9996aaSopenharmony_ci
1075f9996aaSopenharmony_ci
1085f9996aaSopenharmony_cidef is_errno_in_valid_range(errno):
1095f9996aaSopenharmony_ci    if int(errno) > 0 and int(errno) <= 255 and errno.isdigit():
1105f9996aaSopenharmony_ci        return True
1115f9996aaSopenharmony_ci    else:
1125f9996aaSopenharmony_ci        raise ValidateError('{} not within the legal range of errno values.'.format(errno))
1135f9996aaSopenharmony_ci
1145f9996aaSopenharmony_ci
1155f9996aaSopenharmony_cidef is_return_errno(return_str):
1165f9996aaSopenharmony_ci    if return_str[0:len('ERRNO')] == 'ERRNO':
1175f9996aaSopenharmony_ci        errno_no = return_str[return_str.find('(') + 1 : return_str.find(')')]
1185f9996aaSopenharmony_ci        return_string = return_str[0:len('ERRNO')]
1195f9996aaSopenharmony_ci        return_string += ' | '
1205f9996aaSopenharmony_ci        if is_errno_in_valid_range(errno_no):
1215f9996aaSopenharmony_ci            return_string += errno_no
1225f9996aaSopenharmony_ci            return True, return_string
1235f9996aaSopenharmony_ci    return False, 'not_return_errno'
1245f9996aaSopenharmony_ci
1255f9996aaSopenharmony_ci
1265f9996aaSopenharmony_cidef function_name_to_nr(function_name_list, func_name_nr_table):
1275f9996aaSopenharmony_ci    return set(func_name_nr_table[function_name] for function_name \
1285f9996aaSopenharmony_ci    in function_name_list if function_name in func_name_nr_table)
1295f9996aaSopenharmony_ci
1305f9996aaSopenharmony_ci
1315f9996aaSopenharmony_cidef filter_syscalls_nr(name_to_nr):
1325f9996aaSopenharmony_ci    syscalls = {}
1335f9996aaSopenharmony_ci    for syscall_name, nr in name_to_nr.items():
1345f9996aaSopenharmony_ci        if not syscall_name.startswith("__NR_") and not syscall_name.startswith("__ARM_NR_"):
1355f9996aaSopenharmony_ci            continue
1365f9996aaSopenharmony_ci
1375f9996aaSopenharmony_ci        if syscall_name.startswith("__NR_arm_"):
1385f9996aaSopenharmony_ci            syscall_name = syscall_name[len("__NR_arm_"):]
1395f9996aaSopenharmony_ci        elif syscall_name.startswith("__NR_riscv_"):
1405f9996aaSopenharmony_ci            syscall_name = syscall_name[len("__NR_riscv_"):]
1415f9996aaSopenharmony_ci        elif syscall_name.startswith("__NR_"):
1425f9996aaSopenharmony_ci            syscall_name = syscall_name[len("__NR_"):]
1435f9996aaSopenharmony_ci        elif syscall_name.startswith("__ARM_NR_"):
1445f9996aaSopenharmony_ci            syscall_name = syscall_name[len("__ARM_NR_"):]
1455f9996aaSopenharmony_ci        elif syscall_name.startswith("__RISCV_NR_"):
1465f9996aaSopenharmony_ci            syscall_name = syscall_name[len("__RISCV_NR_"):]
1475f9996aaSopenharmony_ci        syscalls[syscall_name] = nr
1485f9996aaSopenharmony_ci
1495f9996aaSopenharmony_ci    return syscalls
1505f9996aaSopenharmony_ci
1515f9996aaSopenharmony_ci
1525f9996aaSopenharmony_cidef parse_syscall_file(file_name):
1535f9996aaSopenharmony_ci    const_pattern = re.compile(
1545f9996aaSopenharmony_ci        r'^\s*#define\s+([A-Za-z_][A-Za-z0-9_]+)\s+(.+)\s*$')
1555f9996aaSopenharmony_ci    mark_pattern = re.compile(r'\b[A-Za-z_][A-Za-z0-9_]+\b')
1565f9996aaSopenharmony_ci    name_to_nr = {}
1575f9996aaSopenharmony_ci    with open(file_name) as f:
1585f9996aaSopenharmony_ci        for line in f:
1595f9996aaSopenharmony_ci            k = const_pattern.match(line)
1605f9996aaSopenharmony_ci            if k is None:
1615f9996aaSopenharmony_ci                continue
1625f9996aaSopenharmony_ci            try:
1635f9996aaSopenharmony_ci                name = k.group(1)
1645f9996aaSopenharmony_ci                nr = eval(mark_pattern.sub(lambda x: str(name_to_nr.get(x.group(0))),
1655f9996aaSopenharmony_ci                                        k.group(2)))
1665f9996aaSopenharmony_ci
1675f9996aaSopenharmony_ci                name_to_nr[name] = nr
1685f9996aaSopenharmony_ci            except(KeyError, SyntaxError, NameError, TypeError):
1695f9996aaSopenharmony_ci                continue
1705f9996aaSopenharmony_ci
1715f9996aaSopenharmony_ci    return filter_syscalls_nr(name_to_nr)
1725f9996aaSopenharmony_ci
1735f9996aaSopenharmony_ci
1745f9996aaSopenharmony_cidef gen_syscall_nr_table(file_name, func_name_nr_table):
1755f9996aaSopenharmony_ci    s = re.search(r"libsyscall_to_nr_([^/]+)", file_name)
1765f9996aaSopenharmony_ci    func_name_nr_table[str(s.group(1))] = parse_syscall_file(file_name)
1775f9996aaSopenharmony_ci    if str(s.group(1)) not in func_name_nr_table.keys():
1785f9996aaSopenharmony_ci        raise ValidateError("parse syscall file failed")
1795f9996aaSopenharmony_ci    return func_name_nr_table
1805f9996aaSopenharmony_ci
1815f9996aaSopenharmony_ci
1825f9996aaSopenharmony_ciclass SeccompPolicyParam:
1835f9996aaSopenharmony_ci    def __init__(self, arch, function_name_nr_table, is_debug):
1845f9996aaSopenharmony_ci        self.arch = arch
1855f9996aaSopenharmony_ci        self.priority = set()
1865f9996aaSopenharmony_ci        self.allow_list = set()
1875f9996aaSopenharmony_ci        self.blocklist = set()
1885f9996aaSopenharmony_ci        self.priority_with_args = set()
1895f9996aaSopenharmony_ci        self.allow_list_with_args = set()
1905f9996aaSopenharmony_ci        self.head_files = set()
1915f9996aaSopenharmony_ci        self.self_define_syscall = set()
1925f9996aaSopenharmony_ci        self.final_allow_list = set()
1935f9996aaSopenharmony_ci        self.final_priority = set()
1945f9996aaSopenharmony_ci        self.final_priority_with_args = set()
1955f9996aaSopenharmony_ci        self.final_allow_list_with_args = set()
1965f9996aaSopenharmony_ci        self.return_value = ''
1975f9996aaSopenharmony_ci        self.mode = 'DEFAULT'
1985f9996aaSopenharmony_ci        self.is_debug = is_debug
1995f9996aaSopenharmony_ci        self.function_name_nr_table = function_name_nr_table
2005f9996aaSopenharmony_ci        self.value_function = {
2015f9996aaSopenharmony_ci            'priority': self.update_priority,
2025f9996aaSopenharmony_ci            'allowList': self.update_allow_list,
2035f9996aaSopenharmony_ci            'blockList': self.update_blocklist,
2045f9996aaSopenharmony_ci            'allowListWithArgs': self.update_allow_list_with_args,
2055f9996aaSopenharmony_ci            'priorityWithArgs': self.update_priority_with_args,
2065f9996aaSopenharmony_ci            'headFiles': self.update_head_files,
2075f9996aaSopenharmony_ci            'selfDefineSyscall': self.update_self_define_syscall,
2085f9996aaSopenharmony_ci            'returnValue': self.update_return_value,
2095f9996aaSopenharmony_ci            'mode': self.update_mode
2105f9996aaSopenharmony_ci        }
2115f9996aaSopenharmony_ci
2125f9996aaSopenharmony_ci    def clear_list(self):
2135f9996aaSopenharmony_ci        self.priority.clear()
2145f9996aaSopenharmony_ci        self.allow_list.clear()
2155f9996aaSopenharmony_ci        self.allow_list_with_args.clear()
2165f9996aaSopenharmony_ci        self.priority_with_args.clear()
2175f9996aaSopenharmony_ci        if self.mode == 'ONLY_CHECK_ARGS':
2185f9996aaSopenharmony_ci            self.final_allow_list.clear()
2195f9996aaSopenharmony_ci            self.final_priority.clear()
2205f9996aaSopenharmony_ci
2215f9996aaSopenharmony_ci    def update_list(self, function_name, to_update_list):
2225f9996aaSopenharmony_ci        if is_function_name_exist(self.arch, function_name, self.function_name_nr_table):
2235f9996aaSopenharmony_ci            to_update_list.add(function_name)
2245f9996aaSopenharmony_ci            return True
2255f9996aaSopenharmony_ci        return False
2265f9996aaSopenharmony_ci
2275f9996aaSopenharmony_ci    def update_priority(self, function_name):
2285f9996aaSopenharmony_ci        return self.update_list(function_name, self.priority)
2295f9996aaSopenharmony_ci
2305f9996aaSopenharmony_ci    def update_allow_list(self, function_name):
2315f9996aaSopenharmony_ci        return self.update_list(function_name, self.allow_list)
2325f9996aaSopenharmony_ci
2335f9996aaSopenharmony_ci    def update_blocklist(self, function_name):
2345f9996aaSopenharmony_ci        return self.update_list(function_name, self.blocklist)
2355f9996aaSopenharmony_ci
2365f9996aaSopenharmony_ci    def update_priority_with_args(self, function_name_with_args):
2375f9996aaSopenharmony_ci        function_name = function_name_with_args[:function_name_with_args.find(':')]
2385f9996aaSopenharmony_ci        function_name = function_name.strip()
2395f9996aaSopenharmony_ci        if is_function_name_exist(self.arch, function_name, self.function_name_nr_table):
2405f9996aaSopenharmony_ci            self.priority_with_args.add(function_name_with_args)
2415f9996aaSopenharmony_ci            return True
2425f9996aaSopenharmony_ci        return False
2435f9996aaSopenharmony_ci
2445f9996aaSopenharmony_ci    def update_allow_list_with_args(self, function_name_with_args):
2455f9996aaSopenharmony_ci        function_name = function_name_with_args[:function_name_with_args.find(':')]
2465f9996aaSopenharmony_ci        function_name = function_name.strip()
2475f9996aaSopenharmony_ci        if is_function_name_exist(self.arch, function_name, self.function_name_nr_table):
2485f9996aaSopenharmony_ci            self.allow_list_with_args.add(function_name_with_args)
2495f9996aaSopenharmony_ci            return True
2505f9996aaSopenharmony_ci        return False
2515f9996aaSopenharmony_ci
2525f9996aaSopenharmony_ci    def update_head_files(self, head_files):
2535f9996aaSopenharmony_ci        if len(head_files) > 2 and (head_files[0] == '\"' and head_files[-1] == '\"') or \
2545f9996aaSopenharmony_ci            (head_files[0] == '<' and head_files[-1] == '>'):
2555f9996aaSopenharmony_ci            self.head_files.add(head_files)
2565f9996aaSopenharmony_ci            return True
2575f9996aaSopenharmony_ci
2585f9996aaSopenharmony_ci        raise ValidateError('{} is not legal by headFiles format'.format(head_files))
2595f9996aaSopenharmony_ci
2605f9996aaSopenharmony_ci    def update_self_define_syscall(self, self_define_syscall):
2615f9996aaSopenharmony_ci        nr, digit_flag = str_convert_to_int(self_define_syscall)
2625f9996aaSopenharmony_ci        if digit_flag and nr not in self.function_name_nr_table.values():
2635f9996aaSopenharmony_ci            self.self_define_syscall.add(nr)
2645f9996aaSopenharmony_ci            return True
2655f9996aaSopenharmony_ci
2665f9996aaSopenharmony_ci        raise ValidateError('{} is not a number or {} is already used by ohter \
2675f9996aaSopenharmony_ci            syscall'.format(self_define_syscall, self_define_syscall))
2685f9996aaSopenharmony_ci
2695f9996aaSopenharmony_ci    def update_return_value(self, return_str):
2705f9996aaSopenharmony_ci        is_ret_errno, return_string = is_return_errno(return_str)
2715f9996aaSopenharmony_ci        if is_ret_errno == True:
2725f9996aaSopenharmony_ci            self.return_value = return_string
2735f9996aaSopenharmony_ci            return True
2745f9996aaSopenharmony_ci        if return_str in ret_str_to_bpf:
2755f9996aaSopenharmony_ci            if self.is_debug == 'false' and return_str == 'LOG':
2765f9996aaSopenharmony_ci                raise ValidateError("LOG return value is not allowed in user mode")
2775f9996aaSopenharmony_ci            self.return_value = return_str
2785f9996aaSopenharmony_ci            return True
2795f9996aaSopenharmony_ci
2805f9996aaSopenharmony_ci        raise ValidateError('{} not in {}'.format(return_str, ret_str_to_bpf.keys()))
2815f9996aaSopenharmony_ci
2825f9996aaSopenharmony_ci    def update_mode(self, mode):
2835f9996aaSopenharmony_ci        if mode in mode_str.keys():
2845f9996aaSopenharmony_ci            self.mode = mode
2855f9996aaSopenharmony_ci            return True
2865f9996aaSopenharmony_ci        raise ValidateError('{} not in [DEFAULT, ONLY_CHECK_ARGS]'.format(mode_str))
2875f9996aaSopenharmony_ci
2885f9996aaSopenharmony_ci    def check_allow_list(self, allow_list):
2895f9996aaSopenharmony_ci        for item in allow_list:
2905f9996aaSopenharmony_ci            pos = item.find(':')
2915f9996aaSopenharmony_ci            syscall = item
2925f9996aaSopenharmony_ci            if pos != -1:
2935f9996aaSopenharmony_ci                syscall = item[:pos]
2945f9996aaSopenharmony_ci            if syscall in self.blocklist:
2955f9996aaSopenharmony_ci                raise ValidateError('{} of allow list  is in block list'.format(syscall))
2965f9996aaSopenharmony_ci        return True
2975f9996aaSopenharmony_ci
2985f9996aaSopenharmony_ci    def check_all_allow_list(self):
2995f9996aaSopenharmony_ci        flag = self.check_allow_list(self.final_allow_list) \
3005f9996aaSopenharmony_ci               and self.check_allow_list(self.final_priority) \
3015f9996aaSopenharmony_ci               and self.check_allow_list(self.final_priority_with_args) \
3025f9996aaSopenharmony_ci               and self.check_allow_list(self.final_allow_list_with_args)
3035f9996aaSopenharmony_ci        block_nr_list = function_name_to_nr(self.blocklist, self.function_name_nr_table)
3045f9996aaSopenharmony_ci        for nr in self.self_define_syscall:
3055f9996aaSopenharmony_ci            if nr in block_nr_list:
3065f9996aaSopenharmony_ci                return False
3075f9996aaSopenharmony_ci        return flag
3085f9996aaSopenharmony_ci
3095f9996aaSopenharmony_ci    def update_final_list(self):
3105f9996aaSopenharmony_ci        #remove duplicate function_name
3115f9996aaSopenharmony_ci        self.final_allow_list |= self.allow_list
3125f9996aaSopenharmony_ci        self.final_priority |= self.priority
3135f9996aaSopenharmony_ci        self.final_allow_list_with_args |= self.allow_list_with_args
3145f9996aaSopenharmony_ci        self.final_priority_with_args |= self.priority_with_args
3155f9996aaSopenharmony_ci        final_priority_function_name_list_with_args = set(item[:item.find(':')]
3165f9996aaSopenharmony_ci                                                            for item in self.final_priority_with_args)
3175f9996aaSopenharmony_ci        final_function_name_list_with_args = set(item[:item.find(':')]
3185f9996aaSopenharmony_ci                                                    for item in self.final_allow_list_with_args)
3195f9996aaSopenharmony_ci        self.final_allow_list = self.final_allow_list - self.final_priority - \
3205f9996aaSopenharmony_ci                                    final_priority_function_name_list_with_args - final_function_name_list_with_args
3215f9996aaSopenharmony_ci        self.final_priority = self.final_priority - final_priority_function_name_list_with_args - \
3225f9996aaSopenharmony_ci                                final_function_name_list_with_args
3235f9996aaSopenharmony_ci        self.clear_list()
3245f9996aaSopenharmony_ci
3255f9996aaSopenharmony_ci
3265f9996aaSopenharmony_ciclass GenBpfPolicy:
3275f9996aaSopenharmony_ci    def __init__(self):
3285f9996aaSopenharmony_ci        self.arch = ''
3295f9996aaSopenharmony_ci        self.syscall_nr_range = []
3305f9996aaSopenharmony_ci        self.bpf_policy = []
3315f9996aaSopenharmony_ci        self.syscall_nr_policy_list = []
3325f9996aaSopenharmony_ci        self.function_name_nr_table_dict = {}
3335f9996aaSopenharmony_ci        self.gen_mode = 0
3345f9996aaSopenharmony_ci        self.flag = True
3355f9996aaSopenharmony_ci        self.return_value = ''
3365f9996aaSopenharmony_ci        self.operate_func_table = {
3375f9996aaSopenharmony_ci            '<' : self.gen_bpf_lt,
3385f9996aaSopenharmony_ci            '<=': self.gen_bpf_le,
3395f9996aaSopenharmony_ci            '==': self.gen_bpf_eq,
3405f9996aaSopenharmony_ci            '!=': self.gen_bpf_ne,
3415f9996aaSopenharmony_ci            '>' : self.gen_bpf_gt,
3425f9996aaSopenharmony_ci            '>=': self.gen_bpf_ge,
3435f9996aaSopenharmony_ci            '&' : self.gen_bpf_set,
3445f9996aaSopenharmony_ci        }
3455f9996aaSopenharmony_ci
3465f9996aaSopenharmony_ci    @staticmethod
3475f9996aaSopenharmony_ci    def gen_bpf_eq32(const_str, jt, jf):
3485f9996aaSopenharmony_ci        bpf_policy = []
3495f9996aaSopenharmony_ci        bpf_policy.append(BPF_JEQ.format(const_str + ' & 0xffffffff', jt, jf))
3505f9996aaSopenharmony_ci        return bpf_policy
3515f9996aaSopenharmony_ci
3525f9996aaSopenharmony_ci    @staticmethod
3535f9996aaSopenharmony_ci    def gen_bpf_eq64(const_str, jt, jf):
3545f9996aaSopenharmony_ci        bpf_policy = []
3555f9996aaSopenharmony_ci        bpf_policy.append(BPF_JEQ.format('((unsigned long)' + const_str + ') >> 32', 0, jf + 2))
3565f9996aaSopenharmony_ci        bpf_policy.append(BPF_LOAD_MEM.format(0))
3575f9996aaSopenharmony_ci        bpf_policy.append(BPF_JEQ.format(const_str + ' & 0xffffffff', jt, jf))
3585f9996aaSopenharmony_ci        return bpf_policy
3595f9996aaSopenharmony_ci
3605f9996aaSopenharmony_ci    @staticmethod
3615f9996aaSopenharmony_ci    def gen_bpf_gt32(const_str, jt, jf):
3625f9996aaSopenharmony_ci        bpf_policy = []
3635f9996aaSopenharmony_ci        bpf_policy.append(BPF_JGT.format(const_str + ' & 0xffffffff', jt, jf))
3645f9996aaSopenharmony_ci        return bpf_policy
3655f9996aaSopenharmony_ci
3665f9996aaSopenharmony_ci    @staticmethod
3675f9996aaSopenharmony_ci    def gen_bpf_gt64(const_str, jt, jf):
3685f9996aaSopenharmony_ci        bpf_policy = []
3695f9996aaSopenharmony_ci        number, digit_flag = str_convert_to_int(const_str)
3705f9996aaSopenharmony_ci
3715f9996aaSopenharmony_ci        hight = int(number / (2**32))
3725f9996aaSopenharmony_ci        low = number & 0xffffffff
3735f9996aaSopenharmony_ci
3745f9996aaSopenharmony_ci        if digit_flag and hight == 0:
3755f9996aaSopenharmony_ci            bpf_policy.append(BPF_JGT.format('((unsigned long)' + const_str + ') >> 32', jt + 2, 0))
3765f9996aaSopenharmony_ci        else:
3775f9996aaSopenharmony_ci            bpf_policy.append(BPF_JGT.format('((unsigned long)' + const_str + ') >> 32', jt + 3, 0))
3785f9996aaSopenharmony_ci            bpf_policy.append(BPF_JEQ.format('((unsigned long)' + const_str + ') >> 32', 0, jf + 2))
3795f9996aaSopenharmony_ci
3805f9996aaSopenharmony_ci        bpf_policy.append(BPF_LOAD_MEM.format(0))
3815f9996aaSopenharmony_ci        bpf_policy.append(BPF_JGT.format(const_str + ' & 0xffffffff', jt, jf))
3825f9996aaSopenharmony_ci
3835f9996aaSopenharmony_ci        return bpf_policy
3845f9996aaSopenharmony_ci
3855f9996aaSopenharmony_ci    @staticmethod
3865f9996aaSopenharmony_ci    def gen_bpf_ge32(const_str, jt, jf):
3875f9996aaSopenharmony_ci        bpf_policy = []
3885f9996aaSopenharmony_ci        bpf_policy.append(BPF_JGE.format(const_str + ' & 0xffffffff', jt, jf))
3895f9996aaSopenharmony_ci        return bpf_policy
3905f9996aaSopenharmony_ci
3915f9996aaSopenharmony_ci    @staticmethod
3925f9996aaSopenharmony_ci    def gen_bpf_ge64(const_str, jt, jf):
3935f9996aaSopenharmony_ci        bpf_policy = []
3945f9996aaSopenharmony_ci        number, digit_flag = str_convert_to_int(const_str)
3955f9996aaSopenharmony_ci
3965f9996aaSopenharmony_ci        hight = int(number / (2**32))
3975f9996aaSopenharmony_ci        low = number & 0xffffffff
3985f9996aaSopenharmony_ci
3995f9996aaSopenharmony_ci        if digit_flag and hight == 0:
4005f9996aaSopenharmony_ci            bpf_policy.append(BPF_JGT.format('((unsigned long)' + const_str + ') >> 32', jt + 2, 0))
4015f9996aaSopenharmony_ci        else:
4025f9996aaSopenharmony_ci            bpf_policy.append(BPF_JGT.format('((unsigned long)' + const_str + ') >> 32', jt + 3, 0))
4035f9996aaSopenharmony_ci            bpf_policy.append(BPF_JEQ.format('((unsigned long)' + const_str + ') >> 32', 0, jf + 2))
4045f9996aaSopenharmony_ci        bpf_policy.append(BPF_LOAD_MEM.format(0))
4055f9996aaSopenharmony_ci        bpf_policy.append(BPF_JGE.format(const_str + ' & 0xffffffff', jt, jf))
4065f9996aaSopenharmony_ci        return bpf_policy
4075f9996aaSopenharmony_ci
4085f9996aaSopenharmony_ci    @staticmethod
4095f9996aaSopenharmony_ci    def gen_bpf_set32(const_str, jt, jf):
4105f9996aaSopenharmony_ci        bpf_policy = []
4115f9996aaSopenharmony_ci        bpf_policy.append(BPF_JSET.format(const_str + ' & 0xffffffff', jt, jf))
4125f9996aaSopenharmony_ci        return bpf_policy
4135f9996aaSopenharmony_ci
4145f9996aaSopenharmony_ci    @staticmethod
4155f9996aaSopenharmony_ci    def gen_bpf_set64(const_str, jt, jf):
4165f9996aaSopenharmony_ci        bpf_policy = []
4175f9996aaSopenharmony_ci        bpf_policy.append(BPF_JSET.format('((unsigned long)' + const_str + ') >> 32', jt + 2, 0))
4185f9996aaSopenharmony_ci        bpf_policy.append(BPF_LOAD_MEM.format(0))
4195f9996aaSopenharmony_ci        bpf_policy.append(BPF_JSET.format(const_str + ' & 0xffffffff', jt, jf))
4205f9996aaSopenharmony_ci        return bpf_policy
4215f9996aaSopenharmony_ci
4225f9996aaSopenharmony_ci    @staticmethod
4235f9996aaSopenharmony_ci    def gen_bpf_valid_syscall_nr(syscall_nr, cur_size):
4245f9996aaSopenharmony_ci        bpf_policy = []
4255f9996aaSopenharmony_ci        bpf_policy.append(BPF_LOAD.format(0))
4265f9996aaSopenharmony_ci        bpf_policy.append(BPF_JEQ.format(syscall_nr, 0, cur_size))
4275f9996aaSopenharmony_ci        return bpf_policy
4285f9996aaSopenharmony_ci
4295f9996aaSopenharmony_ci    @staticmethod
4305f9996aaSopenharmony_ci    def check_arg_str(arg_atom):
4315f9996aaSopenharmony_ci        arg_str = arg_atom[0:3]
4325f9996aaSopenharmony_ci        if arg_str != 'arg':
4335f9996aaSopenharmony_ci            raise ValidateError('format ERROR, {} is not equal to arg'.format(arg_atom))
4345f9996aaSopenharmony_ci
4355f9996aaSopenharmony_ci        arg_id = int(arg_atom[3])
4365f9996aaSopenharmony_ci        if arg_id not in range(6):
4375f9996aaSopenharmony_ci            raise ValidateError('arg num out of the scope 0~5')
4385f9996aaSopenharmony_ci
4395f9996aaSopenharmony_ci        return arg_id, True
4405f9996aaSopenharmony_ci
4415f9996aaSopenharmony_ci    @staticmethod
4425f9996aaSopenharmony_ci    def check_operation_str(operation_atom):
4435f9996aaSopenharmony_ci        operation_str = operation_atom
4445f9996aaSopenharmony_ci        if operation_str not in operation:
4455f9996aaSopenharmony_ci            operation_str = operation_atom[0]
4465f9996aaSopenharmony_ci            if operation_str not in operation:
4475f9996aaSopenharmony_ci                raise ValidateError('operation not in [<, <=, !=, ==, >, >=, &]')
4485f9996aaSopenharmony_ci        return operation_str, True
4495f9996aaSopenharmony_ci
4505f9996aaSopenharmony_ci    #gen bpf (argn & mask) == value
4515f9996aaSopenharmony_ci    @staticmethod
4525f9996aaSopenharmony_ci    def gen_mask_equal_bpf(arg_id, mask, value, cur_size):
4535f9996aaSopenharmony_ci        bpf_policy = []
4545f9996aaSopenharmony_ci        #high 4 bytes
4555f9996aaSopenharmony_ci        bpf_policy.append(BPF_LOAD.format(20 + arg_id * 8))
4565f9996aaSopenharmony_ci        bpf_policy.append(BPF_AND.format('((uint64_t)' + mask + ') >> 32'))
4575f9996aaSopenharmony_ci        bpf_policy.append(BPF_JEQ.format('((uint64_t)' + value + ') >> 32', 0, cur_size + 4))
4585f9996aaSopenharmony_ci
4595f9996aaSopenharmony_ci        #low 4 bytes
4605f9996aaSopenharmony_ci        bpf_policy.append(BPF_LOAD.format(16 + arg_id * 8))
4615f9996aaSopenharmony_ci        bpf_policy.append(BPF_AND.format(mask))
4625f9996aaSopenharmony_ci        bpf_policy.append(BPF_JEQ.format(value, cur_size, cur_size + 1))
4635f9996aaSopenharmony_ci
4645f9996aaSopenharmony_ci        return bpf_policy
4655f9996aaSopenharmony_ci
4665f9996aaSopenharmony_ci    def update_arch(self, arch):
4675f9996aaSopenharmony_ci        self.arch = arch
4685f9996aaSopenharmony_ci        self.syscall_nr_range = []
4695f9996aaSopenharmony_ci        self.syscall_nr_policy_list = []
4705f9996aaSopenharmony_ci
4715f9996aaSopenharmony_ci    def update_function_name_nr_table(self, func_name_nr_table):
4725f9996aaSopenharmony_ci        self.function_name_nr_table_dict = func_name_nr_table
4735f9996aaSopenharmony_ci
4745f9996aaSopenharmony_ci    def clear_bpf_policy(self):
4755f9996aaSopenharmony_ci        self.bpf_policy.clear()
4765f9996aaSopenharmony_ci
4775f9996aaSopenharmony_ci    def get_gen_flag(self):
4785f9996aaSopenharmony_ci        return self.flag
4795f9996aaSopenharmony_ci
4805f9996aaSopenharmony_ci    def set_gen_flag(self, flag):
4815f9996aaSopenharmony_ci        if flag:
4825f9996aaSopenharmony_ci            self.flag = True
4835f9996aaSopenharmony_ci        else:
4845f9996aaSopenharmony_ci            self.flag = False
4855f9996aaSopenharmony_ci
4865f9996aaSopenharmony_ci    def set_gen_mode(self, mode):
4875f9996aaSopenharmony_ci        self.gen_mode = mode_str.get(mode)
4885f9996aaSopenharmony_ci
4895f9996aaSopenharmony_ci    def set_return_value(self, return_value):
4905f9996aaSopenharmony_ci        is_ret_errno, return_string = is_return_errno(return_value)
4915f9996aaSopenharmony_ci        if is_ret_errno == True:
4925f9996aaSopenharmony_ci            self.return_value = return_string
4935f9996aaSopenharmony_ci            return
4945f9996aaSopenharmony_ci        if return_value not in ret_str_to_bpf:
4955f9996aaSopenharmony_ci            self.set_gen_mode(False)
4965f9996aaSopenharmony_ci            return
4975f9996aaSopenharmony_ci
4985f9996aaSopenharmony_ci        self.return_value = return_value
4995f9996aaSopenharmony_ci
5005f9996aaSopenharmony_ci    def gen_bpf_eq(self, const_str, jt, jf):
5015f9996aaSopenharmony_ci        if self.arch == 'arm':
5025f9996aaSopenharmony_ci            return self.gen_bpf_eq32(const_str, jt, jf)
5035f9996aaSopenharmony_ci        elif self.arch == 'arm64' or self.arch == 'riscv64':
5045f9996aaSopenharmony_ci            return self.gen_bpf_eq64(const_str, jt, jf)
5055f9996aaSopenharmony_ci        return []
5065f9996aaSopenharmony_ci
5075f9996aaSopenharmony_ci    def gen_bpf_ne(self, const_str, jt, jf):
5085f9996aaSopenharmony_ci        return self.gen_bpf_eq(const_str, jf, jt)
5095f9996aaSopenharmony_ci
5105f9996aaSopenharmony_ci    def gen_bpf_gt(self, const_str, jt, jf):
5115f9996aaSopenharmony_ci        if self.arch == 'arm':
5125f9996aaSopenharmony_ci            return self.gen_bpf_gt32(const_str, jt, jf)
5135f9996aaSopenharmony_ci        elif self.arch == 'arm64' or self.arch == 'riscv64':
5145f9996aaSopenharmony_ci            return self.gen_bpf_gt64(const_str, jt, jf)
5155f9996aaSopenharmony_ci        return []
5165f9996aaSopenharmony_ci
5175f9996aaSopenharmony_ci    def gen_bpf_le(self, const_str, jt, jf):
5185f9996aaSopenharmony_ci        return self.gen_bpf_gt(const_str, jf, jt)
5195f9996aaSopenharmony_ci
5205f9996aaSopenharmony_ci    def gen_bpf_ge(self, const_str, jt, jf):
5215f9996aaSopenharmony_ci        if self.arch == 'arm':
5225f9996aaSopenharmony_ci            return self.gen_bpf_ge32(const_str, jt, jf)
5235f9996aaSopenharmony_ci        elif self.arch == 'arm64' or self.arch == 'riscv64':
5245f9996aaSopenharmony_ci            return self.gen_bpf_ge64(const_str, jt, jf)
5255f9996aaSopenharmony_ci        return []
5265f9996aaSopenharmony_ci
5275f9996aaSopenharmony_ci    def gen_bpf_lt(self, const_str, jt, jf):
5285f9996aaSopenharmony_ci        return self.gen_bpf_ge(const_str, jf, jt)
5295f9996aaSopenharmony_ci
5305f9996aaSopenharmony_ci    def gen_bpf_set(self, const_str, jt, jf):
5315f9996aaSopenharmony_ci        if self.arch == 'arm':
5325f9996aaSopenharmony_ci            return self.gen_bpf_set32(const_str, jt, jf)
5335f9996aaSopenharmony_ci        elif self.arch == 'arm64' or self.arch == 'riscv64':
5345f9996aaSopenharmony_ci            return self.gen_bpf_set64(const_str, jt, jf)
5355f9996aaSopenharmony_ci        return []
5365f9996aaSopenharmony_ci
5375f9996aaSopenharmony_ci    def gen_range_list(self, syscall_nr_list):
5385f9996aaSopenharmony_ci        if len(syscall_nr_list) == 0:
5395f9996aaSopenharmony_ci            return
5405f9996aaSopenharmony_ci        self.syscall_nr_range.clear()
5415f9996aaSopenharmony_ci
5425f9996aaSopenharmony_ci        syscall_nr_list_order = sorted(list(syscall_nr_list))
5435f9996aaSopenharmony_ci        range_temp = [syscall_nr_list_order[0], syscall_nr_list_order[0]]
5445f9996aaSopenharmony_ci
5455f9996aaSopenharmony_ci        for i in range(len(syscall_nr_list_order) - 1):
5465f9996aaSopenharmony_ci            if syscall_nr_list_order[i + 1] != syscall_nr_list_order[i] + 1:
5475f9996aaSopenharmony_ci                range_temp[1] = syscall_nr_list_order[i]
5485f9996aaSopenharmony_ci                self.syscall_nr_range.append(range_temp)
5495f9996aaSopenharmony_ci                range_temp = [syscall_nr_list_order[i + 1], syscall_nr_list_order[i + 1]]
5505f9996aaSopenharmony_ci
5515f9996aaSopenharmony_ci        range_temp[1] = syscall_nr_list_order[-1]
5525f9996aaSopenharmony_ci        self.syscall_nr_range.append(range_temp)
5535f9996aaSopenharmony_ci
5545f9996aaSopenharmony_ci    def gen_policy_syscall_nr(self, min_index, max_index, cur_syscall_nr_range):
5555f9996aaSopenharmony_ci        middle_index = (int)((min_index + max_index + 1) / 2)
5565f9996aaSopenharmony_ci
5575f9996aaSopenharmony_ci        if middle_index == min_index:
5585f9996aaSopenharmony_ci            self.syscall_nr_policy_list.append(cur_syscall_nr_range[middle_index][1] + 1)
5595f9996aaSopenharmony_ci            return
5605f9996aaSopenharmony_ci        else:
5615f9996aaSopenharmony_ci            self.syscall_nr_policy_list.append(cur_syscall_nr_range[middle_index][0])
5625f9996aaSopenharmony_ci
5635f9996aaSopenharmony_ci        self.gen_policy_syscall_nr(min_index, middle_index - 1, cur_syscall_nr_range)
5645f9996aaSopenharmony_ci        self.gen_policy_syscall_nr(middle_index, max_index, cur_syscall_nr_range)
5655f9996aaSopenharmony_ci
5665f9996aaSopenharmony_ci    def gen_policy_syscall_nr_list(self, cur_syscall_nr_range):
5675f9996aaSopenharmony_ci        if not cur_syscall_nr_range:
5685f9996aaSopenharmony_ci            return
5695f9996aaSopenharmony_ci        self.syscall_nr_policy_list.clear()
5705f9996aaSopenharmony_ci        self.syscall_nr_policy_list.append(cur_syscall_nr_range[0][0])
5715f9996aaSopenharmony_ci        self.gen_policy_syscall_nr(0, len(cur_syscall_nr_range) - 1, cur_syscall_nr_range)
5725f9996aaSopenharmony_ci
5735f9996aaSopenharmony_ci    def calculate_step(self, index):
5745f9996aaSopenharmony_ci        for i in range(index + 1, len(self.syscall_nr_policy_list)):
5755f9996aaSopenharmony_ci            if self.syscall_nr_policy_list[index] < self.syscall_nr_policy_list[i]:
5765f9996aaSopenharmony_ci                step = i - index
5775f9996aaSopenharmony_ci                break
5785f9996aaSopenharmony_ci        return step - 1
5795f9996aaSopenharmony_ci
5805f9996aaSopenharmony_ci    def nr_range_to_bpf_policy(self, cur_syscall_nr_range):
5815f9996aaSopenharmony_ci        self.gen_policy_syscall_nr_list(cur_syscall_nr_range)
5825f9996aaSopenharmony_ci        syscall_list_len = len(self.syscall_nr_policy_list)
5835f9996aaSopenharmony_ci
5845f9996aaSopenharmony_ci        if syscall_list_len == 0:
5855f9996aaSopenharmony_ci            return
5865f9996aaSopenharmony_ci
5875f9996aaSopenharmony_ci        self.bpf_policy.append(BPF_JGE.format(self.syscall_nr_policy_list[0], 0, syscall_list_len))
5885f9996aaSopenharmony_ci
5895f9996aaSopenharmony_ci        range_max_list = [k[1] for k in cur_syscall_nr_range]
5905f9996aaSopenharmony_ci
5915f9996aaSopenharmony_ci        for i in range(1, syscall_list_len):
5925f9996aaSopenharmony_ci            if self.syscall_nr_policy_list[i] - 1 in range_max_list:
5935f9996aaSopenharmony_ci                self.bpf_policy.append(BPF_JGE.format(self.syscall_nr_policy_list[i], \
5945f9996aaSopenharmony_ci                                        syscall_list_len - i, syscall_list_len - i - 1))
5955f9996aaSopenharmony_ci            else:
5965f9996aaSopenharmony_ci                step = self.calculate_step(i)
5975f9996aaSopenharmony_ci                self.bpf_policy.append(BPF_JGE.format(self.syscall_nr_policy_list[i], step, 0))
5985f9996aaSopenharmony_ci
5995f9996aaSopenharmony_ci        if self.syscall_nr_policy_list:
6005f9996aaSopenharmony_ci            self.bpf_policy.append(BPF_RET_VALUE.format('SECCOMP_RET_ALLOW'))
6015f9996aaSopenharmony_ci
6025f9996aaSopenharmony_ci    def count_alone_range(self):
6035f9996aaSopenharmony_ci        cnt = 0
6045f9996aaSopenharmony_ci        for item in self.syscall_nr_range:
6055f9996aaSopenharmony_ci            if item[0] == item[1]:
6065f9996aaSopenharmony_ci                cnt = cnt + 1
6075f9996aaSopenharmony_ci        return cnt
6085f9996aaSopenharmony_ci
6095f9996aaSopenharmony_ci    def gen_transverse_bpf_policy(self):
6105f9996aaSopenharmony_ci        if not self.syscall_nr_range:
6115f9996aaSopenharmony_ci            return
6125f9996aaSopenharmony_ci        cnt = self.count_alone_range()
6135f9996aaSopenharmony_ci        total_instruction_num = cnt + (len(self.syscall_nr_range) - cnt) * 2
6145f9996aaSopenharmony_ci        i = 0
6155f9996aaSopenharmony_ci        for item in self.syscall_nr_range:
6165f9996aaSopenharmony_ci            if item[0] == item[1]:
6175f9996aaSopenharmony_ci                if i == total_instruction_num - 1:
6185f9996aaSopenharmony_ci                    self.bpf_policy.append(BPF_JEQ.format(item[0], total_instruction_num - i - 1, 1))
6195f9996aaSopenharmony_ci                else:
6205f9996aaSopenharmony_ci                    self.bpf_policy.append(BPF_JEQ.format(item[0], total_instruction_num - i - 1, 0))
6215f9996aaSopenharmony_ci                i += 1
6225f9996aaSopenharmony_ci            else:
6235f9996aaSopenharmony_ci                self.bpf_policy.append(BPF_JGE.format(item[0], 0, total_instruction_num - i))
6245f9996aaSopenharmony_ci                i += 1
6255f9996aaSopenharmony_ci                if i == total_instruction_num - 1:
6265f9996aaSopenharmony_ci                    self.bpf_policy.append(BPF_JGE.format(item[1] + 1, 1, total_instruction_num - i - 1))
6275f9996aaSopenharmony_ci                else:
6285f9996aaSopenharmony_ci                    self.bpf_policy.append(BPF_JGE.format(item[1] + 1, 0, total_instruction_num - i - 1))
6295f9996aaSopenharmony_ci                i += 1
6305f9996aaSopenharmony_ci
6315f9996aaSopenharmony_ci        self.bpf_policy.append(BPF_RET_VALUE.format('SECCOMP_RET_ALLOW'))
6325f9996aaSopenharmony_ci
6335f9996aaSopenharmony_ci    def gen_bpf_policy(self, syscall_nr_list):
6345f9996aaSopenharmony_ci        self.gen_range_list(syscall_nr_list)
6355f9996aaSopenharmony_ci        range_size = (int)((len(self.syscall_nr_range) - 1) / 127) + 1
6365f9996aaSopenharmony_ci        alone_range_cnt = self.count_alone_range()
6375f9996aaSopenharmony_ci        if alone_range_cnt == len(self.syscall_nr_range):
6385f9996aaSopenharmony_ci            #Scattered distribution
6395f9996aaSopenharmony_ci            self.gen_transverse_bpf_policy()
6405f9996aaSopenharmony_ci            return
6415f9996aaSopenharmony_ci
6425f9996aaSopenharmony_ci        if range_size == 1:
6435f9996aaSopenharmony_ci            self.nr_range_to_bpf_policy(self.syscall_nr_range)
6445f9996aaSopenharmony_ci        else:
6455f9996aaSopenharmony_ci            for i in range(0, range_size):
6465f9996aaSopenharmony_ci                if i == 0:
6475f9996aaSopenharmony_ci                    self.nr_range_to_bpf_policy(self.syscall_nr_range[-127 * (i + 1):])
6485f9996aaSopenharmony_ci                elif i == range_size - 1:
6495f9996aaSopenharmony_ci                    self.nr_range_to_bpf_policy(self.syscall_nr_range[:-127 * i])
6505f9996aaSopenharmony_ci                else:
6515f9996aaSopenharmony_ci                    self.nr_range_to_bpf_policy(self.syscall_nr_range[-127 * (i + 1): -127 * i])
6525f9996aaSopenharmony_ci
6535f9996aaSopenharmony_ci    def load_arg(self, arg_id):
6545f9996aaSopenharmony_ci        # little endian
6555f9996aaSopenharmony_ci        bpf_policy = []
6565f9996aaSopenharmony_ci        if self.arch == 'arm':
6575f9996aaSopenharmony_ci            bpf_policy.append(BPF_LOAD.format(16 + arg_id * 8))
6585f9996aaSopenharmony_ci        elif self.arch == 'arm64' or self.arch == 'riscv64':
6595f9996aaSopenharmony_ci            #low 4 bytes
6605f9996aaSopenharmony_ci            bpf_policy.append(BPF_LOAD.format(16 + arg_id * 8))
6615f9996aaSopenharmony_ci            bpf_policy.append(BPF_ST.format(0))
6625f9996aaSopenharmony_ci            #high 4 bytes
6635f9996aaSopenharmony_ci            bpf_policy.append(BPF_LOAD.format(20 + arg_id * 8))
6645f9996aaSopenharmony_ci            bpf_policy.append(BPF_ST.format(1))
6655f9996aaSopenharmony_ci
6665f9996aaSopenharmony_ci        return bpf_policy
6675f9996aaSopenharmony_ci
6685f9996aaSopenharmony_ci    def compile_atom(self, atom, cur_size):
6695f9996aaSopenharmony_ci        bpf_policy = []
6705f9996aaSopenharmony_ci        if len(atom) < 6:
6715f9996aaSopenharmony_ci            raise ValidateError('{} format ERROR '.format(atom))
6725f9996aaSopenharmony_ci
6735f9996aaSopenharmony_ci        if atom[0] == '(':
6745f9996aaSopenharmony_ci            bpf_policy += self.compile_mask_equal_atom(atom, cur_size)
6755f9996aaSopenharmony_ci        else:
6765f9996aaSopenharmony_ci            bpf_policy += self.compile_single_operation_atom(atom, cur_size)
6775f9996aaSopenharmony_ci
6785f9996aaSopenharmony_ci        return bpf_policy
6795f9996aaSopenharmony_ci
6805f9996aaSopenharmony_ci    def compile_mask_equal_atom(self, atom, cur_size):
6815f9996aaSopenharmony_ci        bpf_policy = []
6825f9996aaSopenharmony_ci        left_brace_pos = atom.find('(')
6835f9996aaSopenharmony_ci        right_brace_pos = atom.rfind(')')
6845f9996aaSopenharmony_ci        inside_brace_content = atom[left_brace_pos + 1: right_brace_pos]
6855f9996aaSopenharmony_ci        outside_brace_content = atom[right_brace_pos + 1:]
6865f9996aaSopenharmony_ci
6875f9996aaSopenharmony_ci        arg_res = self.check_arg_str(inside_brace_content[0:4])
6885f9996aaSopenharmony_ci        if not arg_res[1]:
6895f9996aaSopenharmony_ci            return bpf_policy
6905f9996aaSopenharmony_ci
6915f9996aaSopenharmony_ci        operation_res_inside = self.check_operation_str(inside_brace_content[4:6])
6925f9996aaSopenharmony_ci        if operation_res_inside[0] != '&' or not operation_res_inside[1]:
6935f9996aaSopenharmony_ci            return bpf_policy
6945f9996aaSopenharmony_ci
6955f9996aaSopenharmony_ci        mask = inside_brace_content[4 + len(operation_res_inside[0]):]
6965f9996aaSopenharmony_ci
6975f9996aaSopenharmony_ci        operation_res_outside = self.check_operation_str(outside_brace_content[0:2])
6985f9996aaSopenharmony_ci        if operation_res_outside[0] != '==' or not operation_res_outside[1]:
6995f9996aaSopenharmony_ci            return bpf_policy
7005f9996aaSopenharmony_ci
7015f9996aaSopenharmony_ci        value = outside_brace_content[len(operation_res_outside[0]):]
7025f9996aaSopenharmony_ci
7035f9996aaSopenharmony_ci        return self.gen_mask_equal_bpf(arg_res[0], mask, value, cur_size)
7045f9996aaSopenharmony_ci
7055f9996aaSopenharmony_ci    def compile_single_operation_atom(self, atom, cur_size):
7065f9996aaSopenharmony_ci        bpf_policy = []
7075f9996aaSopenharmony_ci        arg_res = self.check_arg_str(atom[0:4])
7085f9996aaSopenharmony_ci        if not arg_res[1]:
7095f9996aaSopenharmony_ci            return bpf_policy
7105f9996aaSopenharmony_ci
7115f9996aaSopenharmony_ci        operation_res = self.check_operation_str(atom[4:6])
7125f9996aaSopenharmony_ci        if not operation_res[1]:
7135f9996aaSopenharmony_ci            return bpf_policy
7145f9996aaSopenharmony_ci
7155f9996aaSopenharmony_ci        const_str = atom[4 + len(operation_res[0]):]
7165f9996aaSopenharmony_ci
7175f9996aaSopenharmony_ci        if not const_str:
7185f9996aaSopenharmony_ci            return bpf_policy
7195f9996aaSopenharmony_ci
7205f9996aaSopenharmony_ci        bpf_policy += self.load_arg(arg_res[0])
7215f9996aaSopenharmony_ci        bpf_policy += self.operate_func_table.get(operation_res[0])(const_str, 0, cur_size + 1)
7225f9996aaSopenharmony_ci
7235f9996aaSopenharmony_ci        return bpf_policy
7245f9996aaSopenharmony_ci
7255f9996aaSopenharmony_ci    def parse_args_with_condition(self, group):
7265f9996aaSopenharmony_ci        #the priority of && higher than ||
7275f9996aaSopenharmony_ci        atoms = group.split('&&')
7285f9996aaSopenharmony_ci        bpf_policy = []
7295f9996aaSopenharmony_ci        for atom in reversed(atoms):
7305f9996aaSopenharmony_ci            bpf_policy = self.compile_atom(atom, len(bpf_policy)) + bpf_policy
7315f9996aaSopenharmony_ci        return bpf_policy
7325f9996aaSopenharmony_ci
7335f9996aaSopenharmony_ci    def parse_sub_group(self, group):
7345f9996aaSopenharmony_ci        bpf_policy = []
7355f9996aaSopenharmony_ci        group_info = group.split(';')
7365f9996aaSopenharmony_ci        operation_part = group_info[0]
7375f9996aaSopenharmony_ci        return_part = group_info[1]
7385f9996aaSopenharmony_ci        if not return_part.startswith('return'):
7395f9996aaSopenharmony_ci            raise ValidateError('allow list with args do not have return part')
7405f9996aaSopenharmony_ci
7415f9996aaSopenharmony_ci        self.set_return_value(return_part[len('return'):])
7425f9996aaSopenharmony_ci        and_cond_groups = operation_part.split('||')
7435f9996aaSopenharmony_ci        for and_condition_group in and_cond_groups:
7445f9996aaSopenharmony_ci            bpf_policy += self.parse_args_with_condition(and_condition_group)
7455f9996aaSopenharmony_ci            bpf_policy.append(BPF_RET_VALUE.format(ret_str_to_bpf.get(self.return_value)))
7465f9996aaSopenharmony_ci        return bpf_policy
7475f9996aaSopenharmony_ci
7485f9996aaSopenharmony_ci    def parse_else_part(self, else_part):
7495f9996aaSopenharmony_ci        return_value = else_part.split(';')[0][else_part.find('return') + len('return'):]
7505f9996aaSopenharmony_ci        self.set_return_value(return_value)
7515f9996aaSopenharmony_ci
7525f9996aaSopenharmony_ci    def parse_args(self, function_name, line, skip):
7535f9996aaSopenharmony_ci        bpf_policy = []
7545f9996aaSopenharmony_ci        group_info = line.split('else')
7555f9996aaSopenharmony_ci        else_part = group_info[-1]
7565f9996aaSopenharmony_ci        group = group_info[0].split('elif')
7575f9996aaSopenharmony_ci        for sub_group in group:
7585f9996aaSopenharmony_ci            bpf_policy += self.parse_sub_group(sub_group)
7595f9996aaSopenharmony_ci        self.parse_else_part(else_part)
7605f9996aaSopenharmony_ci        if self.return_value[0:len('ERRNO')] == 'ERRNO':
7615f9996aaSopenharmony_ci            bpf_policy.append(BPF_RET_VALUE.format(self.return_value.replace('ERRNO', ret_str_to_bpf.get('ERRNO'))))
7625f9996aaSopenharmony_ci        else:
7635f9996aaSopenharmony_ci            bpf_policy.append(BPF_RET_VALUE.format(ret_str_to_bpf.get(self.return_value)))
7645f9996aaSopenharmony_ci        syscall_nr = self.function_name_nr_table_dict.get(self.arch).get(function_name)
7655f9996aaSopenharmony_ci        #load syscall nr
7665f9996aaSopenharmony_ci        bpf_policy = self.gen_bpf_valid_syscall_nr(syscall_nr, len(bpf_policy) - skip) + bpf_policy
7675f9996aaSopenharmony_ci        return bpf_policy
7685f9996aaSopenharmony_ci
7695f9996aaSopenharmony_ci    def gen_bpf_policy_with_args(self, allow_list_with_args, mode, return_value):
7705f9996aaSopenharmony_ci        self.set_gen_mode(mode)
7715f9996aaSopenharmony_ci        skip = 0
7725f9996aaSopenharmony_ci        for line in allow_list_with_args:
7735f9996aaSopenharmony_ci            if self.gen_mode == 1 and line == list(allow_list_with_args)[-1]:
7745f9996aaSopenharmony_ci                skip = 2
7755f9996aaSopenharmony_ci            line = line.replace(' ', '')
7765f9996aaSopenharmony_ci            pos = line.find(':')
7775f9996aaSopenharmony_ci            function_name = line[:pos]
7785f9996aaSopenharmony_ci
7795f9996aaSopenharmony_ci            left_line = line[pos + 1:]
7805f9996aaSopenharmony_ci            if not left_line.startswith('if'):
7815f9996aaSopenharmony_ci                continue
7825f9996aaSopenharmony_ci
7835f9996aaSopenharmony_ci            self.bpf_policy += self.parse_args(function_name, left_line[2:], skip)
7845f9996aaSopenharmony_ci
7855f9996aaSopenharmony_ci    def add_load_syscall_nr(self):
7865f9996aaSopenharmony_ci        self.bpf_policy.append(BPF_LOAD.format(0))
7875f9996aaSopenharmony_ci
7885f9996aaSopenharmony_ci    def add_return_value(self, return_value):
7895f9996aaSopenharmony_ci        if return_value[0:len('ERRNO')] == 'ERRNO':
7905f9996aaSopenharmony_ci            self.bpf_policy.append(BPF_RET_VALUE.format(return_value.replace('ERRNO', ret_str_to_bpf.get('ERRNO'))))
7915f9996aaSopenharmony_ci        else:
7925f9996aaSopenharmony_ci            self.bpf_policy.append(BPF_RET_VALUE.format(ret_str_to_bpf.get(return_value)))
7935f9996aaSopenharmony_ci
7945f9996aaSopenharmony_ci    def add_validate_arch(self, arches, skip_step):
7955f9996aaSopenharmony_ci        if not self.bpf_policy or not self.flag:
7965f9996aaSopenharmony_ci            return
7975f9996aaSopenharmony_ci        bpf_policy = []
7985f9996aaSopenharmony_ci        #load arch
7995f9996aaSopenharmony_ci        bpf_policy.append(BPF_LOAD.format(4))
8005f9996aaSopenharmony_ci        if len(arches) == 2:
8015f9996aaSopenharmony_ci            bpf_policy.append(BPF_JEQ.format(architecture_to_number.get(arches[0]), 3, 0))
8025f9996aaSopenharmony_ci            bpf_policy.append(BPF_JEQ.format(architecture_to_number.get(arches[1]), 0, 1))
8035f9996aaSopenharmony_ci            bpf_policy.append(BPF_JA.format(skip_step))
8045f9996aaSopenharmony_ci            bpf_policy.append(BPF_RET_VALUE.format('SECCOMP_RET_TRAP'))
8055f9996aaSopenharmony_ci        elif len(arches) == 1:
8065f9996aaSopenharmony_ci            bpf_policy.append(BPF_JEQ.format(architecture_to_number.get(arches[0]), 1, 0))
8075f9996aaSopenharmony_ci            bpf_policy.append(BPF_RET_VALUE.format('SECCOMP_RET_TRAP'))
8085f9996aaSopenharmony_ci        else:
8095f9996aaSopenharmony_ci            self.bpf_policy = []
8105f9996aaSopenharmony_ci
8115f9996aaSopenharmony_ci        self.bpf_policy = bpf_policy + self.bpf_policy
8125f9996aaSopenharmony_ci
8135f9996aaSopenharmony_ci
8145f9996aaSopenharmony_ciclass AllowBlockList:
8155f9996aaSopenharmony_ci    def __init__(self, filter_name, arch, function_name_nr_table):
8165f9996aaSopenharmony_ci        self.is_valid = False
8175f9996aaSopenharmony_ci        self.arch = arch
8185f9996aaSopenharmony_ci        self.filter_name = filter_name
8195f9996aaSopenharmony_ci        self.reduced_block_list = set()
8205f9996aaSopenharmony_ci        self.function_name_nr_table = function_name_nr_table
8215f9996aaSopenharmony_ci        self.value_function = {
8225f9996aaSopenharmony_ci            'privilegedProcessName': self.update_flag,
8235f9996aaSopenharmony_ci            'allowBlockList': self.update_reduced_block_list,
8245f9996aaSopenharmony_ci        }
8255f9996aaSopenharmony_ci
8265f9996aaSopenharmony_ci    def update_flag(self, name):
8275f9996aaSopenharmony_ci        if self.filter_name == name:
8285f9996aaSopenharmony_ci            self.is_valid = True
8295f9996aaSopenharmony_ci        else:
8305f9996aaSopenharmony_ci            self.is_valid = False
8315f9996aaSopenharmony_ci
8325f9996aaSopenharmony_ci    def update_reduced_block_list(self, function_name):
8335f9996aaSopenharmony_ci        if self.is_valid and is_function_name_exist(self.arch, function_name, self.function_name_nr_table):
8345f9996aaSopenharmony_ci            self.reduced_block_list.add(function_name)
8355f9996aaSopenharmony_ci            return True
8365f9996aaSopenharmony_ci        return False
8375f9996aaSopenharmony_ci
8385f9996aaSopenharmony_ci
8395f9996aaSopenharmony_ciclass SeccompPolicyParser:
8405f9996aaSopenharmony_ci    def __init__(self):
8415f9996aaSopenharmony_ci        self.cur_parse_item = ''
8425f9996aaSopenharmony_ci        self.arches = set()
8435f9996aaSopenharmony_ci        self.bpf_generator = GenBpfPolicy()
8445f9996aaSopenharmony_ci        self.seccomp_policy_param = dict()
8455f9996aaSopenharmony_ci        self.reduced_block_list_parm = dict()
8465f9996aaSopenharmony_ci        self.key_process_flag = False
8475f9996aaSopenharmony_ci        self.is_debug = False
8485f9996aaSopenharmony_ci
8495f9996aaSopenharmony_ci    def update_is_debug(self, is_debug):
8505f9996aaSopenharmony_ci        if is_debug == 'false':
8515f9996aaSopenharmony_ci            self.is_debug = False
8525f9996aaSopenharmony_ci        else:
8535f9996aaSopenharmony_ci            self.is_debug = True
8545f9996aaSopenharmony_ci
8555f9996aaSopenharmony_ci    def update_arch(self, target_cpu):
8565f9996aaSopenharmony_ci        if target_cpu == "arm":
8575f9996aaSopenharmony_ci            self.arches.add(target_cpu)
8585f9996aaSopenharmony_ci        elif target_cpu == "arm64":
8595f9996aaSopenharmony_ci            self.arches.add("arm")
8605f9996aaSopenharmony_ci            self.arches.add(target_cpu)
8615f9996aaSopenharmony_ci        elif target_cpu == "riscv64":
8625f9996aaSopenharmony_ci            self.arches.add(target_cpu)
8635f9996aaSopenharmony_ci
8645f9996aaSopenharmony_ci    def update_block_list(self):
8655f9996aaSopenharmony_ci        for arch in supported_architecture:
8665f9996aaSopenharmony_ci            self.seccomp_policy_param.get(arch).blocklist -= self.reduced_block_list_parm.get(arch).reduced_block_list
8675f9996aaSopenharmony_ci
8685f9996aaSopenharmony_ci    def update_parse_item(self, line):
8695f9996aaSopenharmony_ci        item = line[1:]
8705f9996aaSopenharmony_ci        if item in supported_parse_item:
8715f9996aaSopenharmony_ci            self.cur_parse_item = item
8725f9996aaSopenharmony_ci            print_info('start deal with {}'.format(self.cur_parse_item))
8735f9996aaSopenharmony_ci
8745f9996aaSopenharmony_ci    def check_allow_list(self):
8755f9996aaSopenharmony_ci        for arch in self.arches:
8765f9996aaSopenharmony_ci            if not self.seccomp_policy_param.get(arch).check_all_allow_list():
8775f9996aaSopenharmony_ci                self.bpf_generator.set_gen_flag(False)
8785f9996aaSopenharmony_ci
8795f9996aaSopenharmony_ci    def clear_file_syscall_list(self):
8805f9996aaSopenharmony_ci        for arch in self.arches:
8815f9996aaSopenharmony_ci            self.seccomp_policy_param.get(arch).update_final_list()
8825f9996aaSopenharmony_ci        self.cur_parse_item = ''
8835f9996aaSopenharmony_ci        self.cur_arch = ''
8845f9996aaSopenharmony_ci
8855f9996aaSopenharmony_ci    def parse_line(self, line):
8865f9996aaSopenharmony_ci        if not self.cur_parse_item :
8875f9996aaSopenharmony_ci            return
8885f9996aaSopenharmony_ci        line = line.replace(' ', '')
8895f9996aaSopenharmony_ci        pos = line.rfind(';')
8905f9996aaSopenharmony_ci        if pos < 0:
8915f9996aaSopenharmony_ci            for arch in self.arches:
8925f9996aaSopenharmony_ci                if self.key_process_flag:
8935f9996aaSopenharmony_ci                    self.reduced_block_list_parm.get(arch).value_function.get(self.cur_parse_item)(line)
8945f9996aaSopenharmony_ci                else:
8955f9996aaSopenharmony_ci                    self.seccomp_policy_param.get(arch).value_function.get(self.cur_parse_item)(line)
8965f9996aaSopenharmony_ci        else:
8975f9996aaSopenharmony_ci            arches = line[pos + 1:].split(',')
8985f9996aaSopenharmony_ci            if arches[0] == 'all':
8995f9996aaSopenharmony_ci                arches = supported_architecture
9005f9996aaSopenharmony_ci            for arch in arches:
9015f9996aaSopenharmony_ci                if self.key_process_flag:
9025f9996aaSopenharmony_ci                    self.reduced_block_list_parm.get(arch).value_function.get(self.cur_parse_item)(line[:pos])
9035f9996aaSopenharmony_ci                else:
9045f9996aaSopenharmony_ci                    self.seccomp_policy_param.get(arch).value_function.get(self.cur_parse_item)(line[:pos])
9055f9996aaSopenharmony_ci
9065f9996aaSopenharmony_ci    def parse_open_file(self, fp):
9075f9996aaSopenharmony_ci        for line in fp:
9085f9996aaSopenharmony_ci            line = line.strip()
9095f9996aaSopenharmony_ci            if not line:
9105f9996aaSopenharmony_ci                continue
9115f9996aaSopenharmony_ci            if line[0] == '#':
9125f9996aaSopenharmony_ci                continue
9135f9996aaSopenharmony_ci            if line[0] == '@':
9145f9996aaSopenharmony_ci                self.update_parse_item(line)
9155f9996aaSopenharmony_ci                continue
9165f9996aaSopenharmony_ci            if line[0] != '@' and self.cur_parse_item == '':
9175f9996aaSopenharmony_ci                continue
9185f9996aaSopenharmony_ci            self.parse_line(line)
9195f9996aaSopenharmony_ci        self.clear_file_syscall_list()
9205f9996aaSopenharmony_ci        self.check_allow_list()
9215f9996aaSopenharmony_ci
9225f9996aaSopenharmony_ci    def parse_file(self, file_path):
9235f9996aaSopenharmony_ci        with open(file_path) as fp:
9245f9996aaSopenharmony_ci            self.parse_open_file(fp)
9255f9996aaSopenharmony_ci
9265f9996aaSopenharmony_ci    def gen_seccomp_policy_of_arch(self, arch):
9275f9996aaSopenharmony_ci        cur_policy_param = self.seccomp_policy_param.get(arch)
9285f9996aaSopenharmony_ci
9295f9996aaSopenharmony_ci        if not cur_policy_param.return_value:
9305f9996aaSopenharmony_ci            raise ValidateError('return value not defined')
9315f9996aaSopenharmony_ci
9325f9996aaSopenharmony_ci        #get final allow_list
9335f9996aaSopenharmony_ci        syscall_nr_allow_list = function_name_to_nr(cur_policy_param.final_allow_list, \
9345f9996aaSopenharmony_ci                                                    cur_policy_param.function_name_nr_table) \
9355f9996aaSopenharmony_ci                                                    | cur_policy_param.self_define_syscall
9365f9996aaSopenharmony_ci        syscall_nr_priority = function_name_to_nr(cur_policy_param.final_priority, \
9375f9996aaSopenharmony_ci                                                  cur_policy_param.function_name_nr_table)
9385f9996aaSopenharmony_ci        self.bpf_generator.update_arch(arch)
9395f9996aaSopenharmony_ci
9405f9996aaSopenharmony_ci        #load syscall nr
9415f9996aaSopenharmony_ci        if syscall_nr_allow_list or syscall_nr_priority:
9425f9996aaSopenharmony_ci            self.bpf_generator.add_load_syscall_nr()
9435f9996aaSopenharmony_ci        self.bpf_generator.gen_bpf_policy(syscall_nr_priority)
9445f9996aaSopenharmony_ci        self.bpf_generator.gen_bpf_policy_with_args(sorted(list(cur_policy_param.final_priority_with_args)), \
9455f9996aaSopenharmony_ci            cur_policy_param.mode, cur_policy_param.return_value)
9465f9996aaSopenharmony_ci        self.bpf_generator.gen_bpf_policy(syscall_nr_allow_list)
9475f9996aaSopenharmony_ci        self.bpf_generator.gen_bpf_policy_with_args(sorted(list(cur_policy_param.final_allow_list_with_args)), \
9485f9996aaSopenharmony_ci            cur_policy_param.mode, cur_policy_param.return_value)
9495f9996aaSopenharmony_ci
9505f9996aaSopenharmony_ci        self.bpf_generator.add_return_value(cur_policy_param.return_value)
9515f9996aaSopenharmony_ci        for line in self.bpf_generator.bpf_policy:
9525f9996aaSopenharmony_ci            if 'SECCOMP_RET_LOG' in line and self.is_debug == False:
9535f9996aaSopenharmony_ci                raise ValidateError("LOG return value is not allowed in user mode")
9545f9996aaSopenharmony_ci
9555f9996aaSopenharmony_ci    def gen_seccomp_policy(self):
9565f9996aaSopenharmony_ci        arches = sorted(list(self.arches))
9575f9996aaSopenharmony_ci        if not arches:
9585f9996aaSopenharmony_ci            return
9595f9996aaSopenharmony_ci        self.gen_seccomp_policy_of_arch(arches[0])
9605f9996aaSopenharmony_ci        skip_step = len(self.bpf_generator.bpf_policy) + 1
9615f9996aaSopenharmony_ci        if len(arches) == 2:
9625f9996aaSopenharmony_ci            self.gen_seccomp_policy_of_arch(arches[1])
9635f9996aaSopenharmony_ci
9645f9996aaSopenharmony_ci        self.bpf_generator.add_validate_arch(arches, skip_step)
9655f9996aaSopenharmony_ci
9665f9996aaSopenharmony_ci    def gen_output_file(self, args):
9675f9996aaSopenharmony_ci        if not self.bpf_generator.bpf_policy:
9685f9996aaSopenharmony_ci            raise ValidateError("bpf_policy is empty!")
9695f9996aaSopenharmony_ci
9705f9996aaSopenharmony_ci        header = textwrap.dedent('''\
9715f9996aaSopenharmony_ci
9725f9996aaSopenharmony_ci            #include <linux/filter.h>
9735f9996aaSopenharmony_ci            #include <stddef.h>
9745f9996aaSopenharmony_ci            #include <linux/seccomp.h>
9755f9996aaSopenharmony_ci            #include <linux/audit.h>
9765f9996aaSopenharmony_ci            ''')
9775f9996aaSopenharmony_ci        extra_header = set()
9785f9996aaSopenharmony_ci        for arch in self.arches:
9795f9996aaSopenharmony_ci            extra_header |= self.seccomp_policy_param.get(arch).head_files
9805f9996aaSopenharmony_ci        extra_header_list = ['#include ' + i for i in sorted(list(extra_header))]
9815f9996aaSopenharmony_ci        filter_name = 'g_' + args.filter_name + 'SeccompFilter'
9825f9996aaSopenharmony_ci
9835f9996aaSopenharmony_ci        array_name = textwrap.dedent('''
9845f9996aaSopenharmony_ci
9855f9996aaSopenharmony_ci            const struct sock_filter {}[] = {{
9865f9996aaSopenharmony_ci            ''').format(filter_name)
9875f9996aaSopenharmony_ci
9885f9996aaSopenharmony_ci        footer = textwrap.dedent('''\
9895f9996aaSopenharmony_ci
9905f9996aaSopenharmony_ci            }};
9915f9996aaSopenharmony_ci
9925f9996aaSopenharmony_ci            const size_t {} = sizeof({}) / sizeof(struct sock_filter);
9935f9996aaSopenharmony_ci            ''').format(filter_name + 'Size', filter_name)
9945f9996aaSopenharmony_ci
9955f9996aaSopenharmony_ci        content = header + '\n'.join(extra_header_list) + array_name + \
9965f9996aaSopenharmony_ci            '    ' + '\n    '.join(self.bpf_generator.bpf_policy) + footer
9975f9996aaSopenharmony_ci
9985f9996aaSopenharmony_ci        flags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC
9995f9996aaSopenharmony_ci        modes = stat.S_IWUSR | stat.S_IRUSR | stat.S_IWGRP | stat.S_IRGRP
10005f9996aaSopenharmony_ci        with os.fdopen(os.open(args.dst_file, flags, modes), 'w') as output_file:
10015f9996aaSopenharmony_ci            output_file.write(content)
10025f9996aaSopenharmony_ci
10035f9996aaSopenharmony_ci    def gen_seccomp_policy_code(self, args):
10045f9996aaSopenharmony_ci        if args.target_cpu not in supported_architecture:
10055f9996aaSopenharmony_ci            raise ValidateError('target cpu not supported')
10065f9996aaSopenharmony_ci        function_name_nr_table_dict = {}
10075f9996aaSopenharmony_ci        for file_name in args.src_files:
10085f9996aaSopenharmony_ci            file_name_tmp = file_name.split('/')[-1]
10095f9996aaSopenharmony_ci            if not file_name_tmp.lower().startswith('libsyscall_to_nr_'):
10105f9996aaSopenharmony_ci                continue
10115f9996aaSopenharmony_ci            function_name_nr_table_dict = gen_syscall_nr_table(file_name, function_name_nr_table_dict)
10125f9996aaSopenharmony_ci
10135f9996aaSopenharmony_ci
10145f9996aaSopenharmony_ci        for arch in supported_architecture:
10155f9996aaSopenharmony_ci            self.seccomp_policy_param.update(
10165f9996aaSopenharmony_ci                {arch: SeccompPolicyParam(arch, function_name_nr_table_dict.get(arch), args.is_debug)})
10175f9996aaSopenharmony_ci            self.reduced_block_list_parm.update(
10185f9996aaSopenharmony_ci                {arch: AllowBlockList(args.filter_name, arch, function_name_nr_table_dict.get(arch))})
10195f9996aaSopenharmony_ci
10205f9996aaSopenharmony_ci        self.bpf_generator.update_function_name_nr_table(function_name_nr_table_dict)
10215f9996aaSopenharmony_ci
10225f9996aaSopenharmony_ci        self.update_arch(args.target_cpu)
10235f9996aaSopenharmony_ci        self.update_is_debug(args.is_debug)
10245f9996aaSopenharmony_ci
10255f9996aaSopenharmony_ci        for file_name in args.blocklist_file:
10265f9996aaSopenharmony_ci            if file_name.lower().endswith('blocklist.seccomp.policy'):
10275f9996aaSopenharmony_ci                self.parse_file(file_name)
10285f9996aaSopenharmony_ci
10295f9996aaSopenharmony_ci        for file_name in args.keyprocess_file:
10305f9996aaSopenharmony_ci            if file_name.lower().endswith('privileged_process.seccomp.policy'):
10315f9996aaSopenharmony_ci                self.key_process_flag = True
10325f9996aaSopenharmony_ci                self.parse_file(file_name)
10335f9996aaSopenharmony_ci                self.key_process_flag = False
10345f9996aaSopenharmony_ci
10355f9996aaSopenharmony_ci        self.update_block_list()
10365f9996aaSopenharmony_ci
10375f9996aaSopenharmony_ci        for file_name in args.src_files:
10385f9996aaSopenharmony_ci            if file_name.lower().endswith('.policy'):
10395f9996aaSopenharmony_ci                self.parse_file(file_name)
10405f9996aaSopenharmony_ci
10415f9996aaSopenharmony_ci        if self.bpf_generator.get_gen_flag():
10425f9996aaSopenharmony_ci            self.gen_seccomp_policy()
10435f9996aaSopenharmony_ci
10445f9996aaSopenharmony_ci        if self.bpf_generator.get_gen_flag():
10455f9996aaSopenharmony_ci            self.gen_output_file(args)
10465f9996aaSopenharmony_ci
10475f9996aaSopenharmony_ci
10485f9996aaSopenharmony_cidef main():
10495f9996aaSopenharmony_ci    parser = argparse.ArgumentParser(
10505f9996aaSopenharmony_ci      description='Generates a seccomp-bpf policy')
10515f9996aaSopenharmony_ci    parser.add_argument('--src-files', type=str, action='append',
10525f9996aaSopenharmony_ci                        help=('The input files\n'))
10535f9996aaSopenharmony_ci
10545f9996aaSopenharmony_ci    parser.add_argument('--blocklist-file', type=str, action='append',
10555f9996aaSopenharmony_ci                        help=('input basic blocklist file(s)\n'))
10565f9996aaSopenharmony_ci
10575f9996aaSopenharmony_ci    parser.add_argument('--keyprocess-file', type=str, action='append',
10585f9996aaSopenharmony_ci                        help=('input key process file(s)\n'))
10595f9996aaSopenharmony_ci
10605f9996aaSopenharmony_ci    parser.add_argument('--dst-file',
10615f9996aaSopenharmony_ci                        help='The output path for the policy files')
10625f9996aaSopenharmony_ci
10635f9996aaSopenharmony_ci    parser.add_argument('--filter-name', type=str,
10645f9996aaSopenharmony_ci                        help='Name of seccomp bpf array generated by this script')
10655f9996aaSopenharmony_ci
10665f9996aaSopenharmony_ci    parser.add_argument('--target-cpu', type=str,
10675f9996aaSopenharmony_ci                        help=('please input target cpu arm or arm64\n'))
10685f9996aaSopenharmony_ci
10695f9996aaSopenharmony_ci    parser.add_argument('--is-debug', type=str,
10705f9996aaSopenharmony_ci                        help=('please input is_debug true or false\n'))
10715f9996aaSopenharmony_ci
10725f9996aaSopenharmony_ci    args = parser.parse_args()
10735f9996aaSopenharmony_ci
10745f9996aaSopenharmony_ci    generator = SeccompPolicyParser()
10755f9996aaSopenharmony_ci    generator.gen_seccomp_policy_code(args)
10765f9996aaSopenharmony_ci
10775f9996aaSopenharmony_ci
10785f9996aaSopenharmony_ciif __name__ == '__main__':
10795f9996aaSopenharmony_ci    sys.exit(main())
1080