On Linux only the "w" access bit is necessary to connect to an AF_UNIX
socket, hence let's only set that and nothing else, to limit exposure.
Just paranoia.
This is gets the resource limits off a specified process, and is very
similar to prlimit() with a NULL new_rlimit argument. In fact, it tries
that first. However, it then falls back to use /proc/$PID/limits. Why?
Simply because Linux prohibits access to prlimit() for processes with a
different UID, but /proc/$PID/limits still works.
This is preparation to allow nspawn to run unprivileged.
Currently the check doesn't take any settings from nspawn settings
files into account, so let's delay the check until after we've
loaded any settings file.
Introduce a new env variable $SYSTEMD_NSPAWN_CHECK_OS_RELEASE, that can
be used to disable the os-release check for bootable OS trees. Useful
when trying to boot a container with empty /etc/ and bind-mounted /usr/.
Resolves: #29185
Sometimes it makes sense to hard kill a client if we die. Let's hence
add a third FORK_DEATHSIG flag for this purpose: FORK_DEATHSIG_SIGKILL.
To make things less confusing this also renames FORK_DEATHSIG to
FORK_DEATHSIG_SIGTERM to make clear it sends SIGTERM. We already had
FORK_DEATHSIG_SIGINT, hence this makes things nicely symmetric.
A bunch of users are switched over for FORK_DEATHSIG_SIGKILL where we
know it's safe to abort things abruptly. This should make some kernel
cases more robust, since we cannot get confused by signal masks or such.
While we are at it, also fix a bunch of bugs where we didn't take
FORK_DEATHSIG_SIGINT into account in safe_fork()
If we have a DDI that contains only a /usr/ tree (and which is thus
combined with a tmpfs for root on boot) we previously would try to apply
idmapping to the tmpfs, but not the /usr/ mount. That's broken of
course.
Fix this by applying it to both trees.
Let's wait until the child is fully done with mounting it's own
instances of procfs/sysfs before we destroy our fully visible copies of
it.
This borrows heavily from Christian Brauners fix#29521, but splits the
place + sync into two steps so that the child payload is not started
before the parent has destroyed the procfs instance.
Alternative to: #29521Fixes: #28157
We use it for more than just pipe() arrays. For example also for
socketpair(). Hence let's give it a generic name.
Also add EBADF_TRIPLET to mirror this for things like
stdin/stdout/stderr arrays, which we use a bunch of times.
When --boot is set, and --keep-unit is not, set CoredumpReceive=yes on
the scope allocated for the container. When --keep-unit is set, nspawn
does not allocate the container's unit, so the existing unit needs to
configure this setting itself.
Since systemd-nspawn@.service sets --boot and --keep-unit, add
CoredumpReceives=yes to that unit.
This adds support for the new fsmount() logic of the kernel: we'll first
create an unattached fsmount fd, and then in a second step attach this
to some real file system inode – as opposed to attaching file system
directly. The benefit of this is that we can pass the open fsmount fds
over some sockets if need be, to isolate the mounting code from the
attaching code.
No functional change. In config_parse_address_generation_type() we would set
the output parameter and then say it's ignored, so it _looked_ like an error in
the code, but the variable was always initialized to SD_ID128_NULL anyway, so
the code was actually fine.
seccomp-util.h doesn't need ifdeffing, hence don't. It has worked since
quite a while with HAVE_SECCOMP is off, hence use it everywhere.
Also drop explicit seccomp.h inclusion everywhere (which needs
HAVE_SECCOMP ifdeffery everywhere). seccomp-util.h includes it anyway,
automatically, which we can just rely on, and it deals with HAVE_SECCOMP
at one central place.
Given that ERRNO_IS_SECCOMP_FATAL() also matches positive values,
make sure this macro is not called with arguments that do not have
errno semantics.
In this case the arguments passed to ERRNO_IS_SECCOMP_FATAL() are the
values returned by external libseccomp function seccomp_load() which is
not expected to return any positive values, but let's be consistent
anyway and move ERRNO_IS_SECCOMP_FATAL() invocations to the branches
where the return values are known to be negative.
Given that ERRNO_IS_NOT_SUPPORTED() also matches positive values,
make sure this macro is not called with arguments that do not have
errno semantics.
In this case the argument passed to ERRNO_IS_NOT_SUPPORTED() is the
value returned by remount_idmap() which is not expected to return
any positive values, but let's be consistent anyway and move the
ERRNO_IS_NOT_SUPPORTED() invocation to the branch where
the return value is known to be negative.
The check added by 4c27749b8c breaks
booting an arm64 image on x86 using qemu-bin-fmt, so remove it.
Without it, the image built with mkosi --architecture=aarch64
boots fine in nspawn.
When merging the settings we take the pointer to the array of extra
devices, but don't reset the array counter to zero. This later leads to
a NULL pointer dereference, where device_node_array_free() attempts to
loop over a NULL pointer:
+ systemd-nspawn --oci-bundle=/var/lib/machines/testsuite-13.oci-bundle.Npo
../src/nspawn/nspawn-settings.c:118:29: runtime error: member access within null pointer of type 'struct DeviceNode'
#0 0x4b91ee in device_node_array_free ../src/nspawn/nspawn-settings.c:118
#1 0x4ba42a in settings_free ../src/nspawn/nspawn-settings.c:161
#2 0x410b79 in settings_freep ../src/nspawn/nspawn-settings.h:249
#3 0x446ce8 in load_oci_bundle ../src/nspawn/nspawn.c:4733
#4 0x44ff42 in run ../src/nspawn/nspawn.c:5476
#5 0x455296 in main ../src/nspawn/nspawn.c:5919
#6 0x7f0cb7a4a50f in __libc_start_call_main (/lib64/libc.so.6+0x2750f)
#7 0x7f0cb7a4a5c8 in __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x275c8)
#8 0x40d284 in _start (/usr/bin/systemd-nspawn+0x40d284)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior ../src/nspawn/nspawn-settings.c:118:29 in
Also, add an appropriate assert to catch such issues in the future.
When we're checking if /etc/resolv.conf exists so we can bind mount
on top of it, we care about whether the symlink itself exists if
/etc/resolv.conf exists and not the file it points to, so add
CHASE_NOFOLLOW to make sure we check existence of the symlink and
not the file it points to.
systemd-nspawn now optionally supports colon-separated pair of
host interface name and container interface name for --network-macvlan, --network-ipvlan and --network-interface options.
Also supported in .nspawn configuration files (i.e Interface=, MACVLAN=, IPVLAN= parameters).
man page changed for ntwk interface naming
Previously, when the NULL (all zero) machine ID is configured in the
container, nspawn refused to execute.
Now id128_get_machine() is used, so NULL machine ID is refused with
-ENOMEDIUM, and fallback to specified UUID or randomly generated one.