aboutsummaryrefslogtreecommitdiff
path: root/tools/generate_seccomp_policy.py
diff options
context:
space:
mode:
authorAashay Shringarpure <aashay@google.com>2021-02-05 21:44:19 +0000
committerTreehugger Robot <treehugger-gerrit@google.com>2021-02-22 22:41:50 +0000
commit0026947253fe902a31b3323da12de386d7f64d71 (patch)
tree8c5fe8b3477bd9286895b5972e2a0da7124bbaf9 /tools/generate_seccomp_policy.py
parent39bb48dbefd109b3490253724fa11ce705b7334f (diff)
downloadminijail-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-xtools/generate_seccomp_policy.py28
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