So far we set the "trusted.delegate" xattr on cgroups where delegation
is on. This duplicates this behaviour with the "user.delegate" xattr.
This has two benefits:
1. unprivileged clients can *read* the xattr. "systemd-cgls" can thus
show delegated cgroups as such properly, even when invoked without
privs
2. unprivileged systemd instances can set the xattr, i.e. when systemd
--user delegates a cgroup to further payloads.
This weakens security a tiny bit, given that code that got a cgroup
delegated can manipulate the xattr, but I think that's OK, given they
have a higher trust level regarding cgroups anyway, if they got a
subtree delegated, and access controls on the cgroup itself are still
enforced. Moreover PID 1 as the cgroup manager only sets these xattrs,
never reads them — the xattr is primarily a way to tell payloads about
the delegation, and it's strictly this one way.
Unprivileged overlayfs is supported since Linux 5.11. The only
change needed to get ExtensionDirectories to work is to avoid
hard-coding the staging directory to the system manager runtime
directory, everything else just works (TM).
This mirrors a similar check in Linux kernel 5.16
(9dcc38e2813e0cd3b195940c98b181ce6ede8f20) that raised the
RLIMIT_MEMLOCK to 8M.
This change does two things: raise the default limit for nspawn
containers (where we try to mimic closely what the kernel does), and
bump it when running on old kernels which still have the lower setting.
Fixes: #16300
See: https://lwn.net/Articles/876288/
The first ExecStartPre or the first ExecStart commands would get the metadata,
but not the subsequent ones. Also check that we do not pass it in
ExecStartPost.
This fixes the following case:
OnFailure= would be spawned correctly, but OnSuccess= would be
spawned without the MONITOR_* metadata, because we'd "collect" the unit
that started successfully. So let's block cleanup while we have a job
running for the handler. The job cannot last infinitely, so at some point
we'll be able to collect both.
We already logged what we are spawning, but not so much why. Let's
add this, so it's easier to distinguish execstartpre/execstart/execstartpost
and such.
Remove the list logic, and simply skip passing metadata if more than one
unit triggered an OnFailure/OnSuccess handler.
Instead of a single env var to loop over, provide each separate item
as its own variable.
Fixes https://github.com/systemd/systemd/issues/22370
Backward incompatible change to avoid returning 'skipped' if a condition causes
a job activation to be skipped when using StartUnitWithFlags().
Job results are broadcasted, so it is theoretically possible that existing
software could get confused if they see this result.
Replaces https://github.com/systemd/systemd/pull/22369
This stuff is sufficiently different from the rest of main.c, let's move
it to its own .c/.h file, to make main.c a bit shorter.
No code changes, just some refactoring.
The only piece missing was to somehow make /proc appear in the
new user+mount namespace. It is not possible to mount a new
/proc instance, not even with hidepid=invisible,subset=pid, in
a user namespace unless a PID namespace is created too (and also
at the same time as the other namespaces, it is not possible to
mount a new /proc in a child process that creates a PID namespace
forked from a parent that created a user+mount namespace, it has
to happen at the same time).
Use the host's /proc with a bind-mount as a fallback for this
case. User session services would already run with it, so
nothing is lost.
This can help users to figure out what makes systemd freeze.
1. Someone kills systemd accidentally, then the sender_pid won't be 1;
2. systemd triggers segfault or assert, then the sender_pid will be 1;
When writing docs for SD_BUS_VTABLE_CAPABILITY, I noticed that we have one use
of SD_BUS_VTABLE_CAPABILITY(CAP_SYS_ADMIN) in the tree. This is the default, so
it's not very useful to specify it. But if we're touching that, I think it's
better to use mac + polkit for this like for everything else.
We don't have a very good category for this, but I don't think it makes sense
to add a new one. I just reused the same as other similar calls.
Add support for managing and configuring watchdog pretimeout values if
the watchdog hardware supports it. The ping interval is adjusted to
account for a pretimeout so that it will still ping at half the timeout
interval before a pretimeout event would be triggered. By default the
pretimeout defaults to 0s or disabled.
The RuntimeWatchdogPreSec config option is added to allow the pretimeout
to be specified (similar to RuntimeWatchdogSec). The
RuntimeWatchdogPreUSec dbus property is added to override the pretimeout
value at runtime (similar to RuntimeWatchdogUSec). Setting the
pretimeout to 0s will disable the pretimeout.
It's not clear why we rescheduled a service auto restart while a stop job for
the unit was pending. The comment claims that the unit shouldn't be restarted
but the code did reschedule an auto restart meanwhile.
In practice that was rarely an issue because the service waited for the next
auto restart to be rescheduled, letting the queued stop job to be proceed and
service_stop() to be called preventing the next restart to complete.
However when RestartSec=0, the timer expired right away making PID1 to
reschedule the unit again, making the timer expired right away... and so
on. This busy loop prevented PID1 to handle any queued jobs (and hence giving
no chance to the start rate limiting to trigger), which made the busy loop last
forever.
This patch breaks this loop by skipping the reschedule of the unit auto restart
and hence not depending on the value of u->restart_usec anymore.
Fixes: #13667
There's currently a deadlock between PID 1 and dbus-daemon: in some
cases dbus-daemon will do NSS lookups (which are blocking) at the same
time PID 1 synchronously blocks on some call to dbus-daemon. Let's break
that by setting SYSTEMD_NSS_DYNAMIC_BYPASS=1 env var for dbus-daemon,
which will disable synchronously blocking varlink calls from nss-systemd
to PID 1.
In the long run we should fix this differently: remove all synchronous
calls to dbus-daemon from PID 1. This is not trivial however: so far we
had the rule that synchronous calls from PID 1 to the dbus broker are OK
as long as they only go to interfaces implemented by the broke itself
rather than services reachable through it. Given that the relationship
between PID 1 and dbus is kinda special anyway, this was considered
acceptable for the sake of simplicity, since we quite often need
metadata about bus peers from the broker, and the asynchronous logic
would substantially complicate even the simplest method handlers.
This mostly reworks the existing code that sets SYSTEMD_NSS_BYPASS_BUS=
(which is a similar hack to deal with deadlocks between nss-systemd and
dbus-daemon itself) to set SYSTEMD_NSS_DYNAMIC_BYPASS=1 instead. No code
was checking SYSTEMD_NSS_BYPASS_BUS= anymore anyway, and it used to
solve a similar problem, hence it's an obvious piece of code to rework
like this.
Issue originally tracked down by Lukas Märdian. This patch is inspired
and closely based on his patch:
https://github.com/systemd/systemd/pull/22038Fixes: #15316
Co-authored-by: Lukas Märdian <slyon@ubuntu.com>
A first step of removing blocking calls to the D-Bus broker from PID 1.
There's a lot more to got (i.e. grep src/core/ for sd_bus_creds
basically), but it's a start.
Removing blocking calls to D-Bus broker deals systematicallly with
deadlocks caused by dbus-daemon blocking on synchronous IPC calls back
to PID1 (e.g. Varlink calls through nss-systemd). Bugs such as #15316.
Also-see: https://github.com/systemd/systemd/pull/22038#issuecomment-1042958390
Previously we'd only watch configured service bus names if Type=dbus was
set. Let's also watch it for other types. This is useful to pick up the
main PID of such a service. In fact the code to pick it up was already
in place, alas it didn't do anything given the signal was never received
for it. Fix that.
(It's also useful for debugging)
We would print "Setting NUMA policy to bind, with nodes .".
This is not very clear, change it to "… with nodes {}.".
Also use range formatting for masks to make output shorter.
For https://bugzilla.redhat.com/show_bug.cgi?id=1986176:
if we are trying to reexecute, and this fails for any reason, we shouldn't
try to execute /sbin/init or /bin/sh. It is better to just freeze.
If we freeze it is easier to diagnose what happened, but if we execute
one of the fallbacks, we don't really know what will happen. In particular
the new init might just return, causing the machine to shut down. Or we
may successfully spawn /bin/sh, which could leave the machine open.