1*8d67ca89SAndroid Build Coastguard Worker#!/usr/bin/env python3 2*8d67ca89SAndroid Build Coastguard Worker 3*8d67ca89SAndroid Build Coastguard Workerimport argparse 4*8d67ca89SAndroid Build Coastguard Workerimport logging 5*8d67ca89SAndroid Build Coastguard Workerimport operator 6*8d67ca89SAndroid Build Coastguard Workerimport os 7*8d67ca89SAndroid Build Coastguard Workerimport re 8*8d67ca89SAndroid Build Coastguard Workerimport sys 9*8d67ca89SAndroid Build Coastguard Workerimport textwrap 10*8d67ca89SAndroid Build Coastguard Worker 11*8d67ca89SAndroid Build Coastguard Workerfrom gensyscalls import SysCallsTxtParser 12*8d67ca89SAndroid Build Coastguard Worker 13*8d67ca89SAndroid Build Coastguard Worker 14*8d67ca89SAndroid Build Coastguard WorkerBPF_JGE = "BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, {0}, {1}, {2})" 15*8d67ca89SAndroid Build Coastguard WorkerBPF_JEQ = "BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, {0}, {1}, {2})" 16*8d67ca89SAndroid Build Coastguard WorkerBPF_ALLOW = "BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW)" 17*8d67ca89SAndroid Build Coastguard Worker 18*8d67ca89SAndroid Build Coastguard Worker 19*8d67ca89SAndroid Build Coastguard Workerclass SyscallRange: 20*8d67ca89SAndroid Build Coastguard Worker def __init__(self, name, value): 21*8d67ca89SAndroid Build Coastguard Worker self.names = [name] 22*8d67ca89SAndroid Build Coastguard Worker self.begin = value 23*8d67ca89SAndroid Build Coastguard Worker self.end = self.begin + 1 24*8d67ca89SAndroid Build Coastguard Worker 25*8d67ca89SAndroid Build Coastguard Worker def __str__(self): 26*8d67ca89SAndroid Build Coastguard Worker return "(%s, %s, %s)" % (self.begin, self.end, self.names) 27*8d67ca89SAndroid Build Coastguard Worker 28*8d67ca89SAndroid Build Coastguard Worker def add(self, name, value): 29*8d67ca89SAndroid Build Coastguard Worker if value != self.end: 30*8d67ca89SAndroid Build Coastguard Worker raise ValueError 31*8d67ca89SAndroid Build Coastguard Worker self.end += 1 32*8d67ca89SAndroid Build Coastguard Worker self.names.append(name) 33*8d67ca89SAndroid Build Coastguard Worker 34*8d67ca89SAndroid Build Coastguard Worker 35*8d67ca89SAndroid Build Coastguard Workerdef load_syscall_names_from_file(file_path, architecture): 36*8d67ca89SAndroid Build Coastguard Worker parser = SysCallsTxtParser() 37*8d67ca89SAndroid Build Coastguard Worker parser.parse_open_file(open(file_path)) 38*8d67ca89SAndroid Build Coastguard Worker return {x["name"] for x in parser.syscalls if x.get(architecture)} 39*8d67ca89SAndroid Build Coastguard Worker 40*8d67ca89SAndroid Build Coastguard Worker 41*8d67ca89SAndroid Build Coastguard Workerdef load_syscall_priorities_from_file(file_path): 42*8d67ca89SAndroid Build Coastguard Worker format_re = re.compile(r'^\s*([A-Za-z_][A-Za-z0-9_]+)\s*$') 43*8d67ca89SAndroid Build Coastguard Worker priorities = [] 44*8d67ca89SAndroid Build Coastguard Worker with open(file_path) as priority_file: 45*8d67ca89SAndroid Build Coastguard Worker for line in priority_file: 46*8d67ca89SAndroid Build Coastguard Worker match = format_re.match(line) 47*8d67ca89SAndroid Build Coastguard Worker if match is None: 48*8d67ca89SAndroid Build Coastguard Worker continue 49*8d67ca89SAndroid Build Coastguard Worker try: 50*8d67ca89SAndroid Build Coastguard Worker name = match.group(1) 51*8d67ca89SAndroid Build Coastguard Worker priorities.append(name) 52*8d67ca89SAndroid Build Coastguard Worker except IndexError: 53*8d67ca89SAndroid Build Coastguard Worker # TODO: This should be impossible becauase it wouldn't have matched? 54*8d67ca89SAndroid Build Coastguard Worker logging.exception('Failed to parse %s from %s', line, file_path) 55*8d67ca89SAndroid Build Coastguard Worker 56*8d67ca89SAndroid Build Coastguard Worker return priorities 57*8d67ca89SAndroid Build Coastguard Worker 58*8d67ca89SAndroid Build Coastguard Worker 59*8d67ca89SAndroid Build Coastguard Workerdef merge_names(base_names, allowlist_names, blocklist_names): 60*8d67ca89SAndroid Build Coastguard Worker if bool(blocklist_names - base_names): 61*8d67ca89SAndroid Build Coastguard Worker raise RuntimeError("blocklist item not in bionic - aborting " + str( 62*8d67ca89SAndroid Build Coastguard Worker blocklist_names - base_names)) 63*8d67ca89SAndroid Build Coastguard Worker 64*8d67ca89SAndroid Build Coastguard Worker return (base_names - blocklist_names) | allowlist_names 65*8d67ca89SAndroid Build Coastguard Worker 66*8d67ca89SAndroid Build Coastguard Worker 67*8d67ca89SAndroid Build Coastguard Workerdef extract_priority_syscalls(syscalls, priorities): 68*8d67ca89SAndroid Build Coastguard Worker # Extract syscalls that are not in the priority list 69*8d67ca89SAndroid Build Coastguard Worker other_syscalls = \ 70*8d67ca89SAndroid Build Coastguard Worker [syscall for syscall in syscalls if syscall[0] not in priorities] 71*8d67ca89SAndroid Build Coastguard Worker # For prioritized syscalls, keep the order in which they appear in th 72*8d67ca89SAndroid Build Coastguard Worker # priority list 73*8d67ca89SAndroid Build Coastguard Worker syscall_dict = {syscall[0]: syscall[1] for syscall in syscalls} 74*8d67ca89SAndroid Build Coastguard Worker priority_syscalls = [] 75*8d67ca89SAndroid Build Coastguard Worker for name in priorities: 76*8d67ca89SAndroid Build Coastguard Worker if name in syscall_dict.keys(): 77*8d67ca89SAndroid Build Coastguard Worker priority_syscalls.append((name, syscall_dict[name])) 78*8d67ca89SAndroid Build Coastguard Worker return priority_syscalls, other_syscalls 79*8d67ca89SAndroid Build Coastguard Worker 80*8d67ca89SAndroid Build Coastguard Worker 81*8d67ca89SAndroid Build Coastguard Workerdef parse_syscall_NRs(names_path): 82*8d67ca89SAndroid Build Coastguard Worker # The input is now the preprocessed source file. This will contain a lot 83*8d67ca89SAndroid Build Coastguard Worker # of junk from the preprocessor, but our lines will be in the format: 84*8d67ca89SAndroid Build Coastguard Worker # 85*8d67ca89SAndroid Build Coastguard Worker # #define __(ARM_)?NR_${NAME} ${VALUE} 86*8d67ca89SAndroid Build Coastguard Worker # 87*8d67ca89SAndroid Build Coastguard Worker # Where ${VALUE} is a preprocessor expression. 88*8d67ca89SAndroid Build Coastguard Worker # 89*8d67ca89SAndroid Build Coastguard Worker # Newer architectures have things like this though: 90*8d67ca89SAndroid Build Coastguard Worker # 91*8d67ca89SAndroid Build Coastguard Worker # #define __NR3264_fcntl 25 92*8d67ca89SAndroid Build Coastguard Worker # #define __NR_fcntl __NR3264_fcntl 93*8d67ca89SAndroid Build Coastguard Worker # 94*8d67ca89SAndroid Build Coastguard Worker # So we need to keep track of the __NR3264_* constants and substitute them. 95*8d67ca89SAndroid Build Coastguard Worker 96*8d67ca89SAndroid Build Coastguard Worker line_re = re.compile(r'^# \d+ ".*".*') 97*8d67ca89SAndroid Build Coastguard Worker undef_re = re.compile(r'^#undef\s.*') 98*8d67ca89SAndroid Build Coastguard Worker define_re = re.compile(r'^\s*#define\s+([A-Za-z0-9_(,)]+)(?:\s+(.+))?\s*$') 99*8d67ca89SAndroid Build Coastguard Worker token_re = re.compile(r'\b[A-Za-z_][A-Za-z0-9_]+\b') 100*8d67ca89SAndroid Build Coastguard Worker constants = {} 101*8d67ca89SAndroid Build Coastguard Worker nr3264s = {} 102*8d67ca89SAndroid Build Coastguard Worker with open(names_path) as f: 103*8d67ca89SAndroid Build Coastguard Worker for line in f: 104*8d67ca89SAndroid Build Coastguard Worker line = line.strip() 105*8d67ca89SAndroid Build Coastguard Worker m = define_re.match(line) 106*8d67ca89SAndroid Build Coastguard Worker if m: 107*8d67ca89SAndroid Build Coastguard Worker name = m.group(1) 108*8d67ca89SAndroid Build Coastguard Worker value = m.group(2) 109*8d67ca89SAndroid Build Coastguard Worker if name.startswith('__NR3264'): 110*8d67ca89SAndroid Build Coastguard Worker nr3264s[name] = value 111*8d67ca89SAndroid Build Coastguard Worker elif name.startswith('__NR_') or name.startswith('__ARM_NR_'): 112*8d67ca89SAndroid Build Coastguard Worker if value in nr3264s: 113*8d67ca89SAndroid Build Coastguard Worker value = nr3264s[value] 114*8d67ca89SAndroid Build Coastguard Worker # eval() takes care of any arithmetic that may be done 115*8d67ca89SAndroid Build Coastguard Worker value = eval(token_re.sub(lambda x: str(constants[x.group(0)]), value)) 116*8d67ca89SAndroid Build Coastguard Worker 117*8d67ca89SAndroid Build Coastguard Worker constants[name] = value 118*8d67ca89SAndroid Build Coastguard Worker else: 119*8d67ca89SAndroid Build Coastguard Worker if not line_re.match(line) and not undef_re.match(line) and line: 120*8d67ca89SAndroid Build Coastguard Worker print('%s: failed to parse line `%s`' % (names_path, line)) 121*8d67ca89SAndroid Build Coastguard Worker sys.exit(1) 122*8d67ca89SAndroid Build Coastguard Worker 123*8d67ca89SAndroid Build Coastguard Worker syscalls = {} 124*8d67ca89SAndroid Build Coastguard Worker for name, value in constants.items(): 125*8d67ca89SAndroid Build Coastguard Worker # Remove the __NR_ prefix. 126*8d67ca89SAndroid Build Coastguard Worker # TODO: why not __ARM_NR too? 127*8d67ca89SAndroid Build Coastguard Worker if name.startswith("__NR_"): 128*8d67ca89SAndroid Build Coastguard Worker name = name[len("__NR_"):] 129*8d67ca89SAndroid Build Coastguard Worker syscalls[name] = value 130*8d67ca89SAndroid Build Coastguard Worker 131*8d67ca89SAndroid Build Coastguard Worker return syscalls 132*8d67ca89SAndroid Build Coastguard Worker 133*8d67ca89SAndroid Build Coastguard Worker 134*8d67ca89SAndroid Build Coastguard Workerdef convert_NRs_to_ranges(syscalls): 135*8d67ca89SAndroid Build Coastguard Worker # Sort the values so we convert to ranges and binary chop 136*8d67ca89SAndroid Build Coastguard Worker syscalls = sorted(syscalls, key=operator.itemgetter(1)) 137*8d67ca89SAndroid Build Coastguard Worker 138*8d67ca89SAndroid Build Coastguard Worker # Turn into a list of ranges. Keep the names for the comments 139*8d67ca89SAndroid Build Coastguard Worker ranges = [] 140*8d67ca89SAndroid Build Coastguard Worker for name, value in syscalls: 141*8d67ca89SAndroid Build Coastguard Worker if not ranges: 142*8d67ca89SAndroid Build Coastguard Worker ranges.append(SyscallRange(name, value)) 143*8d67ca89SAndroid Build Coastguard Worker continue 144*8d67ca89SAndroid Build Coastguard Worker 145*8d67ca89SAndroid Build Coastguard Worker last_range = ranges[-1] 146*8d67ca89SAndroid Build Coastguard Worker if last_range.end == value: 147*8d67ca89SAndroid Build Coastguard Worker last_range.add(name, value) 148*8d67ca89SAndroid Build Coastguard Worker else: 149*8d67ca89SAndroid Build Coastguard Worker ranges.append(SyscallRange(name, value)) 150*8d67ca89SAndroid Build Coastguard Worker return ranges 151*8d67ca89SAndroid Build Coastguard Worker 152*8d67ca89SAndroid Build Coastguard Worker 153*8d67ca89SAndroid Build Coastguard Worker# Converts the sorted ranges of allowed syscalls to a binary tree bpf 154*8d67ca89SAndroid Build Coastguard Worker# For a single range, output a simple jump to {fail} or {allow}. We can't set 155*8d67ca89SAndroid Build Coastguard Worker# the jump ranges yet, since we don't know the size of the filter, so use a 156*8d67ca89SAndroid Build Coastguard Worker# placeholder 157*8d67ca89SAndroid Build Coastguard Worker# For multiple ranges, split into two, convert the two halves and output a jump 158*8d67ca89SAndroid Build Coastguard Worker# to the correct half 159*8d67ca89SAndroid Build Coastguard Workerdef convert_to_intermediate_bpf(ranges): 160*8d67ca89SAndroid Build Coastguard Worker if len(ranges) == 1: 161*8d67ca89SAndroid Build Coastguard Worker # We will replace {fail} and {allow} with appropriate range jumps later 162*8d67ca89SAndroid Build Coastguard Worker return [BPF_JGE.format(ranges[0].end, "{fail}", "{allow}") + 163*8d67ca89SAndroid Build Coastguard Worker ", //" + "|".join(ranges[0].names)] 164*8d67ca89SAndroid Build Coastguard Worker 165*8d67ca89SAndroid Build Coastguard Worker half = (len(ranges) + 1) // 2 166*8d67ca89SAndroid Build Coastguard Worker first = convert_to_intermediate_bpf(ranges[:half]) 167*8d67ca89SAndroid Build Coastguard Worker second = convert_to_intermediate_bpf(ranges[half:]) 168*8d67ca89SAndroid Build Coastguard Worker jump = [BPF_JGE.format(ranges[half].begin, len(first), 0) + ","] 169*8d67ca89SAndroid Build Coastguard Worker return jump + first + second 170*8d67ca89SAndroid Build Coastguard Worker 171*8d67ca89SAndroid Build Coastguard Worker 172*8d67ca89SAndroid Build Coastguard Worker# Converts the prioritized syscalls to a bpf list that is prepended to the 173*8d67ca89SAndroid Build Coastguard Worker# tree generated by convert_to_intermediate_bpf(). If we hit one of these 174*8d67ca89SAndroid Build Coastguard Worker# syscalls, shortcut to the allow statement at the bottom of the tree 175*8d67ca89SAndroid Build Coastguard Worker# immediately 176*8d67ca89SAndroid Build Coastguard Workerdef convert_priority_to_intermediate_bpf(priority_syscalls): 177*8d67ca89SAndroid Build Coastguard Worker result = [] 178*8d67ca89SAndroid Build Coastguard Worker for syscall in priority_syscalls: 179*8d67ca89SAndroid Build Coastguard Worker result.append(BPF_JEQ.format(syscall[1], "{allow}", 0) + 180*8d67ca89SAndroid Build Coastguard Worker ", //" + syscall[0]) 181*8d67ca89SAndroid Build Coastguard Worker return result 182*8d67ca89SAndroid Build Coastguard Worker 183*8d67ca89SAndroid Build Coastguard Worker 184*8d67ca89SAndroid Build Coastguard Workerdef convert_ranges_to_bpf(ranges, priority_syscalls): 185*8d67ca89SAndroid Build Coastguard Worker bpf = convert_priority_to_intermediate_bpf(priority_syscalls) + \ 186*8d67ca89SAndroid Build Coastguard Worker convert_to_intermediate_bpf(ranges) 187*8d67ca89SAndroid Build Coastguard Worker 188*8d67ca89SAndroid Build Coastguard Worker # Now we know the size of the tree, we can substitute the {fail} and {allow} 189*8d67ca89SAndroid Build Coastguard Worker # placeholders 190*8d67ca89SAndroid Build Coastguard Worker for i, statement in enumerate(bpf): 191*8d67ca89SAndroid Build Coastguard Worker # Replace placeholder with 192*8d67ca89SAndroid Build Coastguard Worker # "distance to jump to fail, distance to jump to allow" 193*8d67ca89SAndroid Build Coastguard Worker # We will add a kill statement and an allow statement after the tree 194*8d67ca89SAndroid Build Coastguard Worker # With bpfs jmp 0 means the next statement, so the distance to the end is 195*8d67ca89SAndroid Build Coastguard Worker # len(bpf) - i - 1, which is where we will put the kill statement, and 196*8d67ca89SAndroid Build Coastguard Worker # then the statement after that is the allow statement 197*8d67ca89SAndroid Build Coastguard Worker bpf[i] = statement.format(fail=str(len(bpf) - i), 198*8d67ca89SAndroid Build Coastguard Worker allow=str(len(bpf) - i - 1)) 199*8d67ca89SAndroid Build Coastguard Worker 200*8d67ca89SAndroid Build Coastguard Worker # Add the allow calls at the end. If the syscall is not matched, we will 201*8d67ca89SAndroid Build Coastguard Worker # continue. This allows the user to choose to match further syscalls, and 202*8d67ca89SAndroid Build Coastguard Worker # also to choose the action when we want to block 203*8d67ca89SAndroid Build Coastguard Worker bpf.append(BPF_ALLOW + ",") 204*8d67ca89SAndroid Build Coastguard Worker 205*8d67ca89SAndroid Build Coastguard Worker # Add check that we aren't off the bottom of the syscalls 206*8d67ca89SAndroid Build Coastguard Worker bpf.insert(0, BPF_JGE.format(ranges[0].begin, 0, str(len(bpf))) + ',') 207*8d67ca89SAndroid Build Coastguard Worker return bpf 208*8d67ca89SAndroid Build Coastguard Worker 209*8d67ca89SAndroid Build Coastguard Worker 210*8d67ca89SAndroid Build Coastguard Workerdef convert_bpf_to_output(bpf, architecture, name_modifier): 211*8d67ca89SAndroid Build Coastguard Worker if name_modifier: 212*8d67ca89SAndroid Build Coastguard Worker name_modifier = name_modifier + "_" 213*8d67ca89SAndroid Build Coastguard Worker else: 214*8d67ca89SAndroid Build Coastguard Worker name_modifier = "" 215*8d67ca89SAndroid Build Coastguard Worker header = textwrap.dedent("""\ 216*8d67ca89SAndroid Build Coastguard Worker // File autogenerated by {self_path} - edit at your peril!! 217*8d67ca89SAndroid Build Coastguard Worker 218*8d67ca89SAndroid Build Coastguard Worker #include <linux/filter.h> 219*8d67ca89SAndroid Build Coastguard Worker #include <errno.h> 220*8d67ca89SAndroid Build Coastguard Worker 221*8d67ca89SAndroid Build Coastguard Worker #include "seccomp/seccomp_bpfs.h" 222*8d67ca89SAndroid Build Coastguard Worker const sock_filter {architecture}_{suffix}filter[] = {{ 223*8d67ca89SAndroid Build Coastguard Worker """).format(self_path=os.path.basename(__file__), architecture=architecture, 224*8d67ca89SAndroid Build Coastguard Worker suffix=name_modifier) 225*8d67ca89SAndroid Build Coastguard Worker 226*8d67ca89SAndroid Build Coastguard Worker footer = textwrap.dedent("""\ 227*8d67ca89SAndroid Build Coastguard Worker 228*8d67ca89SAndroid Build Coastguard Worker }}; 229*8d67ca89SAndroid Build Coastguard Worker 230*8d67ca89SAndroid Build Coastguard Worker const size_t {architecture}_{suffix}filter_size = sizeof({architecture}_{suffix}filter) / sizeof(struct sock_filter); 231*8d67ca89SAndroid Build Coastguard Worker """).format(architecture=architecture,suffix=name_modifier) 232*8d67ca89SAndroid Build Coastguard Worker return header + "\n".join(bpf) + footer 233*8d67ca89SAndroid Build Coastguard Worker 234*8d67ca89SAndroid Build Coastguard Worker 235*8d67ca89SAndroid Build Coastguard Workerdef construct_bpf(syscalls, architecture, name_modifier, priorities): 236*8d67ca89SAndroid Build Coastguard Worker priority_syscalls, other_syscalls = \ 237*8d67ca89SAndroid Build Coastguard Worker extract_priority_syscalls(syscalls, priorities) 238*8d67ca89SAndroid Build Coastguard Worker ranges = convert_NRs_to_ranges(other_syscalls) 239*8d67ca89SAndroid Build Coastguard Worker bpf = convert_ranges_to_bpf(ranges, priority_syscalls) 240*8d67ca89SAndroid Build Coastguard Worker return convert_bpf_to_output(bpf, architecture, name_modifier) 241*8d67ca89SAndroid Build Coastguard Worker 242*8d67ca89SAndroid Build Coastguard Worker 243*8d67ca89SAndroid Build Coastguard Workerdef gen_policy(name_modifier, out_dir, base_syscall_file, syscall_files, 244*8d67ca89SAndroid Build Coastguard Worker syscall_NRs, priority_file): 245*8d67ca89SAndroid Build Coastguard Worker for arch in syscall_NRs.keys(): 246*8d67ca89SAndroid Build Coastguard Worker base_names = load_syscall_names_from_file(base_syscall_file, arch) 247*8d67ca89SAndroid Build Coastguard Worker allowlist_names = set() 248*8d67ca89SAndroid Build Coastguard Worker blocklist_names = set() 249*8d67ca89SAndroid Build Coastguard Worker for f in syscall_files: 250*8d67ca89SAndroid Build Coastguard Worker if "blocklist" in f.lower(): 251*8d67ca89SAndroid Build Coastguard Worker blocklist_names |= load_syscall_names_from_file(f, arch) 252*8d67ca89SAndroid Build Coastguard Worker else: 253*8d67ca89SAndroid Build Coastguard Worker allowlist_names |= load_syscall_names_from_file(f, arch) 254*8d67ca89SAndroid Build Coastguard Worker priorities = [] 255*8d67ca89SAndroid Build Coastguard Worker if priority_file: 256*8d67ca89SAndroid Build Coastguard Worker priorities = load_syscall_priorities_from_file(priority_file) 257*8d67ca89SAndroid Build Coastguard Worker 258*8d67ca89SAndroid Build Coastguard Worker allowed_syscalls = [] 259*8d67ca89SAndroid Build Coastguard Worker for name in sorted(merge_names(base_names, allowlist_names, blocklist_names)): 260*8d67ca89SAndroid Build Coastguard Worker try: 261*8d67ca89SAndroid Build Coastguard Worker allowed_syscalls.append((name, syscall_NRs[arch][name])) 262*8d67ca89SAndroid Build Coastguard Worker except: 263*8d67ca89SAndroid Build Coastguard Worker logging.exception("Failed to find %s in %s (%s)", name, arch, syscall_NRs[arch]) 264*8d67ca89SAndroid Build Coastguard Worker raise 265*8d67ca89SAndroid Build Coastguard Worker output = construct_bpf(allowed_syscalls, arch, name_modifier, priorities) 266*8d67ca89SAndroid Build Coastguard Worker 267*8d67ca89SAndroid Build Coastguard Worker # And output policy 268*8d67ca89SAndroid Build Coastguard Worker filename_modifier = "_" + name_modifier if name_modifier else "" 269*8d67ca89SAndroid Build Coastguard Worker output_path = os.path.join(out_dir, 270*8d67ca89SAndroid Build Coastguard Worker "{}{}_policy.cpp".format(arch, filename_modifier)) 271*8d67ca89SAndroid Build Coastguard Worker with open(output_path, "w") as output_file: 272*8d67ca89SAndroid Build Coastguard Worker output_file.write(output) 273*8d67ca89SAndroid Build Coastguard Worker 274*8d67ca89SAndroid Build Coastguard Worker 275*8d67ca89SAndroid Build Coastguard Workerdef main(): 276*8d67ca89SAndroid Build Coastguard Worker parser = argparse.ArgumentParser( 277*8d67ca89SAndroid Build Coastguard Worker description="Generates a seccomp-bpf policy") 278*8d67ca89SAndroid Build Coastguard Worker parser.add_argument("--verbose", "-v", help="Enables verbose logging.") 279*8d67ca89SAndroid Build Coastguard Worker parser.add_argument("--name-modifier", 280*8d67ca89SAndroid Build Coastguard Worker help=("Specifies the name modifier for the policy. " 281*8d67ca89SAndroid Build Coastguard Worker "One of {app,system}.")) 282*8d67ca89SAndroid Build Coastguard Worker parser.add_argument("--out-dir", 283*8d67ca89SAndroid Build Coastguard Worker help="The output directory for the policy files") 284*8d67ca89SAndroid Build Coastguard Worker parser.add_argument("base_file", metavar="base-file", type=str, 285*8d67ca89SAndroid Build Coastguard Worker help="The path of the base syscall list (SYSCALLS.TXT).") 286*8d67ca89SAndroid Build Coastguard Worker parser.add_argument("files", metavar="FILE", type=str, nargs="+", 287*8d67ca89SAndroid Build Coastguard Worker help=("The path of the input files. In order to " 288*8d67ca89SAndroid Build Coastguard Worker "simplify the build rules, it can take any of the " 289*8d67ca89SAndroid Build Coastguard Worker "following files: \n" 290*8d67ca89SAndroid Build Coastguard Worker "* /blocklist.*\\.txt$/ syscall blocklist.\n" 291*8d67ca89SAndroid Build Coastguard Worker "* /allowlist.*\\.txt$/ syscall allowlist.\n" 292*8d67ca89SAndroid Build Coastguard Worker "* /priority.txt$/ priorities for bpf rules.\n" 293*8d67ca89SAndroid Build Coastguard Worker "* otherwise, syscall name-number mapping.\n")) 294*8d67ca89SAndroid Build Coastguard Worker args = parser.parse_args() 295*8d67ca89SAndroid Build Coastguard Worker 296*8d67ca89SAndroid Build Coastguard Worker if args.verbose: 297*8d67ca89SAndroid Build Coastguard Worker logging.basicConfig(level=logging.DEBUG) 298*8d67ca89SAndroid Build Coastguard Worker else: 299*8d67ca89SAndroid Build Coastguard Worker logging.basicConfig(level=logging.INFO) 300*8d67ca89SAndroid Build Coastguard Worker 301*8d67ca89SAndroid Build Coastguard Worker syscall_files = [] 302*8d67ca89SAndroid Build Coastguard Worker priority_file = None 303*8d67ca89SAndroid Build Coastguard Worker syscall_NRs = {} 304*8d67ca89SAndroid Build Coastguard Worker for filename in args.files: 305*8d67ca89SAndroid Build Coastguard Worker if filename.lower().endswith('.txt'): 306*8d67ca89SAndroid Build Coastguard Worker if filename.lower().endswith('priority.txt'): 307*8d67ca89SAndroid Build Coastguard Worker priority_file = filename 308*8d67ca89SAndroid Build Coastguard Worker else: 309*8d67ca89SAndroid Build Coastguard Worker syscall_files.append(filename) 310*8d67ca89SAndroid Build Coastguard Worker else: 311*8d67ca89SAndroid Build Coastguard Worker m = re.search(r"libseccomp_gen_syscall_nrs_([^/]+)", filename) 312*8d67ca89SAndroid Build Coastguard Worker syscall_NRs[m.group(1)] = parse_syscall_NRs(filename) 313*8d67ca89SAndroid Build Coastguard Worker 314*8d67ca89SAndroid Build Coastguard Worker gen_policy(name_modifier=args.name_modifier, out_dir=args.out_dir, 315*8d67ca89SAndroid Build Coastguard Worker syscall_NRs=syscall_NRs, base_syscall_file=args.base_file, 316*8d67ca89SAndroid Build Coastguard Worker syscall_files=syscall_files, priority_file=priority_file) 317*8d67ca89SAndroid Build Coastguard Worker 318*8d67ca89SAndroid Build Coastguard Worker 319*8d67ca89SAndroid Build Coastguard Workerif __name__ == "__main__": 320*8d67ca89SAndroid Build Coastguard Worker main() 321