Commit Graph
1039 Commits
Author SHA1 Message Date
Daan De Meyer 38701809a8 core: Add DelegateNamespaces= (#36532) 2025-03-01 15:18:45 +01:00
Daan De Meyer 8234cd9989 core: Add DelegateNamespaces=
This delegates one or more namespaces to the service. Concretely,
this setting influences in which order we unshare namespaces. Delegated
namespaces are unshared *after* the user namespace is unshared. Other
namespaces are unshared *before* the user namespace is unshared.

Fixes #35369
2025-03-01 13:54:58 +01:00
Lennart Poettering bbdad5c025 core: also issue OSC 3008 from service context
(Note: we also change TEST-13-NSPAWN.machined.sh minimally here, because
it checks for byte precise output of a pty allocated for a service
invocation - which it's not going to get if it claims that the pty is an
all-powerful one. After all this PR ensures that we'll generate the new
OSC sequence on non-dumb terminals associated with services. Hence, set
TERM=dumb explicitly to ensure no ANSI sequences are generated, ever.
Which is a nice test btw that TERM=dumb really does its thing here.)
2025-02-27 15:17:34 +01:00
Lennart Poettering 5b3eaf9e68 terminal-util: change conditioning in terminal_reset_defensive()
So far we conditioned the logic that issues ansi sequences for resetting
the TTY based on whether something is a pty is not (under the assumption
we need no reset on ptys, since they are shortlived).

This is simply wrong though. The pty that a container getty is invoked
on is generally long-lived: as long as the container is up, and it will
be reused between getty instances/sessions all the time. In such a case
we really should reset properly.

Let's instead make the logic dependent on whether TERM is set to
anything other than "dumb". The previous commit made sure we always set
TERM in a sensible way in systemd-run, hence this
*explicit* logic sounds like a much better choice now, as it mea
2025-02-27 15:17:34 +01:00
Lennart Poettering 9ab703d8e1 terminal-util: change 2nd parameter of terminal_reset_defensive() to flags
let's convert the 2nd argumeng form a boolean to a proper flags
parameter. Doesn't change behaviour in anyway, but is more readable, and
prepares ground for adding more flags soon.
2025-02-27 15:13:15 +01:00
Yu Watanabe d7306348b2 tree-wide: insert a space at the end of comments 2025-01-25 05:24:23 +09:00
Mike Yuan 1e4e557262 tree-wide: replace FLAGS_SET(..., 1 << v) with BIT_SET(..., v) 2024-12-28 15:08:00 +01:00
Lennart Poettering 5d1e57b820 serialize: add explicit calls for finishing serialization
These new calls will do three things:

1. in case of FILE* stuff: flush any pending bytes onto the fd, just in
   case
2. seal the backing memfd
3. seek back to the beginning.

Note that this adds sealing to serialization: once we serialized fully,
we'll seal the thing off for further modifications, before we pass the
fd over to the target process. This should add a bit of robustness, and
maybe finds a bug or two one day, if we accidentally write to a
serialization that is complete.
2024-12-17 18:26:15 +01:00
Yu Watanabe e76fcd0e40 core: make ProtectHostname= optionally take a hostname
Closes #35623.
2024-12-16 23:55:44 +09:00
Daan De Meyer 284dd31e9d core: Bind mount notify socket to /run/host/notify in sandboxed units
To be able to run systemd in a Type=notify transient unit, the notify
socket can't be bind mounted to /run/systemd/notify as systemd in the
transient unit wants to use that as its own notify socket which conflicts
with systemd on the host.

Instead, for sandboxed units, let's bind mount the notify socket to
/run/host/notify as documented in the container interface. Since we don't
guarantee a stable location for the notify socket and insist users use
$NOTIFY_SOCKET to get its path, this is safe to do.
2024-12-13 13:37:02 +01:00
Ryan Wilson 6746f28854 core: Migrate ProtectHostname to use enum vs boolean
Migrating ProtectHostname to enum will set the stage for adding more
properties like ProtectHostname=private in future commits.

In addition, we add PrivateHostnameEx property to dbus API which uses
string instead of boolean.
2024-12-06 13:33:49 -08:00
David Tardon c3dc460b6c execute: free syscall_log hashmap when done
Fixes #35394
2024-11-28 16:45:02 +01:00
Daan De Meyer 406f177501 core: Introduce PrivatePIDs=
This new setting allows unsharing the pid namespace in a unit. Because
you have to fork to get a process into a pid namespace, we fork in
systemd-executor to get into the new pid namespace. The parent then
sends the pid of the child process back to the manager and exits while
the child process continues on with the rest of exec_invoke() and then
executes the actual payload.

Communicating the child pid is done via a new pidref socket pair that is
set up on manager startup.

We unshare the PID namespace right before the mount namespace so we
mount procfs correctly. Note PrivatePIDs=yes always implies MountAPIVFS=yes
to mount procfs.

When running unprivileged in a user session, user namespace is set up first
to allow for PID namespace to be unshared. However, when running in
privileged mode, we unshare the user namespace last to ensure the user
namespace does not own the PID namespace and cannot break out of the sandbox.

Note we disallow Type=forking services from using PrivatePIDs=yes since the
init proess inside the PID namespace must not exit for other processes in
the namespace to exist.

Note Daan De Meyer did the original work for this commit with Ryan Wilson
addressing follow-ups.

Co-authored-by: Daan De Meyer <daan.j.demeyer@gmail.com>
2024-11-05 05:32:02 -08:00
Luca Boccassi 890bdd1d77 core: add read-only flag for exec directories
When an exec directory is shared between services, this allows one of the
service to be the producer of files, and the other the consumer, without
letting the consumer modify the shared files.
This will be especially useful in conjunction with id-mapped exec directories
so that fully sandboxed services can share directories in one direction, safely.
2024-11-01 10:46:55 +00:00
Lennart Poettering 2ef87de9d3 core: add EXEC_DIRECTORY_TYPE_SHALL_CHOWN() helper
Let's make ConfigurationDirectory= a bit less "special-casey", by hiding
the fact that it's the only per-service dir we do not do chown()ing for
inside of a new EXEC_DIRECTORY_TYPE_SHALL_CHOWN() helper.
2024-10-30 13:33:29 +01:00
Ryan Wilson cd58b5a135 cgroup: Add support for ProtectControlGroups= private and strict
This commit adds two settings private and strict to
the ProtectControlGroups= property. Private will unshare the cgroup
namespace and mount a read-write private cgroup2 filesystem at /sys/fs/cgroup.
Strict does the same except the mount is read-only. Since the unit is
running in a cgroup namespace, the new root of /sys/fs/cgroup is the unit's
own cgroup.

We also add a new dbus property ProtectControlGroupsEx which accepts strings
instead of boolean. This will allow users to use private/strict via dbus
and systemd-run in addition to service files.

Note private and strict fall back to no and yes respectively if the kernel
doesn't support cgroup2 or system is not using unified hierarchy.

Fixes: #34634
2024-10-28 08:37:36 -07:00
Ryan Wilson 5fe2923828 core: Refactor ProtectControlGroups= to use enum vs bool
This commit refactors ProtectControlGroups= from using a boolean
in the dbus/execute backend to using an enum. There is no functional
change but this will allow adding new non-boolean values (e.g. strict,
private) a la PrivateHome.
2024-10-28 06:42:53 -07:00
Ryan Wilson 3543456f84 Add ExtraFileDescriptor property to StartTransientUnit dbus API
This adds the ExtraFileDescriptor property to StartTransient dbus API
with format "a(hs)" - array of (file descriptor, name) pairs. The FD
will be passed to the unit via sd_notify like Socket and OpenFile.

systemctl show also shows ExtraFileDescriptorName for these transient
units. We only show the name passed to dbus as the FD numbers will
change once passed over the unix socket and are duplicated, so its
confusing to display the numbers.

We do not add this functionality for systemd-run or general systemd
service units as it is not useful for general systemd services.
Arguably, it could be useful for systemd-run in bash scripts but we
prefer to be cautious and not expose the API yet.

Fixes: #34396
2024-10-07 09:01:48 -07:00
Mike Yuan a2c8652a2a tree-wide: use strv_extend_strv_consume() where appropriate 2024-09-21 00:53:50 +02:00
Daan De Meyer fa693fdc7e core: Add support for PrivateUsers=identity
This configures an indentity mapping similar to
systemd-nspawn --private-users=identity.
2024-09-09 18:31:01 +02:00
Mike Yuan 7a9f0125bb core: rename BindJournalSockets= to BindLogSockets=
Addresses https://github.com/systemd/systemd/pull/32487#issuecomment-2328465309
2024-09-04 21:44:25 +02:00
Mike Yuan 368a3071e9 core: introduce BindJournalSockets=
Closes #32478
2024-09-03 21:04:50 +02:00
Luca Boccassi 7d8bbfbe08 service: add 'debug' option to RestartMode=
One of the major pait points of managing fleets of headless nodes is
that when something fails at startup, unless debug level was already
enabled (which usually isn't, as it's a firehose), one needs to manually
enable it and pray the issue can be reproduced, which often is really
hard and time consuming, just to get extra info. Usually the extra log
messages are enough to triage an issue.

This new option makes it so that when a service fails and is restarted
due to Restart=, log level for that unit is set to debug, so that all
setup code in pid1 and sd-executor logs at debug level, and also a new
DEBUG_INVOCATION=1 env var is passed to the service itself, so that it
knows it should start with a higher log level. Once the unit succeeds
or reaches the rate limit the original level is restored.
2024-08-27 12:24:45 +01:00
Lennart Poettering b004393d70 core: rename original_ambient_set → saved_ambient_set
We call similar other fields in main.c (notably: rlimit stuff, env vars) "saved",
rather than "original". Hence stick to that kind of naming here too.

Follow-up for: #32937
2024-08-22 18:21:56 +02:00
Daan De Meyer 14702b9c18 core: Use RateLimit struct to store ratelimits
This makes it easier to serialize these ratelimits with
JSON_BUILD_CALLBACK().
2024-08-14 14:18:40 +02:00
Yu Watanabe af7b3851ea core/execute: fix typo
Follow-up for 628c214656.
2024-08-03 05:50:50 +09:00
Mike Yuan 8574b7940b core/unit: merge use of LOG_CONTEXT_SET_LOG_LEVEL into LOG_CONTEXT_PUSH_UNIT
No functional change, since LOG_CONTEXT_PUSH_UNIT is only used
in exec_spawn().
2024-07-31 21:40:28 +02:00
Daan De Meyer e54a8e0fc3 Merge pull request #33873 from DaanDeMeyer/rename-creds
core: Add support for renaming credentials with ImportCredential=
2024-07-31 17:35:58 +02:00
Luca Boccassi 0e5c97ae6f Merge pull request #32937 from steelman/github/drop-ambient-caps-executor
core: drop ambient capabilities in systemd-executor
2024-07-31 16:11:30 +02:00
Daan De Meyer 831f208783 core: Add support for renaming credentials with ImportCredential=
This allows for "per-instance" credentials for units. The use case
is best explained with an example. Currently all our getty units
have the following stanzas in their unit file:

"""
ImportCredential=agetty.*
ImportCredential=login.*
"""

This means that setting agetty.autologin=root as a system credential
will make every instance of our all our getty units autologin as the
root user. This prevents us from doing autologin on /dev/hvc0 while
still requiring manual login on all other ttys.

To solve the issue, we introduce support for renaming credentials with
ImportCredential=. This will allow us to add the following to e.g.
serial-getty@.service:

"""
ImportCredential=tty.serial.%I.agetty.*:agetty.
ImportCredential=tty.serial.%I.login.*:login.
"""

which for serial-getty@hvc0.service will make the service manager read
all credentials of the form "tty.serial.hvc0.agetty.xxx" and pass them
to the service in the form "agetty.xxx" (same goes for login). We can
apply the same to each of the getty units to allow setting agetty and
login credentials for individual ttys instead of globally.
2024-07-31 15:52:27 +02:00
Daan De Meyer 7881f485c9 execute: Drop log level to unit log level in exec_spawn()
All messages logged from exec_spawn() are attributed to the unit
and as such we should set the log level to the unit's max log level
for the duration of the function.
2024-07-31 13:12:55 +02:00
Łukasz Stelmach e0ebc81b2d core: drop ambient capabilities in systemd-executor
Since the commit 963b6b906e ("core: drop ambient capabilities in
user manager") systemd running as the session manager has dropped ambient
capabilities retaining other sets allowing user services to be started
with elevated capabilities. This, worked fine until the introduction of
sd-executor. For a non-root process to be started with elevated
capabilities by a non-root parent it either needs file capabilities or
ambient capabilities in the parent process. Thus, systemd needs to allow
sd-executor to inherit its ambient capabilities and sd-executor should
drop them as systemd did before.

The ambient set is managed for both system and session managers, but
with the default set for PID#1 being empty, this code does not affect
operation of PID#1.

Fixes: bb5232b6a3 ("core: add systemd-executor binary")
2024-07-31 11:09:58 +02:00
Lennart Poettering 4a24cc859f terminal-util: move lock_dev_console() here
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.
2024-07-19 11:44:04 +02:00
Lennart Poettering 628c214656 exec-invoke: move terminal initialization a bit
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)
2024-07-19 11:44:04 +02:00
Lennart Poettering 27c067ceeb execute: reorder "destructive" tty reset operations
Let's make sure to first issue the non-destructive operations, then
issue the hangup (for which we need the fd), then try to disallocate the
device (for which we don't need it anymore).
2024-07-19 11:44:04 +02:00
Lennart Poettering 3f2e8e951a execute: also hook up ansi-seq-based terminal size determination with exec_context_determine_size()
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.
2024-07-19 11:44:04 +02:00
Lennart Poettering 967bcc6e26 tree-wide: reset stdout not stdin
We nowadays reset TTYs by writing ANSI sequences to them. This can only
work if we operate on an *output* fd, not an input fd. Hence switch
various cases where we erroneously used an input fd to use an output fd
instead.
2024-07-19 11:44:04 +02:00
Lennart Poettering cfac09083b terminal-util: add new helper terminal_reset_defensive() that combines reset-by-ioctl and reset-by-sequence reasonably 2024-07-19 11:41:43 +02:00
Zbigniew Jędrzejewski-Szmek bfd5a0687f various: move const ptr indicator to return value 2024-06-19 16:28:28 +02:00
Luca Boccassi 0e551b04ef core: do not imply PrivateTmp with DynamicUser, create a private tmpfs instead
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.
2024-06-17 17:05:55 +01:00
Zbigniew Jędrzejewski-Szmek e9bdbb6bbc core,vconsole-setup: treat locking failure as non-fatal
Locking of the tty device and then /dev/console was added to synchronize
vconsole-setup with other writers to the console. But it turns out that often
the locking doesn't work and we carved out various cases where we ignore
failure:
- lack of permissions (in the user manager)
- missing device node

It turns out that there's at least one more failure mode: we get -EIO when the
console is (mis-)configured to point to an invalid device. E.g. in
rhbug#2273069 the reporter has a VM in Proxmox without a virtual console
configured and has 'console=tty console=ttyS0' on the kernel cmdline. I
couldn't reproduce this under libvirt, but failure with EIO has been reported
by at least four users in #30501.

Note that in systemd-vconsole-setup we report this is a hard failure, while
in the manager, we only do a debug line. So it's possible that the failure
also occured there, causing the rest of the setup of the tty to be skipped
without further notice.

Ignore the locking failure, since there's just too many ways it can fail. If we
proceed without a lock, we're back to the situation before we started locking,
which wasn't too bad. OTOH, skipping setup of the console is problematic for
users, and it seems better to try to do the setup without locking.

Fixes https://github.com/systemd/systemd/issues/30501,
https://bugzilla.redhat.com/show_bug.cgi?id=2273069.
2024-05-14 23:22:41 +02:00
Mike Yuan dddc060286 core/execute: re-break function declaration of exec_spawn
Also rearrange some variable definitions. Note that
DECIMAL_STR_MAX() contains the size of NUL byte,
so +1 is dropped.
2024-05-08 00:16:54 +08:00
Daan De Meyer 7e0e6b50b4 core: Record ExecMainStartTimestamp before forking
Otherwise there's a chance the handover timestamp is less than the
start timestamp depending on the whims of the scheduler.

For non-forking services, we also propagate the start timestamp into
Service->main_exec_status to make sure it starts earlier than the
handoff timestamp.
2024-05-05 14:19:30 +02:00
Mike Yuan 0afd4d214f core/execute: switch mount_apivfs to tristate
No functional change, just refactoring.
2024-04-27 14:30:29 +08:00
Lennart Poettering be3444f119 execute: make ExecStatus dump more useful by showing passed time
Let's show the runtimes of our commands and preparations for them. It's
actually quite interesting, we sometimes are irritatingly slow with our
handoffs.
2024-04-25 13:40:41 +02:00
Lennart Poettering 3c1d1ca146 manager: switch service unit type over to using new handoff timestamping logic
Also: rename Handover → Handoff. I think it makes it clearer that this
is not really about handing over any resources, but that the executor is
out off the game from that point on.
2024-04-25 13:40:41 +02:00
Lennart Poettering b9e4d9ba95 mount,swap: include ExecStatus output in dump
socket and service units output there ExecCommand/ExecStatus definitions
already, but this was missing in mount/swap. Fix that.
2024-04-24 21:23:42 +02:00
Luca Boccassi 93cb78aee2 core: add ExecMainHandoverTimestamp property recording time-of-execve
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.
2024-04-22 15:16:05 +02:00
Mike Yuan 58ff2f1e38 core/execute: also check cg_is_threaded for clone3()
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.
2024-04-14 23:22:13 +08:00
Mike Yuan f09604b0a6 core/execute: introduce exec_command_free 2024-04-11 04:44:57 +08:00