Note sure why it didn't occur earlier to me, but now that we have this
nice helper to get the effective value of the set_login_environment
field instead of just falling back to "false".
Follow-up for: #30552
This is preparation for #28891, which adds a bunch more helpers around
"struct iovec", at which point this really deserves its own .c/.h file.
The idea is that we sooner or later can consider "struct iovec" as an
entirely generic mechanism to reference some binary blob, and is the
go-to type for this purpose whenever we need one.
Before this commit, $USER, $HOME, $LOGNAME and $SHELL are only
set when User= is set for the unit. For system service, this
results in different behaviors depending on whether User=root is set.
$USER always makes sense on its own, so let's set it unconditionally.
Ideally $HOME should be set too, but it causes trouble when e.g. getty
passes '-p' to login(1), which then doesn't override $HOME. $LOGNAME and
$SHELL are more like "login environments", and are generally not
suitable for system services. Therefore, a new option SetLoginEnvironment=
is also added to control the latter three variables.
Fixes#23438
Replaces #8227
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.
Let's restrict how we apply credential globbing in ImportCredential=, so
that we have some flexibility in automatically extending the glob
expression with per-instance data eventually without getting into
conflict with the globbing parts.
In our current uses we only allow globbing at the end of the expression,
and this is a new, unreleased feature hence let's be restrictive on this
initially. We can still relax this later if we feel the need to after
all.
Fixes: #28022
This setting allows services to run in an ephemeral copy of the root
directory or root image. To make sure the ephemeral copies are always
cleaned up, we add a tmpfiles snippet to unconditionally clean up
/var/lib/systemd/ephemeral. To prevent in use ephemeral copies from
being cleaned up by tmpfiles, we use the newly added COPY_LOCK_BSD
and BTRFS_SNAPSHOT_LOCK_BSD flags to take a BSD lock on the ephemeral
copies which instruct tmpfiles to not touch those ephemeral copies as
long as the BSD lock is held.
This new helper adds all strings from a Set object as a string array to
a message.
Various places where we have similar code are then ported over to this.
ImportCredential= takes a credential name and searches for a matching
credential in all the credential stores we know about it. It supports
globs which are expanded so that all matching credentials are loaded.
This adds support for KSM (kernel samepage merging). It adds a new
boolean parameter called MemoryKSM to enable the feature. The feature
can only be enabled with newer kernels.
The property name is called ExecStartEx, but we have to write it as ExecStart=
in the unit file. :(
Bug introduced in b3d593673c when ex-properties
were initially added.
In addition, we cannot escape $ as $$, because when ":" is used, we wouldn't
unescape $$ back to $.
Oftentimes it is useful to allow the per-service fd store to survive
longer than for a restart. This is useful in various scenarios:
1. An fd to some security relevant object needs to be stashed somewhere,
that should not be cleaned automatically, because the security
enforcement would be dropped then.
2. A user namespace fd should be allocated on first invocation and be
kept around until the user logs out (i.e. systemd --user ends), á la
#16328 (This does not implement what #16318 asks for, but should
solve the use-case discussed there.)
3. There's interest in allow a concept of "userspace reboots" where the
kernel stays running, and userspace is swapped out (i.e. all services
exit, and the rootfs transitioned into a new version of it) while
keeping some select resources pinned, very similar to how we
implement a switch root. Thus it is useful to allow services to exit,
while leaving their fds around till the very end.
This is exposed through a new FileDescriptorStorePreserve= setting that
is closely modelled after RuntimeDirectoryPreserve= (in fact it reused
the same internal type), since we want similar behaviour in the end, and
quite often they probably want to be used together.
ExecContext has a field that controls the mount propagation flag of the
mounts in the resulting namespace. This is exposed as "MountFlags="
which is super confusing, as it suggests one could control more than
propagation, and that it was actually a flags field. It's an enum
though only, and nothing else.
We might want to rename this externally one day, but given the compat
kludges this requires and the fact this is somewhat nichey it might not
be worth it. But internally let's rename it, as it makes things much
easier to grok, in particular as part of the codebase already exposed
the concept as mount_propagation_flag.
No actual code flow changes, just some renaming.
Define new unit parameter (LogFilterPatterns) to filter logs processed by
journald.
This option is used to store a regular expression which is carried from
PID1 to systemd-journald through a cgroup xattrs:
`user.journald_log_filter_patterns`.
The precise bounds of the scheduling priority depend on the scheduling policy,
so depending on the order in which the two settings are specified the
validation might pass or fail.
When checking the setting only validate the outer range (valid values in general are 0 to 99),
and let the execution fail later if the priority does not match the
specified policy (1 to 99 for RR/FIFO, 0 for the rest).
Fixes https://github.com/systemd/systemd/issues/20320
The very basic functinality of StateDirectory= or friends is creating
specified directories. That should work if one entry is a subdirectory
of another. However, it does not when combined with DynamicUser=yes.
To support such case, this adds ExecDirectoryItem.only_create flag, and
if it is set PID1 only create private directory, and not create the symlink
to the private directory.
Fixes#24783.
When some transient unit setting is received over D-Bus, we write it it to a
transient unit file. We escape backslashes and specifiers. For most settings
this is enough, because most settings only do parsing and interpolation of
specifiers. When systemd-run is called (or something equivalent that gives us a
command strv), we write ExecStart=, but when reading it, we not only do parsing
and interpolation of specifiers, but also split on semicolons and do variable
substitution. This results in an ugly situation where the commandline is
interpolated twice, once on the caller side, and once in the manager.
I think we need to treat this as a bug: current behaviour seems to be an
accident of implementation and hard to explain in a reasonable way. If we
*were* doing specifier expansion, then it'd be somewhat reasonable so say that
"the commandline is handled the same as ExecStart=". But since we explicitly
prevent specifier expansion, we best we could say is "the commandline has some
subset of features of ExecStart=". I think this is not useful, and unexpected
by users. Since most people use use a shell to call systemd-run, one level of
variable expansion is already done on the caller side, and having to take into
account another level of expansion (with slightly different rules), creates a
big mental overhead when the commandline needs to include a dollar character or
such. Not doing any expansion is much cleaner and easier to explain or use.
Thus I think it's better to change behaviour here, even though in principle
some people could be relying on current behaviour. I think it's more likely
that nobody noticed, because people generally don't use systemd-run for
complicated commandlines.
Thus this commit adds an additional mode of escaping that prevents variable
explansion and other elements of ExecStart= syntax. I looked over all the
places where unit_escape_setting() is called, and I think that only two need to
be changed to use the new flag.
Fixes#23631.
This was a trivial wrapper that didn't provide any added value. With more
complicated structures like strvs, hashmaps, sets, and arrays, it is possible
to have an empty container. But in case of a list, the list is empty only when
the head is missing.
Also, we generally want the positive condition, so we replace many
if (!LIST_IS_EMPTY(x)) with just if (x).
This reverts PR #22587 and its follow-up commit. More specifically,
2299b1cae3 (partially),
e176f855278d5098d3fecc5aa24ba702147d42e0,
ceb46a31a01b3d3d1d6095d857e29ea214a2776b, and
51bb9076ab8c050bebb64db5035852385accda35.
The PR was merged without final approval, and has several issues:
- OSS fuzz reported issues in the conf parser,
- It calls synchrnous netlink call, it should not be especially in PID1,
- The importance of NFTSet for CGroup and DynamicUser may be
questionable, at least, there was no justification PID1 should support
it.
- For networkd, it should be implemented with Request object,
- There is no test for the feature.
Fixes#23711.
Fixes#23717.
Fixes#23719.
Fixes#23720.
Fixes#23721.
Fixes#23759.
Follow-up for 68acc1afbe.
Before the commit, SystemCallFilter bus property provides only allowed
syscalls if ExecContext.syscall_filter is an allow-list, and vice versa.
After the commit, if the list is allow-list, it contains allowed
syscalls with value `-1`, and denied syscalls with non-negative values.
To keep the backward compatibility, denied syscalls must be dropped in
SystemCallFilter bus property.
New directive `DynamicUserNFTSet=` provides a method for integrating
configuration of dynamic users into firewall rules with NFT sets.
Example:
```
table inet filter {
set u {
typeof meta skuid
}
chain service_output {
meta skuid != @u drop
accept
}
}
```
```
/etc/systemd/system/dunft.service
[Service]
DynamicUser=yes
DynamicUserNFTSet=inet:filter:u
ExecStart=/bin/sleep 1000
[Install]
WantedBy=multi-user.target
```
```
$ sudo nft list set inet filter u
table inet filter {
set u {
typeof meta skuid
elements = { 64864 }
}
}
$ ps -n --format user,group,pid,command -p `pgrep sleep`
USER GROUP PID COMMAND
64864 64864 55158 /bin/sleep 1000
```
Add a new setting that follows the same principle and implementation
as ExtensionImages, but using directories as sources.
It will be used to implement support for extending portable images
with directories, since portable services can already use a directory
as root.
When combined with a tmpfs on /run or /var/lib, allows to create
arbitrary and ephemeral symlinks for StateDirectory or RuntimeDirectory.
This is especially useful when sharing these directories between
different services, to make the same state/runtime directory 'backend'
appear as different names to each service, so that they can be added/removed
to a sharing agreement transparently, without code changes.
An example (simplified, but real) use case:
foo.service:
StateDirectory=foo
bar.service:
StateDirectory=bar
foo.service.d/shared.conf:
StateDirectory=
StateDirectory=shared:foo
bar.service.d/shared.conf:
StateDirectory=
StateDirectory=shared:bar
foo and bar use respectively /var/lib/foo and /var/lib/bar. Then
the orchestration layer decides to stop this sharing, the drop-in
can be removed. The services won't need any update and will keep
working and being able to store state, transparently.
To keep backward compatibility, new DBUS messages are added.
Let's define two helpers strdupa_safe() + strndupa_safe() which do the
same as their non-safe counterparts, except that they abort if called
with allocations larger than ALLOCA_MAX.
This should ensure that all our alloca() based allocations are subject
to this limit.
afaics glibc offers three alloca() based APIs: alloca() itself,
strndupa() + strdupa(). With this we have now replacements for all of
them, that take the limit into account.