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.next
It 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.
|
[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:
|
/* Plus a good set of additional syscalls which are not part of any of the groups above */ |
|
{ 0, "brk" }, |
|
{ 0, "capget" }, |
|
{ 0, "capset" }, |
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
swapcontextis out of system call filter whitelist of nspawn. Anyone of{get,set,make,swap}contextis 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:
It should print "FOO", but it segmentation fault.
Part. 2
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 usesmakecontext()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):We already have
{,rt_}sigprocmaskin whitelist now (@signal), but there is noswapcontext.systemd/src/shared/seccomp-util.c
Lines 723 to 740 in 2479c4f
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