/** * Check to see if the seccomp() syscall is supported * * This function attempts to see if the system supports the seccomp() syscall. * Unfortunately, there are a few reasons why this check may fail, including * a previously loaded seccomp filter, so it is hard to say for certain. * Return one if the syscall is supported, zero otherwise. * */ int sys_chk_seccomp_syscall(void) { int rc; int nr_seccomp; /* NOTE: it is reasonably safe to assume that we should be able to call * seccomp() when the caller first starts, but we can't rely on * it later so we need to cache our findings for use later */ if (_support_seccomp_syscall >= 0) return _support_seccomp_syscall; #if SYSCALL_WHITELIST_ENABLE /* architecture whitelist */ switch (arch_def_native->token) { case SCMP_ARCH_X86_64: case SCMP_ARCH_ARM: case SCMP_ARCH_AARCH64: case SCMP_ARCH_PPC64: case SCMP_ARCH_PPC64LE: case SCMP_ARCH_S390: case SCMP_ARCH_S390X: break; default: goto unsupported; } #endif nr_seccomp = arch_syscall_resolve_name(arch_def_native, "seccomp"); if (nr_seccomp < 0) goto unsupported; /* this is an invalid call because the second argument is non-zero, but * depending on the errno value of ENOSYS or EINVAL we can guess if the * seccomp() syscal is supported or not */ rc = syscall(nr_seccomp, SECCOMP_SET_MODE_STRICT, 1, NULL); if (rc < 0 && errno == EINVAL) goto supported; unsupported: _support_seccomp_syscall = 0; return 0; supported: _nr_seccomp = nr_seccomp; _support_seccomp_syscall = 1; return 1; }
/** * main */ int main(int argc, char *argv[]) { int opt; const struct arch_def *arch = arch_def_native; int offset = 0; int iter; int sys_num; const char *sys_name; /* parse the command line */ while ((opt = getopt(argc, argv, "a:o:h")) > 0) { switch (opt) { case 'a': arch = arch_def_lookup_name(optarg); if (arch == 0) exit_usage(argv[0]); break; case 'o': offset = atoi(optarg); break; case 'h': default: /* usage information */ exit_usage(argv[0]); } } iter = 0; do { switch (arch->token) { case SCMP_ARCH_X86: sys_name = x86_syscall_iterate_name(iter); break; case SCMP_ARCH_X86_64: sys_name = x86_64_syscall_iterate_name(iter); break; case SCMP_ARCH_X32: sys_name = x32_syscall_iterate_name(iter); break; case SCMP_ARCH_ARM: sys_name = arm_syscall_iterate_name(iter); break; case SCMP_ARCH_MIPS: case SCMP_ARCH_MIPSEL: sys_name = mips_syscall_iterate_name(iter); break; case SCMP_ARCH_MIPS64: case SCMP_ARCH_MIPSEL64: sys_name = mips64_syscall_iterate_name(iter); break; case SCMP_ARCH_MIPS64N32: case SCMP_ARCH_MIPSEL64N32: sys_name = mips64n32_syscall_iterate_name(iter); break; case SCMP_ARCH_AARCH64: sys_name = aarch64_syscall_iterate_name(iter); break; default: /* invalid arch */ exit_usage(argv[0]); } if (sys_name != NULL) { sys_num = arch_syscall_resolve_name(arch, sys_name); if (offset > 0 && sys_num > 0) sys_num -= offset; /* output the results */ printf("%s\t%d\n", sys_name, sys_num); /* next */ iter++; } } while (sys_name != NULL); return 0; }