diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index a0069587f4..6d1c4e0528 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -2030,6 +2030,10 @@ RestrictNamespaces=~cgroup net @timer System calls for scheduling operations by time (alarm2, timer_create2, …) + + @known + All system calls defined by the kernel. This list is defined statically in systemd based on a kernel version that was available when this systmed version was released. It will become progressively more out-of-date as the kernel is updated. + diff --git a/meson.build b/meson.build index 5fedbaa117..a42fbc1d6d 100644 --- a/meson.build +++ b/meson.build @@ -1625,8 +1625,15 @@ install_libsystemd_static = static_library( libgcrypt], c_args : libsystemd_c_args + (static_libsystemd_pic ? [] : ['-fno-PIC'])) -# Generate autosuspend rules +############################################################ + +autosuspend_update_sh = find_program('tools/autosuspend-update.sh') +hwdb_update_sh = find_program('tools/hwdb-update.sh') make_autosuspend_rules_py = find_program('tools/make-autosuspend-rules.py') +make_directive_index_py = find_program('tools/make-directive-index.py') +make_man_index_py = find_program('tools/make-man-index.py') +syscall_names_update_sh = find_program('tools/syscall-names-update.sh') +xml_helper_py = find_program('tools/xml_helper.py') ############################################################ @@ -3329,12 +3336,6 @@ run_target( ############################################################ -make_directive_index_py = find_program('tools/make-directive-index.py') -make_man_index_py = find_program('tools/make-man-index.py') -xml_helper_py = find_program('tools/xml_helper.py') -hwdb_update_sh = find_program('tools/hwdb-update.sh') -autosuspend_update_sh = find_program('tools/autosuspend-update.sh') - subdir('sysctl.d') subdir('sysusers.d') subdir('tmpfiles.d') diff --git a/src/nspawn/nspawn-seccomp.c b/src/nspawn/nspawn-seccomp.c index 79110d90d5..1ab50553a9 100644 --- a/src/nspawn/nspawn-seccomp.c +++ b/src/nspawn/nspawn-seccomp.c @@ -21,7 +21,7 @@ #if HAVE_SECCOMP -static int seccomp_add_default_syscall_filter( +static int add_syscall_filters( scmp_filter_ctx ctx, uint32_t arch, uint64_t cap_list_retain, @@ -139,6 +139,7 @@ static int seccomp_add_default_syscall_filter( */ }; + _cleanup_strv_free_ char **added = NULL; char **p; int r; @@ -146,18 +147,37 @@ static int seccomp_add_default_syscall_filter( if (allow_list[i].capability != 0 && (cap_list_retain & (1ULL << allow_list[i].capability)) == 0) continue; - r = seccomp_add_syscall_filter_item(ctx, allow_list[i].name, SCMP_ACT_ALLOW, syscall_deny_list, false); + r = seccomp_add_syscall_filter_item(ctx, + allow_list[i].name, + SCMP_ACT_ALLOW, + syscall_deny_list, + false, + &added); if (r < 0) return log_error_errno(r, "Failed to add syscall filter item %s: %m", allow_list[i].name); } STRV_FOREACH(p, syscall_allow_list) { - r = seccomp_add_syscall_filter_item(ctx, *p, SCMP_ACT_ALLOW, syscall_deny_list, true); + r = seccomp_add_syscall_filter_item(ctx, *p, SCMP_ACT_ALLOW, syscall_deny_list, true, &added); if (r < 0) log_warning_errno(r, "Failed to add rule for system call %s on %s, ignoring: %m", *p, seccomp_arch_to_string(arch)); } + /* The default action is ENOSYS. Respond with EPERM to all other "known" but not allow-listed + * syscalls. */ + r = seccomp_add_syscall_filter_item(ctx, "@known", SCMP_ACT_ERRNO(EPERM), added, true, NULL); + if (r < 0) + log_warning_errno(r, "Failed to add rule for @known set on %s, ignoring: %m", + seccomp_arch_to_string(arch)); + +#if (SCMP_VER_MAJOR == 2 && SCMP_VER_MINOR >= 5) || SCMP_VER_MAJOR > 2 + /* We have a large filter here, so let's turn on the binary tree mode if possible. */ + r = seccomp_attr_set(ctx, SCMP_FLTATR_CTL_OPTIMIZE, 2); + if (r < 0) + return r; +#endif + return 0; } @@ -175,11 +195,13 @@ int setup_seccomp(uint64_t cap_list_retain, char **syscall_allow_list, char **sy log_debug("Applying allow list on architecture: %s", seccomp_arch_to_string(arch)); - r = seccomp_init_for_arch(&seccomp, arch, SCMP_ACT_ERRNO(EPERM)); + /* We install ENOSYS as the default action, but it will only apply to syscalls which are not + * in the @known set, see above. */ + r = seccomp_init_for_arch(&seccomp, arch, SCMP_ACT_ERRNO(ENOSYS)); if (r < 0) return log_error_errno(r, "Failed to allocate seccomp object: %m"); - r = seccomp_add_default_syscall_filter(seccomp, arch, cap_list_retain, syscall_allow_list, syscall_deny_list); + r = add_syscall_filters(seccomp, arch, cap_list_retain, syscall_allow_list, syscall_deny_list); if (r < 0) return r; diff --git a/src/shared/generate-syscall-list.py b/src/shared/generate-syscall-list.py new file mode 100755 index 0000000000..030c3feec4 --- /dev/null +++ b/src/shared/generate-syscall-list.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python3 +import sys +import os + +s390 = 's390' in os.uname().machine +arm = 'arm' in os.uname().machine + +for line in open(sys.argv[1]): + if line.startswith('s390_') and not s390: + continue + if line.startswith('arm_') and not arm: + continue + + print('"{}\\0"'.format(line.strip())) diff --git a/src/shared/meson.build b/src/shared/meson.build index d192a4d8d7..ce3462b3dd 100644 --- a/src/shared/meson.build +++ b/src/shared/meson.build @@ -264,6 +264,16 @@ endif test_tables_h = files('test-tables.h') shared_sources += test_tables_h +generate_syscall_list = find_program('generate-syscall-list.py') +fname = 'syscall-list.h' +syscall_list_h = custom_target( + fname, + input : 'syscall-names.text', + output : fname, + command : [generate_syscall_list, + '@INPUT@'], + capture : true) + if conf.get('HAVE_ACL') == 1 shared_sources += files('acl-util.c') endif @@ -274,6 +284,7 @@ endif if conf.get('HAVE_SECCOMP') == 1 shared_sources += files('seccomp-util.c') + shared_sources += syscall_list_h endif if conf.get('HAVE_LIBIPTC') == 1 @@ -378,3 +389,9 @@ libshared = shared_library( dependencies : libshared_deps, install : true, install_dir : rootlibexecdir) + +############################################################ + +run_target( + 'syscall-names-update', + command : [syscall_names_update_sh, meson.current_source_dir()]) diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c index 1acef04f9c..5b0ab30cff 100644 --- a/src/shared/seccomp-util.c +++ b/src/shared/seccomp-util.c @@ -902,30 +902,50 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = { "timerfd_settime64\0" "times\0" }, + [SYSCALL_FILTER_SET_KNOWN] = { + .name = "@known", + .help = "All known syscalls declared in the kernel", + .value = +#include "syscall-list.h" + }, }; const SyscallFilterSet *syscall_filter_set_find(const char *name) { - unsigned i; - if (isempty(name) || name[0] != '@') return NULL; - for (i = 0; i < _SYSCALL_FILTER_SET_MAX; i++) + for (unsigned i = 0; i < _SYSCALL_FILTER_SET_MAX; i++) if (streq(syscall_filter_sets[i].name, name)) return syscall_filter_sets + i; return NULL; } -static int seccomp_add_syscall_filter_set(scmp_filter_ctx seccomp, const SyscallFilterSet *set, uint32_t action, char **exclude, bool log_missing); +static int add_syscall_filter_set( + scmp_filter_ctx seccomp, + const SyscallFilterSet *set, + uint32_t action, + char **exclude, + bool log_missing, + char ***added); + +int seccomp_add_syscall_filter_item( + scmp_filter_ctx *seccomp, + const char *name, + uint32_t action, + char **exclude, + bool log_missing, + char ***added) { -int seccomp_add_syscall_filter_item(scmp_filter_ctx *seccomp, const char *name, uint32_t action, char **exclude, bool log_missing) { assert(seccomp); assert(name); if (strv_contains(exclude, name)) return 0; + /* Any syscalls that are handled are added to the *added strv. The pointer + * must be either NULL or point to a valid pre-initialized possibly-empty strv. */ + if (name[0] == '@') { const SyscallFilterSet *other; @@ -935,7 +955,7 @@ int seccomp_add_syscall_filter_item(scmp_filter_ctx *seccomp, const char *name, "Filter set %s is not known!", name); - return seccomp_add_syscall_filter_set(seccomp, other, action, exclude, log_missing); + return add_syscall_filter_set(seccomp, other, action, exclude, log_missing, added); } else { int id, r; @@ -959,25 +979,34 @@ int seccomp_add_syscall_filter_item(scmp_filter_ctx *seccomp, const char *name, return r; } + if (added) { + r = strv_extend(added, name); + if (r < 0) + return r; + } + return 0; } } -static int seccomp_add_syscall_filter_set( +static int add_syscall_filter_set( scmp_filter_ctx seccomp, const SyscallFilterSet *set, uint32_t action, char **exclude, - bool log_missing) { + bool log_missing, + char ***added) { const char *sys; int r; + /* Any syscalls that are handled are added to the *added strv. It needs to be initialized. */ + assert(seccomp); assert(set); NULSTR_FOREACH(sys, set->value) { - r = seccomp_add_syscall_filter_item(seccomp, sys, action, exclude, log_missing); + r = seccomp_add_syscall_filter_item(seccomp, sys, action, exclude, log_missing, added); if (r < 0) return r; } @@ -1003,7 +1032,7 @@ int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilter if (r < 0) return r; - r = seccomp_add_syscall_filter_set(seccomp, set, action, NULL, log_missing); + r = add_syscall_filter_set(seccomp, set, action, NULL, log_missing, NULL); if (r < 0) return log_debug_errno(r, "Failed to add filter set: %m"); @@ -1160,7 +1189,6 @@ int seccomp_restrict_namespaces(unsigned long retain) { SECCOMP_FOREACH_LOCAL_ARCH(arch) { _cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL; - unsigned i; log_debug("Operating on architecture: %s", seccomp_arch_to_string(arch)); @@ -1190,7 +1218,7 @@ int seccomp_restrict_namespaces(unsigned long retain) { continue; } - for (i = 0; namespace_flag_map[i].name; i++) { + for (unsigned i = 0; namespace_flag_map[i].name; i++) { unsigned long f; f = namespace_flag_map[i].flag; @@ -1384,7 +1412,7 @@ int seccomp_restrict_address_families(Set *address_families, bool allow_list) { return r; if (allow_list) { - int af, first = 0, last = 0; + int first = 0, last = 0; void *afp; /* If this is an allow list, we first block the address families that are out of @@ -1392,7 +1420,7 @@ int seccomp_restrict_address_families(Set *address_families, bool allow_list) { * highest address family in the set. */ SET_FOREACH(afp, address_families, i) { - af = PTR_TO_INT(afp); + int af = PTR_TO_INT(afp); if (af <= 0 || af >= af_max()) continue; @@ -1446,7 +1474,7 @@ int seccomp_restrict_address_families(Set *address_families, bool allow_list) { } /* Block everything between the first and last entry */ - for (af = 1; af < af_max(); af++) { + for (int af = 1; af < af_max(); af++) { if (set_contains(address_families, INT_TO_PTR(af))) continue; @@ -1473,7 +1501,6 @@ int seccomp_restrict_address_families(Set *address_families, bool allow_list) { * then combined in OR checks. */ SET_FOREACH(af, address_families, i) { - r = seccomp_rule_add_exact( seccomp, SCMP_ACT_ERRNO(EAFNOSUPPORT), diff --git a/src/shared/seccomp-util.h b/src/shared/seccomp-util.h index ef970434c6..b62ee7c448 100644 --- a/src/shared/seccomp-util.h +++ b/src/shared/seccomp-util.h @@ -21,7 +21,7 @@ typedef struct SyscallFilterSet { } SyscallFilterSet; enum { - /* Please leave DEFAULT first, but sort the rest alphabetically */ + /* Please leave DEFAULT first and KNOWN last, but sort the rest alphabetically */ SYSCALL_FILTER_SET_DEFAULT, SYSCALL_FILTER_SET_AIO, SYSCALL_FILTER_SET_BASIC_IO, @@ -50,6 +50,7 @@ enum { SYSCALL_FILTER_SET_SYNC, SYSCALL_FILTER_SET_SYSTEM_SERVICE, SYSCALL_FILTER_SET_TIMER, + SYSCALL_FILTER_SET_KNOWN, _SYSCALL_FILTER_SET_MAX }; @@ -59,7 +60,13 @@ const SyscallFilterSet *syscall_filter_set_find(const char *name); int seccomp_filter_set_add(Hashmap *s, bool b, const SyscallFilterSet *set); -int seccomp_add_syscall_filter_item(scmp_filter_ctx *ctx, const char *name, uint32_t action, char **exclude, bool log_missing); +int seccomp_add_syscall_filter_item( + scmp_filter_ctx *ctx, + const char *name, + uint32_t action, + char **exclude, + bool log_missing, + char ***added); int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilterSet *set, uint32_t action, bool log_missing); int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* set, uint32_t action, bool log_missing); diff --git a/src/shared/syscall-names.text b/src/shared/syscall-names.text new file mode 100644 index 0000000000..40d18a8894 --- /dev/null +++ b/src/shared/syscall-names.text @@ -0,0 +1,597 @@ +_llseek +_newselect +_sysctl +accept +accept4 +access +acct +add_key +adjtimex +alarm +arc_gettls +arc_settls +arc_usr_cmpxchg +arch_prctl +arm_fadvise64_64 +arm_sync_file_range +atomic_barrier +atomic_cmpxchg_32 +bdflush +bfin_spinlock +bind +bpf +brk +cache_sync +cachectl +cacheflush +capget +capset +chdir +chmod +chown +chown32 +chroot +clock_adjtime +clock_adjtime64 +clock_getres +clock_getres_time64 +clock_gettime +clock_gettime64 +clock_nanosleep +clock_nanosleep_time64 +clock_settime +clock_settime64 +clone +clone2 +clone3 +close +close_range +connect +copy_file_range +creat +create_module +delete_module +dipc +dup +dup2 +dup3 +epoll_create +epoll_create1 +epoll_ctl +epoll_ctl_old +epoll_pwait +epoll_wait +epoll_wait_old +eventfd +eventfd2 +exec_with_loader +execv +execve +execveat +exit +exit_group +faccessat +faccessat2 +fadvise64 +fadvise64_64 +fallocate +fanotify_init +fanotify_mark +fchdir +fchmod +fchmodat +fchown +fchown32 +fchownat +fcntl +fcntl64 +fdatasync +fgetxattr +finit_module +flistxattr +flock +fork +fp_udfiex_crtl +fremovexattr +fsconfig +fsetxattr +fsmount +fsopen +fspick +fstat +fstat64 +fstatat64 +fstatfs +fstatfs64 +fsync +ftruncate +ftruncate64 +futex +futex_time64 +futimesat +get_kernel_syms +get_mempolicy +get_robust_list +get_thread_area +getcpu +getcwd +getdents +getdents64 +getdomainname +getdtablesize +getegid +getegid32 +geteuid +geteuid32 +getgid +getgid32 +getgroups +getgroups32 +gethostname +getitimer +getpagesize +getpeername +getpgid +getpgrp +getpid +getpmsg +getppid +getpriority +getrandom +getresgid +getresgid32 +getresuid +getresuid32 +getrlimit +getrusage +getsid +getsockname +getsockopt +gettid +gettimeofday +getuid +getuid32 +getunwind +getxattr +getxgid +getxpid +getxuid +idle +init_module +inotify_add_watch +inotify_init +inotify_init1 +inotify_rm_watch +io_cancel +io_destroy +io_getevents +io_pgetevents +io_pgetevents_time64 +io_setup +io_submit +io_uring_enter +io_uring_register +io_uring_setup +ioctl +ioperm +iopl +ioprio_get +ioprio_set +ipc +kcmp +kern_features +kexec_file_load +kexec_load +keyctl +kill +lchown +lchown32 +lgetxattr +link +linkat +listen +listxattr +llistxattr +lookup_dcookie +lremovexattr +lseek +lsetxattr +lstat +lstat64 +madvise +mbind +membarrier +memfd_create +memory_ordering +migrate_pages +mincore +mkdir +mkdirat +mknod +mknodat +mlock +mlock2 +mlockall +mmap +mmap2 +modify_ldt +mount +move_mount +move_pages +mprotect +mq_getsetattr +mq_notify +mq_open +mq_timedreceive +mq_timedreceive_time64 +mq_timedsend +mq_timedsend_time64 +mq_unlink +mremap +msgctl +msgget +msgrcv +msgsnd +msync +multiplexer +munlock +munlockall +munmap +name_to_handle_at +nanosleep +newfstatat +nfsservctl +ni_syscall +nice +old_adjtimex +old_getpagesize +oldfstat +oldlstat +oldolduname +oldstat +oldumount +olduname +open +open_by_handle_at +open_tree +openat +openat2 +or1k_atomic +osf_adjtime +osf_afs_syscall +osf_alt_plock +osf_alt_setsid +osf_alt_sigpending +osf_asynch_daemon +osf_audcntl +osf_audgen +osf_chflags +osf_execve +osf_exportfs +osf_fchflags +osf_fdatasync +osf_fpathconf +osf_fstat +osf_fstatfs +osf_fstatfs64 +osf_fuser +osf_getaddressconf +osf_getdirentries +osf_getdomainname +osf_getfh +osf_getfsstat +osf_gethostid +osf_getitimer +osf_getlogin +osf_getmnt +osf_getrusage +osf_getsysinfo +osf_gettimeofday +osf_kloadcall +osf_kmodcall +osf_lstat +osf_memcntl +osf_mincore +osf_mount +osf_mremap +osf_msfs_syscall +osf_msleep +osf_mvalid +osf_mwakeup +osf_naccept +osf_nfssvc +osf_ngetpeername +osf_ngetsockname +osf_nrecvfrom +osf_nrecvmsg +osf_nsendmsg +osf_ntp_adjtime +osf_ntp_gettime +osf_old_creat +osf_old_fstat +osf_old_getpgrp +osf_old_killpg +osf_old_lstat +osf_old_open +osf_old_sigaction +osf_old_sigblock +osf_old_sigreturn +osf_old_sigsetmask +osf_old_sigvec +osf_old_stat +osf_old_vadvise +osf_old_vtrace +osf_old_wait +osf_oldquota +osf_pathconf +osf_pid_block +osf_pid_unblock +osf_plock +osf_priocntlset +osf_profil +osf_proplist_syscall +osf_reboot +osf_revoke +osf_sbrk +osf_security +osf_select +osf_set_program_attributes +osf_set_speculative +osf_sethostid +osf_setitimer +osf_setlogin +osf_setsysinfo +osf_settimeofday +osf_shmat +osf_signal +osf_sigprocmask +osf_sigsendset +osf_sigstack +osf_sigwaitprim +osf_sstk +osf_stat +osf_statfs +osf_statfs64 +osf_subsys_info +osf_swapctl +osf_swapon +osf_syscall +osf_sysinfo +osf_table +osf_uadmin +osf_usleep_thread +osf_uswitch +osf_utc_adjtime +osf_utc_gettime +osf_utimes +osf_utsname +osf_wait4 +osf_waitid +pause +pciconfig_iobase +pciconfig_read +pciconfig_write +perf_event_open +perfctr +perfmonctl +personality +pidfd_getfd +pidfd_open +pidfd_send_signal +pipe +pipe2 +pivot_root +pkey_alloc +pkey_free +pkey_mprotect +poll +ppoll +ppoll_time64 +prctl +pread64 +preadv +preadv2 +prlimit64 +process_vm_readv +process_vm_writev +pselect6 +pselect6_time64 +ptrace +pwrite64 +pwritev +pwritev2 +query_module +quotactl +read +readahead +readdir +readlink +readlinkat +readv +reboot +recv +recvfrom +recvmmsg +recvmmsg_time64 +recvmsg +remap_file_pages +removexattr +rename +renameat +renameat2 +request_key +restart_syscall +riscv_flush_icache +rmdir +rseq +rt_sigaction +rt_sigpending +rt_sigprocmask +rt_sigqueueinfo +rt_sigreturn +rt_sigsuspend +rt_sigtimedwait +rt_sigtimedwait_time64 +rt_tgsigqueueinfo +rtas +s390_guarded_storage +s390_pci_mmio_read +s390_pci_mmio_write +s390_runtime_instr +s390_sthyi +sched_get_affinity +sched_get_priority_max +sched_get_priority_min +sched_getaffinity +sched_getattr +sched_getparam +sched_getscheduler +sched_rr_get_interval +sched_rr_get_interval_time64 +sched_set_affinity +sched_setaffinity +sched_setattr +sched_setparam +sched_setscheduler +sched_yield +seccomp +select +semctl +semget +semop +semtimedop +semtimedop_time64 +send +sendfile +sendfile64 +sendmmsg +sendmsg +sendto +set_mempolicy +set_robust_list +set_thread_area +set_tid_address +setdomainname +setfsgid +setfsgid32 +setfsuid +setfsuid32 +setgid +setgid32 +setgroups +setgroups32 +sethae +sethostname +setitimer +setns +setpgid +setpgrp +setpriority +setregid +setregid32 +setresgid +setresgid32 +setresuid +setresuid32 +setreuid +setreuid32 +setrlimit +setsid +setsockopt +settimeofday +setuid +setuid32 +setxattr +sgetmask +shmat +shmctl +shmdt +shmget +shutdown +sigaction +sigaltstack +signal +signalfd +signalfd4 +sigpending +sigprocmask +sigreturn +sigsuspend +socket +socketcall +socketpair +splice +spu_create +spu_run +ssetmask +stat +stat64 +statfs +statfs64 +statx +stime +subpage_prot +swapcontext +swapoff +swapon +switch_endian +symlink +symlinkat +sync +sync_file_range +sync_file_range2 +syncfs +sys_debug_setcontext +syscall +sysfs +sysinfo +syslog +sysmips +tee +tgkill +time +timer_create +timer_delete +timer_getoverrun +timer_gettime +timer_gettime64 +timer_settime +timer_settime64 +timerfd +timerfd_create +timerfd_gettime +timerfd_gettime64 +timerfd_settime +timerfd_settime64 +times +tkill +truncate +truncate64 +udftrap +ugetrlimit +umask +umount +umount2 +uname +unlink +unlinkat +unshare +uselib +userfaultfd +ustat +utime +utimensat +utimensat_time64 +utimes +utimesat +utrap_install +vfork +vhangup +vm86 +vm86old +vmsplice +wait4 +waitid +waitpid +write +writev diff --git a/src/test/test-seccomp.c b/src/test/test-seccomp.c index a39e40cf01..697130e70c 100644 --- a/src/test/test-seccomp.c +++ b/src/test/test-seccomp.c @@ -124,7 +124,9 @@ static void test_filter_sets(void) { int fd, r; /* If we look at the default set (or one that includes it), allow-list instead of deny-list */ - if (IN_SET(i, SYSCALL_FILTER_SET_DEFAULT, SYSCALL_FILTER_SET_SYSTEM_SERVICE)) + if (IN_SET(i, SYSCALL_FILTER_SET_DEFAULT, + SYSCALL_FILTER_SET_SYSTEM_SERVICE, + SYSCALL_FILTER_SET_KNOWN)) r = seccomp_load_syscall_filter_set(SCMP_ACT_ERRNO(EUCLEAN), syscall_filter_sets + i, SCMP_ACT_ALLOW, true); else r = seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + i, SCMP_ACT_ERRNO(EUCLEAN), true); @@ -148,22 +150,25 @@ static void test_filter_sets(void) { } static void test_filter_sets_ordered(void) { - size_t i; - log_info("/* %s */", __func__); /* Ensure "@default" always remains at the beginning of the list */ assert_se(SYSCALL_FILTER_SET_DEFAULT == 0); assert_se(streq(syscall_filter_sets[0].name, "@default")); - for (i = 0; i < _SYSCALL_FILTER_SET_MAX; i++) { + /* Ensure "@known" always remains at the end of the list */ + assert_se(SYSCALL_FILTER_SET_KNOWN == _SYSCALL_FILTER_SET_MAX - 1); + assert_se(streq(syscall_filter_sets[SYSCALL_FILTER_SET_KNOWN].name, "@known")); + + for (size_t i = 0; i < _SYSCALL_FILTER_SET_MAX; i++) { const char *k, *p = NULL; /* Make sure each group has a description */ assert_se(!isempty(syscall_filter_sets[0].help)); - /* Make sure the groups are ordered alphabetically, except for the first entry */ - assert_se(i < 2 || strcmp(syscall_filter_sets[i-1].name, syscall_filter_sets[i].name) < 0); + /* Make sure the groups are ordered alphabetically, except for the first and last entries */ + assert_se(i < 2 || i == _SYSCALL_FILTER_SET_MAX - 1 || + strcmp(syscall_filter_sets[i-1].name, syscall_filter_sets[i].name) < 0); NULSTR_FOREACH(k, syscall_filter_sets[i].value) { diff --git a/tools/syscall-names-update.sh b/tools/syscall-names-update.sh new file mode 100755 index 0000000000..c884b93cda --- /dev/null +++ b/tools/syscall-names-update.sh @@ -0,0 +1,6 @@ +#!/bin/sh +set -eu + +cd "$1" + +curl -L -o syscall-names.text 'https://raw.githubusercontent.com/hrw/syscalls-table/master/syscall-names.text'