The kernel's sched_setattr interface allows for more control over a processes
scheduling attributes as the previously used sched_setscheduler interface.
Using sched_setattr is also the prerequisite for support of utilization
clamping (UCLAMP [1], see #26705) and allows to set sched_runtime. The latter,
sched_runtime, will probably become a relevant scheduling parameter of the
EEVDF scheduler [2, 3], and therefore will not only apply to processes
scheduled via SCHED_DEADLINE, but also for processes scheduled via
SCHED_OTHER/SCHED_BATCH (i.e., most processes).
1: https://docs.kernel.org/next/scheduler/sched-util-clamp.html
2: https://lwn.net/Articles/969062/
3: https://lwn.net/ml/linux-kernel/20240405110010.934104715@infradead.org/
Before 12001b1bf0, write() is required for
if Type=exec. However, with the previous commit, now write() is also used
for sending handoff timestamp. Let's allow write() if necessary.
Fixes a regression caused by 12001b1bf0.
Fixes#33299.
Before 12001b1bf0, the timestamp is sent
with write(), but the commit made the timestamp sent by send(), and
causes regressin #33299.
Note the invocation will still fail if write() is filtered by seccomp.
But, that is an old issue since Type=exec is introduced
(5686391b00).
Partially fixes a regression caused by 12001b1bf0.
Partially fixes#33299.
DynamicUser= enables PrivateTmp= implicitly to avoid files owned by reusable uids
leaking into the host. Change it to instead create a fully private tmpfs instance
instead, which also ensures the same result, since it has less impactful semantics
with respect to PrivateTmp=yes, which links the mount namespace to the host's /tmp
instead. If a user specifies PrivateTmp manually, let the existing behaviour
unchanged to ensure backward compatibility is not broken.
- drop unnecessary SYNTHETIC_ERRNO() when the logger does not propagate
error code,
- drop unnecessary '%m' in error message when the error code is
specified with SYNTHETIC_ERRNO(),
- add missing full stop at the end of log message,
- use RET_GATHER(),
- add missing ", ignoring.",
- upeercase the first letter, etc., etc...
This changes the executor to systematically send handoff timestamps to
the service manager if a socket for that is supplied. This drops the
code that did this via Type=exec messages, and reverts that part to the
old behaviour before 93cb78aee2.
Benefits of this approach:
1. We can collect the handoff for any command we fork off, regardless
if it's ExecStart= something else, regardless whether it's Type=exec,
Type=simple or some any other service type, regardless of the unit
type.
2. We collect both CLOCK_REALTIME and CLOCK_MONOTONIC, as we do for the
other process timestamps.
3. It's entirely backwards compatible, as this doesn't change the
protocol between service manager and executor, but just extends it.
Enable the exec_fd logic for Type=notify* services too, and change it
to send a timestamp instead of a '1' byte. Record the timestamp in a
new ExecMainHandoverTimestamp property so that users can track accurately
when control is handed over from systemd to the service payload, so
that latency and startup performance can be trivially and accurately
tracked and attributed.
Use FOREACH_ELEMENT where possible. Generated with this command,
and checked manually:
git grep -l 'FOREACH_ARRAY.*ELEMENTSOF' | \
xargs sed -ri 's/FOREACH_ARRAY\((.*), (.*), (ELEMENTSOF.*)\)/FOREACH_ELEMENT(\1, \2)/'
Prompted by #32259
We already have this check in exec_invoke(), i.e. child.
But if CLONE_INTO_CGROUP is used, the failure would
occur on parent's side, so do the check there too.
Follow-up for 4d8b0f0f7a
After the mentioned commit, when the ExecCommand executable is missing,
and failure will be ignored by manager, we exit with EXIT_SUCCESS at executor
side too. The behavior however contradicts systemd.service(5), which states:
> If the executable path is prefixed with "-", an exit code of the command
> normally considered a failure (i.e. non-zero exit status or abnormal exit
> due to signal is _recorded_, but has no further effect and is considered
> equivalent to success.
and thus makes debugging unexpected failures harder. Therefore, let's still
exit with EXIT_EXEC, but just skip LOG_ERR level log.
This is useful for situations where an array of FDs is to be passed into
a child process (i.e. by passing it through safe_fork). This function
can be called in the child (before calling exec) to pack the FDs to all
be next to each-other starting from SD_LISTEN_FDS_START (i.e. 3)
Inspired by CVE-2024-21626, let's add a longer comment explaining why
the code really shouldn#t be moved any earlier.
Just in the hope that anyone who feels tempted to move this around maybe
actually reads the comment and reconsiders.
The man page pam_setcred(3) states:
> The credentials should be deleted after the session has been closed
> (with pam_close_session(3)).
Follow-up for 3bb39ea936.
This file is a bit misnamed. What it actually implements is one specific
BPF LSM module, that restricts file systems. As such it really should be
named after that, and not primarily by the mechanism it uses for that.
With this our glue code is now named the same way as the actual bpf code
files in src/core/bpf/, thus things become a bit more symmetric.
This is particular relevant as we'll soon have another BPF LSM in our
tree, see #26826, and we should be able to distinguish them by name.
This commit just renames the files and does some dumb search/replace of
the string. A follow-up commit will name some functions more expressively
inside the files.
If PAMName= is used we'll spawn a PAM session for the service, and leave
a process around that closes the PAM session eventually. That process
must close the "exec_fd" that we use to implement Type=exec. After all
the logic relies on the fact that execve() will implicitly close the
exec_fd, and the EOF seen on it is hence indication for the service
manager that execve() has worked. But if we keep an fd open in the PAM
service process, then this is not going to work.
Hence close the fd explicitly so that it definitely doesn't stay pinned
in the child.