-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Description
systemd version the issue has been seen with
From 96bedbe nspawn: replace syscall blacklist with a whitelist
... v239 v238 v237 v236 v235.
Unexpected behaviour you saw
Function swapcontext is out of system call filter whitelist of nspawn. Anyone of {get,set,make,swap}context is not available on PowerPC 32-bit (i.e. PPC32) container by default.
Use case: Fibers of Ruby is not available in PPC32 container.
https://bugs.ruby-lang.org/issues/14883
Steps to reproduce the problem
Part. 1
nspawn a PPC32 container, run Ruby code:
fib = Enumerator.new do |y|
y << "FOO"
y << "BAR"
end
puts fib.nextIt should print "FOO", but it segmentation fault.
Part. 2
#include <ucontext.h>
#include <errno.h>
int main() {
ucontext_t c;
if (getcontext(&c) < 0)
return errno;
return 0;
}It should return 0, but it returned 1 (EPERM).
Notes
A fiber uses getcontext() function to get the current context, to construct a new context, and uses makecontext() to switch context, so we have a nice lightweight userspace "thread" (or coroutine, fiber etc.).
The underlying call of getcontext() depends on architectures.
I checked source code from glibc (/sysdeps/unix/sysv/linux):
aarch64: rt_sigprocmask
sparc64: trap 0x6e
sparc32: rt_sigprocmask
sh3: sigprocmask
sh4: sigprocmask
i386: sigprocmask
arm: sigprocmask
powerpc64: sigprocmask
powerpc32: swapcontext
alpha: osf_sigprocmask
s390-32: rt_sigprocmask
s390-64: rt_sigprocmask
nios2: rt_sigprocmask
ia64: rt_sigprocmask
hppa: sigprocmask
x86_64: rt_sigprocmask
m680x0: sigprocmask
We already have {,rt_}sigprocmask in whitelist now (@signal), but there is no swapcontext.
systemd/src/shared/seccomp-util.c
Lines 723 to 740 in 2479c4f
| [SYSCALL_FILTER_SET_SIGNAL] = { | |
| .name = "@signal", | |
| .help = "Process signal handling", | |
| .value = | |
| "rt_sigaction\0" | |
| "rt_sigpending\0" | |
| "rt_sigprocmask\0" | |
| "rt_sigsuspend\0" | |
| "rt_sigtimedwait\0" | |
| "sigaction\0" | |
| "sigaltstack\0" | |
| "signal\0" | |
| "signalfd\0" | |
| "signalfd4\0" | |
| "sigpending\0" | |
| "sigprocmask\0" | |
| "sigsuspend\0" | |
| }, |
The syscall swapcontext() is a kind of mixture of {get,set,make,swap}context. Semantically it may be not suitable for @signal, we can put it in here:
systemd/src/nspawn/nspawn-seccomp.c
Lines 57 to 60 in 2479c4f
| /* Plus a good set of additional syscalls which are not part of any of the groups above */ | |
| { 0, "brk" }, | |
| { 0, "capget" }, | |
| { 0, "capset" }, |