github.com/opencontainers/runc@v1.2.0-rc.1.0.20240520010911-492dc558cdd6/tests/integration/testdata/seccomp_syscall_test1.c (about) 1 #define _GNU_SOURCE 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <unistd.h> 5 #include <assert.h> 6 #include <errno.h> 7 #include <fcntl.h> 8 #include <sched.h> 9 10 #include <sys/types.h> 11 #include <sys/socket.h> 12 #include <sys/syscall.h> 13 14 static int exit_code = 0; 15 16 /* 17 * We need raw wrappers around each syscall so that glibc won't rewrite the 18 * errno value when it is returned from the seccomp filter (glibc has a habit 19 * of hiding -ENOSYS if possible -- which counters what we're trying to test). 20 */ 21 #define raw(name, ...) \ 22 syscall(SYS_ ## name, ##__VA_ARGS__) 23 24 #define syscall_assert(sval, rval) \ 25 do { \ 26 int L = (sval), R = (rval); \ 27 if (L < 0) \ 28 L = -errno; \ 29 if (L != R) { \ 30 printf("syscall_assert(%s == %s) failed: %d != %d\n", #sval, #rval, L, R); \ 31 exit_code = 32; \ 32 } \ 33 } while (0) 34 35 int main(void) 36 { 37 // Basic permitted syscalls. 38 syscall_assert(write(-1, NULL, 0), -EBADF); 39 40 // Basic syscall with masked rules. 41 syscall_assert(raw(socket, AF_UNIX, SOCK_STREAM, 0x000), 3); 42 syscall_assert(raw(socket, AF_UNIX, SOCK_STREAM, 0x0FF), -EPROTONOSUPPORT); 43 syscall_assert(raw(socket, AF_UNIX, SOCK_STREAM, 0x001), 4); 44 syscall_assert(raw(socket, AF_UNIX, SOCK_STREAM, 0x100), -EPERM); 45 syscall_assert(raw(socket, AF_UNIX, SOCK_STREAM, 0xC00), -EPERM); 46 47 // Multiple arguments with OR rules. 48 syscall_assert(raw(process_vm_readv, 100, NULL, 0, NULL, 0, ~0), -EINVAL); 49 syscall_assert(raw(process_vm_readv, 9001, NULL, 0, NULL, 0, ~0), -EINVAL); 50 syscall_assert(raw(process_vm_readv, 0, NULL, 0, NULL, 0, ~0), -EPERM); 51 syscall_assert(raw(process_vm_readv, 0, NULL, 0, NULL, 0, ~0), -EPERM); 52 53 // Multiple arguments with OR rules -- rule is ERRNO(-ENOANO). 54 syscall_assert(raw(process_vm_writev, 1337, NULL, 0, NULL, 0, ~0), -ENOANO); 55 syscall_assert(raw(process_vm_writev, 2020, NULL, 0, NULL, 0, ~0), -ENOANO); 56 syscall_assert(raw(process_vm_writev, 0, NULL, 0, NULL, 0, ~0), -EPERM); 57 syscall_assert(raw(process_vm_writev, 0, NULL, 0, NULL, 0, ~0), -EPERM); 58 59 // Multiple arguments with AND rules. 60 syscall_assert(raw(ftruncate, 123456789, 1337), -EBADF); 61 syscall_assert(raw(ftruncate, 123456789, 0), -EPERM); 62 syscall_assert(raw(ftruncate, 500, 1337), -EPERM); 63 syscall_assert(raw(ftruncate, 500, 500), -EPERM); 64 65 // Multiple rules for the same syscall. 66 syscall_assert(raw(dup3, 0, -100, 0xFFFF), -EPERM); 67 syscall_assert(raw(dup3, 1, -100, 0xFFFF), -EINVAL); 68 syscall_assert(raw(dup3, 2, -100, 0xFFFF), -EPERM); 69 syscall_assert(raw(dup3, 3, -100, 0xFFFF), -EINVAL); 70 71 // Explicitly denied syscalls (those in Linux 3.0) get -EPERM. 72 syscall_assert(raw(unshare, 0), -EPERM); 73 syscall_assert(raw(setns, 0, 0), -EPERM); 74 75 // Out-of-bounds fake syscall. 76 syscall_assert(syscall(1000, 0xDEADBEEF, 0xCAFEFEED, 0x1337), -ENOSYS); 77 78 return exit_code; 79 }