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