From b931112cb2b2a9bd1ba095ec468fb18f85065c8d Mon Sep 17 00:00:00 2001 From: Alex Protsko Date: Thu, 9 Jul 2026 11:19:24 +0300 Subject: [PATCH] worker-privs: allow munmap/mremap/madvise for isolated workers Fix worker crashes on musl-based systems when isolate-workers = true by allowing munmap, mremap, and madvise in the worker seccomp filter. Move seccomp coverage to Alpine CI and use oc_syslog for seccomp trap diagnostics instead of direct write()-based output. Keep glibc backtrace diagnostics as the default and allow musl builds to select the syscall-only fallback with the assume-glibc Meson option. Resolves: #749 Signed-off-by: Alex Protsko --- .gitlab-ci.yml | 28 +++++++++++++++++++++++++++- meson.build | 1 + meson_options.txt | 1 + src/worker-privs.c | 17 +++++++++++++++-- 4 files changed, 44 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 292b7bd5..e734522b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -221,7 +221,7 @@ musl/Alpine: stage: testing image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$ALPINE_BUILD script: - - meson setup build -Dwith-werror=true + - meson setup build -Dwith-werror=true -Dassume-glibc=false - ninja -C build -j$JOBS tags: - saas-linux-small-amd64 @@ -339,6 +339,32 @@ seccomp/Fedora: untracked: true when: on_failure +# Tests seccomp filters under musl/Alpine to catch allocator/syscall gaps +seccomp/Alpine: + stage: testing + image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$ALPINE_BUILD + script: + - apk add --no-cache bash + - chmod -R o-w tests/data/raddb + - git submodule update --init + - meson setup build -Dseccomp-trap=true -Dassume-glibc=false + - ninja -C build -j$JOBS + - >- + meson test -C build --no-rebuild --num-processes 1 --print-errorlogs + session-timeout traffic bandwidth + oc-aes256-gcm-cipher oc-aes128-gcm-cipher + ac-aes128-gcm-cipher ac-aes256-gcm-cipher + no-dtls-cipher + tags: + - saas-linux-medium-amd64 + except: + - tags + - schedules + artifacts: + expire_in: 1 week + untracked: true + when: on_failure + # Tests per-worker RLIMIT_DATA by making setrlimit failures fatal worker-memory-limit/Fedora: stage: testing diff --git a/meson.build b/meson.build index 40aa477e..808d2f90 100644 --- a/meson.build +++ b/meson.build @@ -362,6 +362,7 @@ cdata.set('PROC_FS_SUPPORTED', proc_fs) cdata.set('SUPPORT_OIDC_AUTH', oidc_enabled) cdata.set('TRY_SHA2_CRYPT', try_sha2_crypt) cdata.set('USE_SECCOMP_TRAP', get_option('seccomp-trap')) +cdata.set('ASSUME_GLIBC', get_option('assume-glibc')) cdata.set('WORKER_MEMORY_LIMIT_TEST', get_option('worker-memory-limit-test')) # These three are used in #elif (not #ifdef), so they must be 1 or undef (not empty) diff --git a/meson_options.txt b/meson_options.txt index 5e1ecaf2..48100950 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -21,6 +21,7 @@ option('local-llhttp', type: 'boolean', value: true, description: 'Us option('local-protobuf', type: 'boolean', value: false, description: 'Force use of bundled protobuf-c') option('local-pcl', type: 'boolean', value: true, description: 'Use bundled PCL (default); false to require system pcl') option('seccomp-trap', type: 'boolean', value: false, description: 'Filtered syscalls fail with a signal (for CI/testing)') +option('assume-glibc', type: 'boolean', value: true, description: 'Use glibc backtrace support for seccomp trap diagnostics') option('worker-memory-limit-test', type: 'boolean', value: false, description: 'RLIMIT_DATA failures in worker are fatal (for CI/testing)') option('root-tests', type: 'boolean', value: true, description: 'Enable tests requiring root/namespaces') option('serial-heavy-tests', type: 'boolean', value: false, description: 'Run iperf3-heavy tests serially to avoid ASAN memory exhaustion under parallel load') diff --git a/src/worker-privs.c b/src/worker-privs.c index 0da0b6f9..d6e613e1 100644 --- a/src/worker-privs.c +++ b/src/worker-privs.c @@ -40,14 +40,24 @@ #ifdef USE_SECCOMP_TRAP #define _SECCOMP_ERR SCMP_ACT_TRAP +#ifdef ASSUME_GLIBC #include -#include +#endif /* ASSUME_GLIBC */ + void sigsys_action(int sig, siginfo_t *info, void *ucontext) { + (void)sig; + (void)ucontext; + +#ifdef ASSUME_GLIBC char *call_addr = *backtrace_symbols(&info->si_call_addr, 1); oc_syslog(LOG_ERR, "Function %s called disabled syscall %d", call_addr, info->si_syscall); +#else + oc_syslog(LOG_ERR, "seccomp trap: syscall %d at %p", info->si_syscall, + info->si_call_addr); +#endif /* ASSUME_GLIBC */ exit(EXIT_FAILURE); } @@ -135,9 +145,12 @@ int disable_system_calls(struct worker_st *ws) ADD_SYSCALL(setitimer, 0); ADD_SYSCALL(getpid, 0); - /* memory allocation - both are used by different platforms */ + /* memory allocations used by different platforms */ ADD_SYSCALL(brk, 0); ADD_SYSCALL(mmap, 0); + ADD_SYSCALL(munmap, 0); + ADD_SYSCALL(mremap, 0); + ADD_SYSCALL(madvise, 0); #if defined(SYS_getrandom) || defined(__NR_getrandom) ADD_SYSCALL(getrandom, 0); /* used by gnutls 3.5.x */