It doesn't really make sense to have that in dev-setup.c, which is
mostly about setting up /dev/, creating device nodes and stuff.
let's move it to the other stuff that deals with /dev/console's
peculiarities.
It's a bit confusing, but we actually initialize the terminal twice for
each service, potentially. One earlier time, where we might end up
firing vhangup() and vt_disallocate(), which is a pretty brutal way to
reset things, by disconnecting and possibly invalidating the tty
completely. When we do this we do not keep any fd open afterwards, since
it quite likely points to a dead connection of a tty.
The 2nd time we initialize things when we actually want to use it.
The first initialization is hence "destructive" (killing any left-overs
from previous uses) the 2nd one "constructive" (preparing things for our
new use), if you so will.
Let's document this distinction in comments, and let's also move both
initializations to exec_invoke(), so that they are easier to see in their
symmetric behaviour. Moreover, let's run the tty initialization after we
opened both input and output, since we need both for doing the fancy
dimension auto init stuff now.
Oh, and of course, one thing to mention: we nowadays initialize
terminals both with ioctl() and with ansi sequences. But the latter
means we need an fd that is open for *write* (since we are *writing*
those ansi sequences to the tty). Hence, resetting via the input fd is
conceptually wrong, it worked only so far if we had O_RDWR open mode
selected)
And while we are at it, merge exec_context_determine_tty_size() +
exec_context_apply_tty_size().
Let's simplify things, and merge the two funcs, since the latter just
does one more call.
At the same time, let's make sure we actually allow passing separate
input/output fds.
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.