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  }