diff options
author | Aashay Shringarpure <aashay@google.com> | 2021-02-05 21:44:19 +0000 |
---|---|---|
committer | Treehugger Robot <treehugger-gerrit@google.com> | 2021-02-22 22:41:50 +0000 |
commit | 0026947253fe902a31b3323da12de386d7f64d71 (patch) | |
tree | 8c5fe8b3477bd9286895b5972e2a0da7124bbaf9 /tools/generate_seccomp_policy.py | |
parent | 39bb48dbefd109b3490253724fa11ce705b7334f (diff) | |
download | minijail-0026947253fe902a31b3323da12de386d7f64d71.tar.gz |
generate_seccomp_policy: Workaround for private ARM syscalls
strace omits the ARM_ prefix on these. Add a permanent workaround to
massage the syscall name in these cases.
These syscalls are also not supported by audit-userspace upstream
leading to 'unknown_syscall's in policy. Add a temporary workaround
to look these up in the same local table.
Test: Used strace and audit on a toy program that calls these syscalls.
Test: Manually verified generated policy in each case.
Bug: chromium:1172449
Bug: b:178654555
Change-Id: I419472dfc17290d88db6073f0cb190b1a6fcf1fc
Diffstat (limited to 'tools/generate_seccomp_policy.py')
-rwxr-xr-x | tools/generate_seccomp_policy.py | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/tools/generate_seccomp_policy.py b/tools/generate_seccomp_policy.py index 35f5154..3654123 100755 --- a/tools/generate_seccomp_policy.py +++ b/tools/generate_seccomp_policy.py @@ -62,6 +62,16 @@ SOCKETCALLS = { 'setsockopt', 'shutdown', 'socket', 'socketpair', } +# List of private ARM syscalls. These can be found in any ARM specific unistd.h +# such as Linux's arch/arm/include/uapi/asm/unistd.h. +PRIVATE_ARM_SYSCALLS = { + 983041: 'ARM_breakpoint', + 983042: 'ARM_cacheflush', + 983043: 'ARM_usr26', + 983044: 'ARM_usr32', + 983045: 'ARM_set_tls', +} + ArgInspectionEntry = collections.namedtuple('ArgInspectionEntry', ('arg_index', 'value_set')) @@ -171,6 +181,13 @@ def parse_trace_file(trace_filename, syscalls, arg_inspection): if uses_socketcall and syscall in SOCKETCALLS: syscall = 'socketcall' + # strace omits the 'ARM_' prefix on all private ARM syscalls. Add + # it manually here as a workaround. These syscalls are exclusive + # to ARM so we don't need to predicate this on a trace_filename + # based heuristic for the arch. + if f'ARM_{syscall}' in PRIVATE_ARM_SYSCALLS.values(): + syscall = f'ARM_{syscall}' + syscalls[syscall] += 1 args = [arg.strip() for arg in args.split(',')] @@ -183,6 +200,8 @@ def parse_trace_file(trace_filename, syscalls, arg_inspection): def parse_audit_log(audit_log, audit_comm, syscalls, arg_inspection): """Parses one audit.log file generated by the Linux audit subsystem.""" + unknown_syscall_re = re.compile(r'unknown-syscall\((?P<syscall_num>\d+)\)') + au = auparse.AuParser(auparse.AUSOURCE_FILE, audit_log) # Quick validity check for whether this parses as a valid audit log. The # first event should have at least one record. @@ -232,6 +251,15 @@ def parse_audit_log(audit_log, audit_comm, syscalls, arg_inspection): # of integers. E.g '16' -> 'ioctl'. syscall = au.interpret_field() + # TODO(crbug/1172449): Add these syscalls to upstream + # audit-userspace and remove this workaround. + # This is redundant but safe for non-ARM architectures due to the + # disjoint set of private syscall numbers. + match = unknown_syscall_re.match(syscall) + if match: + syscall_num = int(match.group('syscall_num')) + syscall = PRIVATE_ARM_SYSCALLS.get(syscall_num, syscall) + if ((syscall in arg_inspection and event_type == 'SECCOMP') or (syscall not in arg_inspection and event_type == 'SYSCALL')): # Skip SECCOMP records for syscalls that require argument |