1
0
mirror of https://github.com/systemd/systemd synced 2025-11-20 17:24:45 +01:00

Compare commits

..

25 Commits

Author SHA1 Message Date
Mike Yuan
28aa0a1f25
core/mount: properly handle REMOUNTING_* states in mount_stop() (#39269) 2025-10-16 20:50:03 +02:00
Matteo Croce
e1e16b4763
core: fix build error due to merge conflict in varlink-execute.h
During last refactor, an include wasn't changed and led to a build
error.

Follow-up for fdb2c0dd6f02f63f6d398ab6729aa59c023e57b6
2025-10-16 19:47:40 +01:00
Luca Boccassi
c92b14ec13
dissect: add support for verity-protected bare filesystems via mountfsd (#39325)
Needed to implement support for RootHashSignature=/RootVerity=/RootHash=
and friends when going through mountfsd, for example with user units,
so that system and user units provide the same features at the same
level
2025-10-16 19:43:45 +01:00
Zbigniew Jędrzejewski-Szmek
48aec295a8 test/parse_hwdb: wrap Or inside an And in a Group
I now get a warning like this with python3-pyparsing-3.1.2-8.fc42:

hwdb.d/parse_hwdb.py:208: UserWarning: warn_multiple_tokens_in_named_alternation:
  setting results name 'VALUE' on Or expression will return a list of all parsed
  tokens in an And alternative, in prior versions only the first token was returned;
  enclose contained argument in Group
('!' ^ (Optional('!') - Word(alphanums + '_')))('VALUE')
2025-10-16 18:09:37 +01:00
Daan De Meyer
06d73c5046
implement ExecContext for io.systemd.Unit.List (#38212) 2025-10-16 19:06:46 +02:00
Lennart Poettering
b0c6d129a5
two small varlink additions (#39323)
Split out of #39293, but make a ton of sense on their own.
2025-10-16 17:42:57 +02:00
Lennart Poettering
0aad728daa kmod-setup: don't load unix.ko as a module anymore
Building unix.ko as a module always has been a really bad idea, from day
1. Debian used to do this, but has long been fixed. Kernel developers
saw the light too, and removed support for it in 6.5
(97154bcf4d1b7cabefec8a72cff5fbb91d5afb7b). Let's hence drop support for
this here too, and delete some old cruft. AF_UNIX is simply our most
basic IPC system and supporting systems without it being around is just
not realistic.
2025-10-16 17:42:33 +02:00
Luca Boccassi
bc019f7c06 test: add coverage for image policy and bare filesystems with verity 2025-10-16 16:22:33 +01:00
Luca Boccassi
fad01f798d dissect: add support for verity-protected bare filesystems via mountfsd
Needed to implement support for RootHashSignature=/RootVerity=/RootHash=
and friends when going through mountfsd, for example with user units,
so that system and user units provide the same features at the same
level
2025-10-16 16:22:33 +01:00
Luca Boccassi
674b4b4f96 mountfsd: add support for verity-protected bare filesystems
Add optional varlink parameters to pass in verity data/roothash/sig
2025-10-16 16:22:33 +01:00
Luca Boccassi
26bf1b9e85 json: add json_dispatch_unhex_iovec helper 2025-10-16 16:22:33 +01:00
Luca Boccassi
5e97d50e17 dissect: fix image policy check for bare dm-verity filesystem
The root_hash_sig pointer might be set, but to an empty iovec. Check
that the length is > 0 instead.

Follow-up for cd22d8562dd085f5c234cf26b4dd773029418833
2025-10-16 15:50:45 +01:00
Luca Boccassi
39175477bd mkosi: provide detached verity signatures too for minimal images
Useful for manual testing in the VM
2025-10-16 15:50:45 +01:00
Lennart Poettering
78a135f567 varlink: move definition of varlink_hash_ops into common code
This is truly useful whenever we have to deal with multiple varlink
connections.
2025-10-16 16:24:29 +02:00
Lennart Poettering
73740ca2fc sd-varlink: add sd_varlink_is_connected() 2025-10-16 16:24:29 +02:00
Ivan Kruglov
55eccf3b0d core: add comments in varlink-io.systemd.Unit.c 2025-10-16 03:52:08 -07:00
Ivan Kruglov
fdb2c0dd6f core: ExecContext for io.systemd.Unit.List method 2025-10-16 03:52:08 -07:00
Ivan Kruglov
3064c04473 core: exec_log_level_max_with_exec_params() 2025-10-16 03:52:08 -07:00
Ivan Kruglov
fbfc439438 core: move cpuset_build_json() to varlink-common 2025-10-16 03:52:02 -07:00
Ivan Kruglov
3de607b48b basic: secure_bits_to_strv() 2025-10-16 03:29:14 -07:00
Ivan Kruglov
115083886a nsflags: namespace_flags_to_strv() 2025-10-16 03:26:39 -07:00
Ivan Kruglov
0033d937c7 json: helper macro JSON_BUILD_PAIR_YES_NO() 2025-10-15 09:14:10 -07:00
Ivan Kruglov
aacfa999dd json: helper macros JSON_BUILD_PAIR_CONDITION_*() 2025-10-15 09:14:10 -07:00
Mike Yuan
6ebb91d92f
core/mount: properly handle REMOUNTING_* states in mount_stop()
Currently, mount_stop() simply turns REMOUNTING_* into corresponding
UNMOUNTING_* states. However the transition is bogus, because
the interruption of remount does not bring down the mount.
Let's instead follow the logic of service_stop(), i.e. terminate
the remount process and spawn umount.
2025-10-09 18:32:18 +02:00
Mike Yuan
a8fe8e8344
core/mount: remove one more unused temporary variable
Similar to 3cea9c403c6d5ff0edb2b8fc99884f2243b1456e,
but for mount_get_what_escaped().
2025-10-09 18:24:56 +02:00
38 changed files with 1886 additions and 100 deletions

View File

@ -205,7 +205,7 @@ def property_grammar():
for name, val in props]
kbd_props = [Regex(r'KEYBOARD_KEY_[0-9a-f]+')('NAME')
- Suppress('=') -
('!' ^ (Optional('!') - Word(alphanums + '_')))('VALUE')
Group('!' ^ (Optional('!') - Word(alphanums + '_')))('VALUE')
]
abs_props = [Regex(r'EVDEV_ABS_[0-9a-f]{2}')('NAME')
- Suppress('=') -

View File

@ -912,6 +912,7 @@ manpages = [
'sd_uid_get_sessions',
'sd_uid_is_on_seat'],
'HAVE_PAM'],
['sd_varlink_is_connected', '3', ['sd_varlink_is_idle'], ''],
['sd_varlink_push_fd', '3', ['sd_varlink_push_dup_fd'], ''],
['sd_varlink_send', '3', ['sd_varlink_sendb', 'sd_varlink_sendbo'], ''],
['sd_varlink_server_new', '3', [], ''],

View File

@ -0,0 +1,93 @@
<?xml version='1.0'?>
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
<refentry id="sd_varlink_is_connected" xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>
<title>sd_varlink_is_connected</title>
<productname>systemd</productname>
</refentryinfo>
<refmeta>
<refentrytitle>sd_varlink_is_connected</refentrytitle>
<manvolnum>3</manvolnum>
</refmeta>
<refnamediv>
<refname>sd_varlink_is_connected</refname>
<refname>sd_varlink_is_idle</refname>
<refpurpose>Query if a Varlink connection object is currently connected or idle</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcsynopsisinfo>#include &lt;systemd/sd-varlink.h&gt;</funcsynopsisinfo>
<funcprototype>
<funcdef>int <function>sd_varlink_is_connected</function></funcdef>
<paramdef>sd_varlink *<parameter>link</parameter></paramdef>
</funcprototype>
<funcprototype>
<funcdef>int <function>sd_varlink_is_idle</function></funcdef>
<paramdef>sd_varlink *<parameter>link</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para><function>sd_varlink_is_connected()</function> checks whether the specified Varlink connection
object is currently connected or whether it has been fully disconnected already.</para>
<para><function>sd_varlink_is_idle()</function> checks whether the specified Varlink connection object is
currently connected but idle, i.e. may accept a method call for enqueuing (if client side of a Varlink
connection) or is waiting for more incoming method calls to arrive (if server side of a Varlink
connection).</para>
</refsect1>
<refsect1>
<title>Return Value</title>
<para>If the connection is currently connected <function>sd_varlink_is_connected()</function> returns a
positive non-zero value. If disconnected it returns 0. If the connection currently is idle
<function>sd_varlink_is_idle()</function> returns a positive non-zero integer. If not, returns 0. On
failure, both functions return a negative <varname>errno</varname> error code.</para>
<refsect2>
<title>Errors</title>
<para>Returned errors may indicate the following problems:</para>
<variablelist>
<varlistentry>
<term><constant>-EINVAL</constant></term>
<listitem><para>The specified Varlink connection is invalid.</para></listitem>
</varlistentry>
</variablelist>
</refsect2>
</refsect1>
<xi:include href="libsystemd-pkgconfig.xml" />
<refsect1>
<title>History</title>
<para><function>sd_varlink_is_connected()</function> was added in version 259.</para>
<para><function>sd_varlink_is_idle()</function> was added in version 257.</para>
</refsect1>
<refsect1>
<title>See Also</title>
<para><simplelist type="inline">
<member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>sd-varlink</refentrytitle><manvolnum>3</manvolnum></citerefentry></member>
</simplelist></para>
</refsect1>
</refentry>

View File

@ -275,7 +275,7 @@
image. There's currently no option to configure the root hash for the <filename>/usr/</filename> file
system via the unit file directly.</para>
<xi:include href="system-only.xml" xpointer="singular"/>
<xi:include href="system-or-user-ns-mountfsd.xml" xpointer="singular"/>
<xi:include href="version-info.xml" xpointer="v246"/></listitem>
</varlistentry>
@ -298,7 +298,7 @@
configure the root hash signature for the <filename>/usr/</filename> via the unit file
directly.</para>
<xi:include href="system-only.xml" xpointer="singular"/>
<xi:include href="system-or-user-ns-mountfsd.xml" xpointer="singular"/>
<xi:include href="version-info.xml" xpointer="v246"/></listitem>
</varlistentry>
@ -319,7 +319,7 @@
<ulink url="https://uapi-group.org/specifications/specs/discoverable_partitions_specification">
Discoverable Partitions Specification</ulink>.</para>
<xi:include href="system-only.xml" xpointer="singular"/>
<xi:include href="system-or-user-ns-mountfsd.xml" xpointer="singular"/>
<xi:include href="version-info.xml" xpointer="v246"/></listitem>
</varlistentry>

View File

@ -28,6 +28,7 @@ rm -f /etc/resolv.conf
for f in "$BUILDROOT"/usr/share/*.verity.sig; do
jq --join-output '.rootHash' "$f" >"${f%.verity.sig}.roothash"
jq --join-output '.signature' "$f" | base64 --decode >"${f%.verity.sig}.roothash.p7s"
done
# We want /var/log/journal to be created on first boot so it can be created with the right chattr settings by

View File

@ -366,13 +366,17 @@ const char* exec_get_private_notify_socket_path(const ExecContext *context, cons
return "/run/host/notify";
}
int exec_log_level_max(const ExecContext *context, const ExecParameters *params) {
assert(context);
int exec_log_level_max_with_exec_params(const ExecContext *context, const ExecParameters *params) {
assert(params);
if (params->debug_invocation)
return LOG_DEBUG;
return exec_log_level_max(context);
}
int exec_log_level_max(const ExecContext *context) {
assert(context);
return context->log_level_max < 0 ? log_get_max_level() : context->log_level_max;
}

View File

@ -633,7 +633,8 @@ bool exec_is_cgroup_mount_read_only(const ExecContext *context);
const char* exec_get_private_notify_socket_path(const ExecContext *context, const ExecParameters *params, bool needs_sandboxing);
int exec_log_level_max(const ExecContext *context, const ExecParameters *params);
int exec_log_level_max_with_exec_params(const ExecContext *context, const ExecParameters *params);
int exec_log_level_max(const ExecContext *context);
/* These logging macros do the same logging as those in unit.h, but using ExecContext and ExecParameters
* instead of the unit object, so that it can be used in the sd-executor context (where the unit object is
@ -655,7 +656,7 @@ int exec_log_level_max(const ExecContext *context, const ExecParameters *params)
LOG_CONTEXT_PUSH_KEY_VALUE(LOG_EXEC_ID_FIELD(p), p->unit_id); \
LOG_CONTEXT_PUSH_KEY_VALUE(LOG_EXEC_INVOCATION_ID_FIELD(p), p->invocation_id_string); \
LOG_CONTEXT_PUSH_IOV(c->log_extra_fields, c->n_log_extra_fields) \
LOG_CONTEXT_SET_LOG_LEVEL(exec_log_level_max(c, p)) \
LOG_CONTEXT_SET_LOG_LEVEL(exec_log_level_max_with_exec_params(c, p)) \
LOG_SET_PREFIX(p->unit_id);
#define LOG_CONTEXT_PUSH_EXEC(ec, ep) \

View File

@ -112,9 +112,6 @@ int kmod_setup(void) {
* we try to configure ::1 on the loopback device. */
{ "ipv6", "/sys/module/ipv6", false, true, NULL },
/* This should never be a module */
{ "unix", "/proc/net/unix", true, true, NULL },
/* virtio_rng would be loaded by udev later, but real entropy might be needed very early */
{ "virtio_rng", NULL, false, false, has_virtio_rng },

View File

@ -66,6 +66,7 @@ libcore_sources = files(
'varlink-cgroup.c',
'varlink-common.c',
'varlink-dynamic-user.c',
'varlink-execute.c',
'varlink-manager.c',
'varlink-unit.c',
)

View File

@ -1390,6 +1390,7 @@ static int mount_start(Unit *u) {
static int mount_stop(Unit *u) {
Mount *m = ASSERT_PTR(MOUNT(u));
int r;
switch (m->state) {
@ -1401,21 +1402,22 @@ static int mount_stop(Unit *u) {
case MOUNT_MOUNTING:
case MOUNT_MOUNTING_DONE:
case MOUNT_REMOUNTING:
/* If we are still waiting for /bin/mount, we go directly into kill mode. */
mount_enter_signal(m, MOUNT_UNMOUNTING_SIGTERM, MOUNT_SUCCESS);
return 0;
case MOUNT_REMOUNTING:
case MOUNT_REMOUNTING_SIGTERM:
/* If we are already waiting for a hung remount, convert this to the matching unmounting state */
mount_set_state(m, MOUNT_UNMOUNTING_SIGTERM);
return 0;
assert(pidref_is_set(&m->control_pid));
r = pidref_kill_and_sigcont(&m->control_pid, SIGKILL);
if (r < 0)
log_unit_debug_errno(u, r,
"Failed to kill remount process " PID_FMT ", ignoring: %m",
m->control_pid.pid);
_fallthrough_;
case MOUNT_REMOUNTING_SIGKILL:
/* as above */
mount_set_state(m, MOUNT_UNMOUNTING_SIGKILL);
return 0;
case MOUNT_MOUNTED:
mount_enter_unmounting(m);
return 1;
@ -2415,7 +2417,6 @@ char* mount_get_where_escaped(const Mount *m) {
}
char* mount_get_what_escaped(const Mount *m) {
_cleanup_free_ char *escaped = NULL;
const char *s = NULL;
assert(m);
@ -2424,14 +2425,10 @@ char* mount_get_what_escaped(const Mount *m) {
s = m->parameters_proc_self_mountinfo.what;
else if (m->from_fragment && m->parameters_fragment.what)
s = m->parameters_fragment.what;
if (!s)
return strdup("");
if (s) {
escaped = utf8_escape_invalid(s);
if (!escaped)
return NULL;
}
return escaped ? TAKE_PTR(escaped) : strdup("");
return utf8_escape_invalid(s);
}
char* mount_get_options_escaped(const Mount *m) {

View File

@ -2604,6 +2604,7 @@ int setup_namespace(const NamespaceParameters *p, char **reterr_path) {
p->root_image,
userns_fd,
p->root_image_policy,
p->verity,
dissect_image_flags,
&dissected_image);
if (r < 0)

View File

@ -4,7 +4,6 @@
#include "bpf-program.h"
#include "cgroup.h"
#include "cpu-set-util.h"
#include "json-util.h"
#include "in-addr-prefix-util.h"
#include "ip-protocol-list.h"
@ -12,35 +11,7 @@
#include "set.h"
#include "unit.h"
#include "varlink-cgroup.h"
#define JSON_BUILD_PAIR_CONDITION_UNSIGNED(condition, name, value) \
SD_JSON_BUILD_PAIR_CONDITION(condition, name, SD_JSON_BUILD_UNSIGNED(value))
static int cpu_set_build_json(sd_json_variant **ret, const char *name, void *userdata) {
_cleanup_free_ uint8_t *array = NULL;
CPUSet *cpuset = ASSERT_PTR(userdata);
size_t allocated;
int r;
assert(ret);
assert(name);
if (!cpuset->set)
goto empty;
r = cpu_set_to_dbus(cpuset, &array, &allocated);
if (r < 0)
return log_debug_errno(r, "Failed to call cpu_set_to_dbus(): %m");
if (allocated == 0)
goto empty;
return sd_json_variant_new_array_bytes(ret, array, allocated);
empty:
*ret = NULL;
return 0;
}
#include "varlink-common.h"
static int tasks_max_build_json(sd_json_variant **ret, const char *name, void *userdata) {
CGroupTasksMax *tasks_max = ASSERT_PTR(userdata);
@ -283,8 +254,8 @@ int unit_cgroup_context_build_json(sd_json_variant **ret, const char *name, void
JSON_BUILD_PAIR_UNSIGNED_NOT_EQUAL("StartupCPUWeight", c->startup_cpu_weight, CGROUP_WEIGHT_INVALID),
JSON_BUILD_PAIR_FINITE_USEC("CPUQuotaPerSecUSec", c->cpu_quota_per_sec_usec),
JSON_BUILD_PAIR_FINITE_USEC("CPUQuotaPeriodUSec", c->cpu_quota_period_usec),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("AllowedCPUs", cpu_set_build_json, &c->cpuset_cpus),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("StartupAllowedCPUs", cpu_set_build_json, &c->startup_cpuset_cpus),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("AllowedCPUs", cpuset_build_json, &c->cpuset_cpus),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("StartupAllowedCPUs", cpuset_build_json, &c->startup_cpuset_cpus),
/* Memory Accounting and Control */
SD_JSON_BUILD_PAIR_BOOLEAN("MemoryAccounting", c->memory_accounting),
@ -303,8 +274,8 @@ int unit_cgroup_context_build_json(sd_json_variant **ret, const char *name, void
JSON_BUILD_PAIR_UNSIGNED_NOT_EQUAL("MemoryZSwapMax", c->memory_zswap_max, CGROUP_LIMIT_MAX),
JSON_BUILD_PAIR_CONDITION_UNSIGNED(c->startup_memory_zswap_max_set, "StartupMemoryZSwapMax", c->startup_memory_zswap_max),
SD_JSON_BUILD_PAIR_BOOLEAN("MemoryZSwapWriteback", c->memory_zswap_writeback),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("AllowedMemoryNodes", cpu_set_build_json, &c->cpuset_mems),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("StartupAllowedMemoryNodes", cpu_set_build_json, &c->startup_cpuset_mems),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("AllowedMemoryNodes", cpuset_build_json, &c->cpuset_mems),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("StartupAllowedMemoryNodes", cpuset_build_json, &c->startup_cpuset_mems),
/* Process Accounting and Control */
SD_JSON_BUILD_PAIR_BOOLEAN("TasksAccounting", c->tasks_accounting),
@ -478,7 +449,7 @@ static int effective_cpuset_build_json(sd_json_variant **ret, const char *name,
if (r < 0)
return log_debug_errno(r, "Failed to get cpu set '%s': %m", cpuset_name);
return cpu_set_build_json(ret, name, &cpus);
return cpuset_build_json(ret, name, &cpus);
}
static inline int effective_cpus_build_json(sd_json_variant **ret, const char *name, void *userdata) {

View File

@ -1,5 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "cpu-set-util.h"
#include "json-util.h"
#include "rlimit-util.h"
#include "varlink-common.h"
@ -54,3 +55,28 @@ int rlimit_table_build_json(sd_json_variant **ret, const char *name, void *userd
return 0;
}
int cpuset_build_json(sd_json_variant **ret, const char *name, void *userdata) {
_cleanup_free_ uint8_t *array = NULL;
CPUSet *cpuset = ASSERT_PTR(userdata);
size_t allocated;
int r;
assert(ret);
if (!cpuset->set)
goto empty;
r = cpu_set_to_dbus(cpuset, &array, &allocated);
if (r < 0)
return log_debug_errno(r, "Failed to serialize cpu set to dbus: %m");
if (allocated == 0)
goto empty;
return sd_json_variant_new_array_bytes(ret, array, allocated);
empty:
*ret = NULL;
return 0;
}

View File

@ -5,3 +5,4 @@
int rlimit_build_json(sd_json_variant **ret, const char *name, void *userdata);
int rlimit_table_build_json(sd_json_variant **ret, const char *name, void *userdata);
int cpuset_build_json(sd_json_variant **ret, const char *name, void *userdata);

957
src/core/varlink-execute.c Normal file
View File

@ -0,0 +1,957 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <unistd.h>
#include "sd-json.h"
#include "alloc-util.h"
#include "capability-list.h"
#include "dissect-image.h"
#include "errno-list.h"
#include "exec-credential.h"
#include "execute.h"
#include "image-policy.h"
#include "ioprio-util.h"
#include "json-util.h"
#include "manager.h"
#include "mountpoint-util.h"
#include "namespace.h"
#include "nsflags.h"
#include "ordered-set.h"
#include "process-util.h"
#include "securebits-util.h"
#include "set.h"
#include "strv.h"
#include "syslog-util.h"
#include "unit.h"
#include "varlink-common.h"
#include "varlink-execute.h"
static int working_directory_build_json(sd_json_variant **ret, const char *name, void *userdata) {
ExecContext *c = ASSERT_PTR(userdata);
assert(ret);
assert(name);
const char *wd = c->working_directory_home ? "~" : c->working_directory;
if (!wd) {
*ret = NULL;
return 0;
}
return sd_json_buildo(
ret,
SD_JSON_BUILD_PAIR_STRING("path", wd),
SD_JSON_BUILD_PAIR_BOOLEAN("missingOK", c->working_directory_missing_ok));
}
static int root_image_options_build_json(sd_json_variant **ret, const char *name, void *userdata) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
MountOptions *root_image_options = userdata;
int r;
assert(ret);
assert(name);
LIST_FOREACH(mount_options, m, root_image_options) {
r = sd_json_variant_append_arraybo(
&v,
SD_JSON_BUILD_PAIR_STRING("partitionDesignator", partition_designator_to_string(m->partition_designator)),
SD_JSON_BUILD_PAIR_STRING("options", m->options));
if (r < 0)
return r;
}
*ret = TAKE_PTR(v);
return 0;
}
static int image_policy_build_json(sd_json_variant **ret, const char *name, void *userdata) {
_cleanup_free_ char *s = NULL;
ImagePolicy *policy = userdata;
int r;
assert(ret);
assert(name);
r = image_policy_to_string(policy ?: &image_policy_service, /* simplify= */ true, &s);
if (r < 0)
return log_debug_errno(r, "Failed to convert image policy to string: %m");
return sd_json_variant_new_string(ret, s);
}
static int bind_paths_build_json(sd_json_variant **ret, const char *name, void *userdata) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
ExecContext *c = ASSERT_PTR(userdata);
int r;
assert(ret);
assert(name);
bool ro = strstr(name, "ReadOnly");
FOREACH_ARRAY(i, c->bind_mounts, c->n_bind_mounts) {
if (ro != i->read_only)
continue;
r = sd_json_variant_append_arraybo(
&v,
SD_JSON_BUILD_PAIR_STRING("source", i->source),
SD_JSON_BUILD_PAIR_STRING("destination", i->destination),
SD_JSON_BUILD_PAIR_BOOLEAN("ignoreEnoent", i->ignore_enoent),
SD_JSON_BUILD_PAIR_STRV("options", STRV_MAKE(i->recursive ? "rbind" : "norbind")));
if (r < 0)
return r;
}
*ret = TAKE_PTR(v);
return 0;
}
static int mount_images_build_json(sd_json_variant **ret, const char *name, void *userdata) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
ExecContext *c = ASSERT_PTR(userdata);
int r;
assert(ret);
assert(name);
FOREACH_ARRAY(i, c->mount_images, c->n_mount_images) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *mo = NULL;
LIST_FOREACH(mount_options, m, i->mount_options) {
r = sd_json_variant_append_arraybo(
&mo,
SD_JSON_BUILD_PAIR_STRING("partitionDesignator", partition_designator_to_string(m->partition_designator)),
SD_JSON_BUILD_PAIR_STRING("options", m->options));
if (r < 0)
return r;
}
r = sd_json_variant_append_arraybo(
&v,
SD_JSON_BUILD_PAIR_STRING("source", i->source),
SD_JSON_BUILD_PAIR_STRING("destination", i->destination),
SD_JSON_BUILD_PAIR_BOOLEAN("ignoreEnoent", i->ignore_enoent),
SD_JSON_BUILD_PAIR_VARIANT("mountOptions", mo));
if (r < 0)
return r;
}
*ret = TAKE_PTR(v);
return 0;
}
static int extension_images_build_json(sd_json_variant **ret, const char *name, void *userdata) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
ExecContext *c = ASSERT_PTR(userdata);
int r;
assert(ret);
assert(name);
FOREACH_ARRAY(i, c->extension_images, c->n_extension_images) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *mo = NULL;
LIST_FOREACH(mount_options, m, i->mount_options) {
r = sd_json_variant_append_arraybo(
&mo,
SD_JSON_BUILD_PAIR_STRING("partitionDesignator", partition_designator_to_string(m->partition_designator)),
SD_JSON_BUILD_PAIR_STRING("options", m->options));
if (r < 0)
return r;
}
r = sd_json_variant_append_arraybo(
&v,
SD_JSON_BUILD_PAIR_STRING("source", i->source),
SD_JSON_BUILD_PAIR_BOOLEAN("ignoreEnoent", i->ignore_enoent),
SD_JSON_BUILD_PAIR_VARIANT("mountOptions", mo));
if (r < 0)
return r;
}
*ret = TAKE_PTR(v);
return 0;
}
static int capability_set_build_json(sd_json_variant **ret, const char *name, void *userdata) {
uint64_t capability_set = PTR_TO_INT64(userdata);
_cleanup_strv_free_ char **l = NULL;
int r;
assert(ret);
assert(name);
r = capability_set_to_strv(capability_set, &l);
if (r < 0)
return log_debug_errno(r, "Failed to convert capability set to strv: %m");
if (strv_isempty(l)) {
*ret = NULL;
return 0;
}
return sd_json_variant_new_array_strv(ret, l);
}
static int secure_bits_build_json(sd_json_variant **ret, const char *name, void *userdata) {
int secure_bits = PTR_TO_INT(userdata);
_cleanup_strv_free_ char **l = NULL;
int r;
assert(ret);
assert(name);
r = secure_bits_to_strv(secure_bits, &l);
if (r < 0)
return log_debug_errno(r, "Failed to convert secure bits to strv: %m");
if (strv_isempty(l)) {
*ret = NULL;
return 0;
}
return sd_json_variant_new_array_strv(ret, l);
}
static int rlimit_table_with_defaults_build_json(sd_json_variant **ret, const char *name, void *userdata) {
/* This function is similar rlimit_table_build_json() but it falls back
* to Manager's default if ExecContext doesn't have one. */
/* Note, this is deviation from DBus implementation. DBus falls
* back directly to getrlimit() without considering Manager's defaults */
Unit *u = ASSERT_PTR(userdata);
Manager *m = ASSERT_PTR(u->manager);
ExecContext *c = ASSERT_PTR(unit_get_exec_context(u));
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
int r;
assert(ret);
assert(name);
for (int i = 0; i < _RLIMIT_MAX; i++) {
r = sd_json_variant_merge_objectbo(
&v,
JSON_BUILD_PAIR_CALLBACK_NON_NULL(rlimit_to_string(i), rlimit_build_json, c->rlimit[i] ?: m->defaults.rlimit[i]));
if (r < 0)
return r;
}
*ret = TAKE_PTR(v);
return 0;
}
static int cpu_sched_class_build_json(sd_json_variant **ret, const char *name, void *userdata) {
ExecContext *c = ASSERT_PTR(userdata);
_cleanup_free_ char *s = NULL;
int r;
assert(ret);
assert(name);
int p = exec_context_get_cpu_sched_policy(c);
r = sched_policy_to_string_alloc(p, &s);
if (r < 0)
return log_debug_errno(r, "Failed to convert sched policy to string: %m");
return sd_json_variant_new_string(ret, s);
}
static int cpu_affinity_build_json(sd_json_variant **ret, const char *name, void *userdata) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
_cleanup_(cpu_set_done) CPUSet numa_cpuset = {};
ExecContext *c = ASSERT_PTR(userdata);
CPUSet *s = NULL;
int r;
assert(ret);
assert(name);
bool cpu_affinity_from_numa = exec_context_get_cpu_affinity_from_numa(c);
if (cpu_affinity_from_numa) {
r = numa_to_cpu_set(&c->numa_policy, &numa_cpuset);
if (r < 0)
return log_debug_errno(r, "Failed to convert numa policy to cpu set: %m");
s = &numa_cpuset;
} else
s = &c->cpu_set;
r = cpuset_build_json(&v, /* name= */ NULL, s);
if (r < 0)
return r;
if (!v) {
*ret = NULL;
return 0;
}
return sd_json_buildo(
ret,
SD_JSON_BUILD_PAIR_VARIANT("affinity", v),
SD_JSON_BUILD_PAIR_BOOLEAN("fromNUMA", cpu_affinity_from_numa));
}
static int numa_policy_build_json(sd_json_variant **ret, const char *name, void *userdata) {
ExecContext *c = ASSERT_PTR(userdata);
assert(ret);
assert(name);
int t = numa_policy_get_type(&c->numa_policy);
if (!mpol_is_valid(t)) {
*ret = NULL;
return 0;
}
return sd_json_variant_new_string(ret, mpol_to_string(t));
}
static int numa_mask_build_json(sd_json_variant **ret, const char *name, void *userdata) {
ExecContext *c = ASSERT_PTR(userdata);
assert(ret);
assert(name);
int t = numa_policy_get_type(&c->numa_policy);
if (!mpol_is_valid(t)) {
*ret = NULL;
return 0;
}
return cpuset_build_json(ret, /* name= */ NULL, &c->numa_policy.nodes);
}
static int ioprio_class_build_json(sd_json_variant **ret, const char *name, void *userdata) {
ExecContext *c = ASSERT_PTR(userdata);
_cleanup_free_ char *s = NULL;
int r;
assert(ret);
assert(name);
int ioprio = exec_context_get_effective_ioprio(c);
r = ioprio_class_to_string_alloc(ioprio_prio_class(ioprio), &s);
if (r < 0)
return log_debug_errno(r, "Failed to convert IO priority class to string: %m");
return sd_json_variant_new_string(ret, s);
}
static int exec_dir_build_json(sd_json_variant **ret, const char *name, void *userdata) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
ExecDirectory *exec_dir = ASSERT_PTR(userdata);
const QuotaLimit *quota = &exec_dir->exec_quota;
int r;
assert(ret);
assert(name);
if (exec_dir->n_items == 0) {
*ret = NULL;
return 0;
}
FOREACH_ARRAY(dir, exec_dir->items, exec_dir->n_items) {
r = sd_json_variant_append_arraybo(
&v,
SD_JSON_BUILD_PAIR_STRING("path", dir->path),
JSON_BUILD_PAIR_STRV_NON_EMPTY("symlinks", dir->symlinks));
if (r < 0)
return r;
}
return sd_json_buildo(
ret,
SD_JSON_BUILD_PAIR("paths", SD_JSON_BUILD_VARIANT(v)),
SD_JSON_BUILD_PAIR_UNSIGNED("mode", exec_dir->mode),
SD_JSON_BUILD_PAIR("quota",
SD_JSON_BUILD_OBJECT(
SD_JSON_BUILD_PAIR_BOOLEAN("accounting", quota->quota_accounting),
SD_JSON_BUILD_PAIR_BOOLEAN("enforce", quota->quota_enforce),
SD_JSON_BUILD_PAIR_UNSIGNED("quotaAbsolute", quota->quota_absolute),
SD_JSON_BUILD_PAIR_UNSIGNED("quotaScale", quota->quota_scale))));
}
static int temporary_filesystems_build_json(sd_json_variant **ret, const char *name, void *userdata) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
ExecContext *c = ASSERT_PTR(userdata);
int r;
assert(ret);
assert(name);
FOREACH_ARRAY(t, c->temporary_filesystems, c->n_temporary_filesystems) {
r = sd_json_variant_append_arraybo(
&v,
SD_JSON_BUILD_PAIR_STRING("path", t->path),
JSON_BUILD_PAIR_STRING_NON_EMPTY("options", t->options));
if (r < 0)
return r;
}
*ret = TAKE_PTR(v);
return 0;
}
static int address_families_build_json(sd_json_variant **ret, const char *name, void *userdata) {
_cleanup_strv_free_ char **l = NULL;
ExecContext *c = ASSERT_PTR(userdata);
assert(ret);
assert(name);
l = exec_context_get_address_families(c);
if (!l)
return -ENOMEM;
if (strv_isempty(l)) {
*ret = NULL;
return 0;
}
return sd_json_buildo(
ret,
SD_JSON_BUILD_PAIR_BOOLEAN("isAllowList", c->address_families_allow_list),
SD_JSON_BUILD_PAIR_STRV("addressFamilies", l));
}
static int restrict_filesystems_build_json(sd_json_variant **ret, const char *name, void *userdata) {
ExecContext *c = ASSERT_PTR(userdata);
_cleanup_strv_free_ char **l = NULL;
assert(ret);
assert(name);
l = exec_context_get_restrict_filesystems(c);
if (!l)
return -ENOMEM;
if (strv_isempty(l)) {
*ret = NULL;
return 0;
}
return sd_json_buildo(
ret,
SD_JSON_BUILD_PAIR_BOOLEAN("isAllowList", c->restrict_filesystems_allow_list),
SD_JSON_BUILD_PAIR_STRV("filesystems", l));
}
static int namespace_flags_build_json(sd_json_variant **ret, const char *name, void *userdata) {
_cleanup_strv_free_ char **l = NULL;
unsigned long namespaces = PTR_TO_ULONG(userdata);
int r;
assert(ret);
assert(name);
r = namespace_flags_to_strv(namespaces, &l);
if (r < 0)
return log_debug_errno(r, "Failed to convert namespace flags to strv: %m");
if (strv_isempty(l)) {
*ret = NULL;
return 0;
}
return sd_json_variant_new_array_strv(ret, l);
}
static int private_bpf_delegate_commands_build_json(sd_json_variant **ret, const char *name, void *userdata) {
ExecContext *c = ASSERT_PTR(userdata);
_cleanup_free_ char *v = bpf_delegate_commands_to_string(c->bpf_delegate_commands);
if (!v) {
*ret = NULL;
return 0;
}
return sd_json_variant_new_string(ASSERT_PTR(ret), v);
}
static int private_bpf_delegate_maps_build_json(sd_json_variant **ret, const char *name, void *userdata) {
ExecContext *c = ASSERT_PTR(userdata);
_cleanup_free_ char *v = bpf_delegate_maps_to_string(c->bpf_delegate_maps);
if (!v) {
*ret = NULL;
return 0;
}
return sd_json_variant_new_string(ASSERT_PTR(ret), v);
}
static int private_bpf_delegate_programs_build_json(sd_json_variant **ret, const char *name, void *userdata) {
ExecContext *c = ASSERT_PTR(userdata);
_cleanup_free_ char *v = bpf_delegate_programs_to_string(c->bpf_delegate_programs);
if (!v) {
*ret = NULL;
return 0;
}
return sd_json_variant_new_string(ASSERT_PTR(ret), v);
}
static int private_bpf_delegate_attachments_build_json(sd_json_variant **ret, const char *name, void *userdata) {
ExecContext *c = ASSERT_PTR(userdata);
_cleanup_free_ char *v = bpf_delegate_attachments_to_string(c->bpf_delegate_attachments);
if (!v) {
*ret = NULL;
return 0;
}
return sd_json_variant_new_string(ASSERT_PTR(ret), v);
}
static int syscall_filter_build_json(sd_json_variant **ret, const char *name, void *userdata) {
ExecContext *c = ASSERT_PTR(userdata);
_cleanup_strv_free_ char **l = NULL;
assert(ret);
assert(name);
l = exec_context_get_syscall_filter(c);
if (!l)
return -ENOMEM;
if (strv_isempty(l)) {
*ret = NULL;
return 0;
}
return sd_json_buildo(
ret,
SD_JSON_BUILD_PAIR_BOOLEAN("isAllowList", c->syscall_allow_list),
SD_JSON_BUILD_PAIR_STRV("systemCalls", l));
}
static int syscall_error_number_build_json(sd_json_variant **ret, const char *name, void *userdata) {
ExecContext *c = ASSERT_PTR(userdata);
assert(ret);
assert(name);
if (c->syscall_errno == 0) {
*ret = NULL;
return 0;
}
return sd_json_variant_new_string(ret, ERRNO_NAME(c->syscall_errno));
}
static int syscall_archs_build_json(sd_json_variant **ret, const char *name, void *userdata) {
ExecContext *c = ASSERT_PTR(userdata);
_cleanup_strv_free_ char **l = NULL;
assert(ret);
assert(name);
l = exec_context_get_syscall_archs(c);
if (!l)
return -ENOMEM;
if (strv_isempty(l)) {
*ret = NULL;
return 0;
}
return sd_json_variant_new_array_strv(ret, l);
}
static int syscall_log_build_json(sd_json_variant **ret, const char *name, void *userdata) {
ExecContext *c = ASSERT_PTR(userdata);
_cleanup_strv_free_ char **l = NULL;
assert(ret);
assert(name);
l = exec_context_get_syscall_log(c);
if (!l)
return -ENOMEM;
if (strv_isempty(l)) {
*ret = NULL;
return 0;
}
return sd_json_buildo(
ret,
SD_JSON_BUILD_PAIR_BOOLEAN("isAllowList", c->syscall_allow_list),
SD_JSON_BUILD_PAIR_STRV("systemCalls", l));
}
static int environment_files_build_json(sd_json_variant **ret, const char *name, void *userdata) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
char **environment_files = userdata;
int r;
assert(ret);
assert(name);
STRV_FOREACH(j, environment_files) {
const char *fn = *j;
if (isempty(fn))
continue;
r = sd_json_variant_append_arraybo(
&v,
SD_JSON_BUILD_PAIR_STRING("path", fn[0] == '-' ? fn + 1 : fn),
SD_JSON_BUILD_PAIR_BOOLEAN("graceful", fn[0] == '-'));
if (r < 0)
return r;
}
*ret = TAKE_PTR(v);
return 0;
}
static int log_level_build_json(sd_json_variant **ret, const char *name, void *userdata) {
int log_level = PTR_TO_INT(userdata);
_cleanup_free_ char *s = NULL;
int r;
assert(ret);
assert(name);
if (log_level < 0) {
*ret = NULL;
return 0;
}
r = log_level_to_string_alloc(log_level, &s);
if (r < 0)
return log_debug_errno(r, "Failed to convert log level to string: %m");
return sd_json_variant_new_string(ret, s);
}
static int log_extra_fields_build_json(sd_json_variant **ret, const char *name, void *userdata) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
ExecContext *c = ASSERT_PTR(userdata);
int r;
assert(ret);
assert(name);
FOREACH_ARRAY(i, c->log_extra_fields, c->n_log_extra_fields) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *s = NULL;
r = sd_json_variant_new_stringn(&s, i->iov_base, i->iov_len);
if (r < 0)
return r;
r = sd_json_variant_append_array(&v, s);
if (r < 0)
return r;
}
*ret = TAKE_PTR(v);
return 0;
}
static int log_filter_patterns_build_json(sd_json_variant **ret, const char *name, void *userdata) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
ExecContext *c = ASSERT_PTR(userdata);
const char *pattern;
int r;
assert(ret);
assert(name);
SET_FOREACH(pattern, c->log_filter_allowed_patterns) {
r = sd_json_variant_append_arraybo(
&v,
SD_JSON_BUILD_PAIR_BOOLEAN("isAllowList", true),
SD_JSON_BUILD_PAIR_STRING("pattern", pattern));
if (r < 0)
return r;
}
SET_FOREACH(pattern, c->log_filter_denied_patterns) {
r = sd_json_variant_append_arraybo(
&v,
SD_JSON_BUILD_PAIR_BOOLEAN("isAllowList", false),
SD_JSON_BUILD_PAIR_STRING("pattern", pattern));
if (r < 0)
return r;
}
*ret = TAKE_PTR(v);
return 0;
}
static int syslog_facility_build_json(sd_json_variant **ret, const char *name, void *userdata) {
int log_facility = PTR_TO_INT(userdata);
_cleanup_free_ char *s = NULL;
int r;
assert(ret);
assert(name);
r = log_facility_unshifted_to_string_alloc(log_facility, &s);
if (r < 0)
return log_debug_errno(r, "Failed to convert log facility to string: %m");
return sd_json_variant_new_string(ret, s);
}
static int load_credential_build_json(sd_json_variant **ret, const char *name, void *userdata) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
Hashmap *load_credentials = userdata;
ExecLoadCredential *lc;
int r;
assert(ret);
assert(name);
bool encrypted = streq(name, "LoadCredentialEncrypted");
HASHMAP_FOREACH(lc, load_credentials) {
if (lc->encrypted != encrypted)
continue;
r = sd_json_variant_append_arraybo(
&v,
SD_JSON_BUILD_PAIR_STRING("id", lc->id),
SD_JSON_BUILD_PAIR_STRING("path", lc->path));
if (r < 0)
return r;
}
*ret = TAKE_PTR(v);
return 0;
}
static int import_credential_build_json(sd_json_variant **ret, const char *name, void *userdata) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
OrderedSet *import_credentials = userdata;
ExecImportCredential *ic;
int r;
assert(ret);
ORDERED_SET_FOREACH(ic, import_credentials) {
r = sd_json_variant_append_arraybo(
&v,
SD_JSON_BUILD_PAIR_STRING("glob", ic->glob),
JSON_BUILD_PAIR_STRING_NON_EMPTY("rename", ic->rename));
if (r < 0)
return r;
}
*ret = TAKE_PTR(v);
return 0;
}
static int set_credential_build_json(sd_json_variant **ret, const char *name, void *userdata) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
Hashmap *set_credentials = userdata;
ExecSetCredential *sc;
int r;
assert(ret);
assert(name);
bool encrypted = streq(name, "SetCredentialEncrypted");
HASHMAP_FOREACH(sc, set_credentials) {
if (sc->encrypted != encrypted)
continue;
r = sd_json_variant_append_arraybo(
&v,
SD_JSON_BUILD_PAIR_STRING("id", sc->id),
SD_JSON_BUILD_PAIR_BASE64("value", sc->data, sc->size));
if (r < 0)
return r;
}
*ret = TAKE_PTR(v);
return 0;
}
int unit_exec_context_build_json(sd_json_variant **ret, const char *name, void *userdata) {
Unit *u = ASSERT_PTR(userdata);
ExecContext *c = unit_get_exec_context(u);
if (!c) {
*ret = NULL;
return 0;
}
return sd_json_buildo(
ASSERT_PTR(ret),
/* Paths */
JSON_BUILD_PAIR_STRV_NON_EMPTY("ExecSearchPath", c->exec_search_path),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("WorkingDirectory", working_directory_build_json, c),
JSON_BUILD_PAIR_STRING_NON_EMPTY("RootDirectory", c->root_directory),
JSON_BUILD_PAIR_STRING_NON_EMPTY("RootImage", c->root_image),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("RootImageOptions", root_image_options_build_json, c->root_image_options),
SD_JSON_BUILD_PAIR_BOOLEAN("RootEphemeral", c->root_ephemeral),
JSON_BUILD_PAIR_BASE64_NON_EMPTY("RootHash", c->root_hash, c->root_hash_size),
JSON_BUILD_PAIR_STRING_NON_EMPTY("RootHashPath", c->root_hash_path),
JSON_BUILD_PAIR_BASE64_NON_EMPTY("RootHashSignature", c->root_hash_sig, c->root_hash_sig_size),
JSON_BUILD_PAIR_STRING_NON_EMPTY("RootHashSignaturePath", c->root_hash_sig_path),
JSON_BUILD_PAIR_STRING_NON_EMPTY("RootVerity", c->root_verity),
SD_JSON_BUILD_PAIR_CALLBACK("RootImagePolicy", image_policy_build_json, c->root_image_policy),
SD_JSON_BUILD_PAIR_CALLBACK("MountImagePolicy", image_policy_build_json, c->mount_image_policy),
SD_JSON_BUILD_PAIR_CALLBACK("ExtensionImagePolicy", image_policy_build_json, c->extension_image_policy),
JSON_BUILD_PAIR_YES_NO("MountAPIVFS", exec_context_get_effective_mount_apivfs(c)),
SD_JSON_BUILD_PAIR_BOOLEAN("BindLogSockets", exec_context_get_effective_bind_log_sockets(c)),
SD_JSON_BUILD_PAIR_STRING("ProtectProc", protect_proc_to_string(c->protect_proc)),
SD_JSON_BUILD_PAIR_STRING("ProcSubset", proc_subset_to_string(c->proc_subset)),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("BindPaths", bind_paths_build_json, c),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("BindReadOnlyPaths", bind_paths_build_json, c),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("MountImages", mount_images_build_json, c),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("ExtensionImages", extension_images_build_json, c),
JSON_BUILD_PAIR_STRV_NON_EMPTY("ExtensionDirectories", c->extension_directories),
/* User/Group Identity */
JSON_BUILD_PAIR_STRING_NON_EMPTY("User", c->user),
JSON_BUILD_PAIR_STRING_NON_EMPTY("Group", c->group),
SD_JSON_BUILD_PAIR_BOOLEAN("DynamicUser", c->dynamic_user),
JSON_BUILD_PAIR_STRV_NON_EMPTY("SupplementaryGroups", c->supplementary_groups),
JSON_BUILD_PAIR_TRISTATE_NON_NULL("SetLoginEnvironment", c->set_login_environment),
JSON_BUILD_PAIR_STRING_NON_EMPTY("PAMName", c->pam_name),
/* Capabilities */
JSON_BUILD_PAIR_CALLBACK_NON_NULL("CapabilityBoundingSet", capability_set_build_json, INT64_TO_PTR(c->capability_bounding_set)),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("AmbientCapabilities", capability_set_build_json, INT64_TO_PTR(c->capability_ambient_set)),
/* Security */
SD_JSON_BUILD_PAIR_BOOLEAN("NoNewPrivileges", c->no_new_privileges),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("SecureBits", secure_bits_build_json, INT_TO_PTR(c->secure_bits)),
/* Mandatory Access Control */
SD_JSON_BUILD_PAIR_CONDITION(!!c->selinux_context, "SELinuxContext",
SD_JSON_BUILD_OBJECT(
SD_JSON_BUILD_PAIR_BOOLEAN("ignore", c->selinux_context_ignore),
SD_JSON_BUILD_PAIR_STRING("context", c->selinux_context))),
SD_JSON_BUILD_PAIR_CONDITION(!!c->apparmor_profile, "AppArmorProfile",
SD_JSON_BUILD_OBJECT(
SD_JSON_BUILD_PAIR_BOOLEAN("ignore", c->apparmor_profile_ignore),
SD_JSON_BUILD_PAIR_STRING("profile", c->apparmor_profile))),
SD_JSON_BUILD_PAIR_CONDITION(!!c->smack_process_label, "SmackProcessLabel",
SD_JSON_BUILD_OBJECT(
SD_JSON_BUILD_PAIR_BOOLEAN("ignore", c->smack_process_label_ignore),
SD_JSON_BUILD_PAIR_STRING("label", c->smack_process_label))),
/* Process Properties */
SD_JSON_BUILD_PAIR_CALLBACK("Limits", rlimit_table_with_defaults_build_json, u),
JSON_BUILD_PAIR_UNSIGNED_NON_ZERO("UMask", c->umask),
JSON_BUILD_PAIR_UNSIGNED_NON_ZERO("CoredumpFilter", exec_context_get_coredump_filter(c)),
SD_JSON_BUILD_PAIR_STRING("KeyringMode", exec_keyring_mode_to_string(c->keyring_mode)),
JSON_BUILD_PAIR_INTEGER_NON_ZERO("OOMScoreAdjust", exec_context_get_oom_score_adjust(c)),
JSON_BUILD_PAIR_UNSIGNED_NOT_EQUAL("TimerSlackNSec", exec_context_get_timer_slack_nsec(c), NSEC_INFINITY),
JSON_BUILD_PAIR_STRING_NON_EMPTY("Personality", personality_to_string(c->personality)),
SD_JSON_BUILD_PAIR_BOOLEAN("IgnoreSIGPIPE", c->ignore_sigpipe),
/* Scheduling */
SD_JSON_BUILD_PAIR_INTEGER("Nice", exec_context_get_nice(c)),
SD_JSON_BUILD_PAIR_CALLBACK("CPUSchedulingPolicy", cpu_sched_class_build_json, c),
SD_JSON_BUILD_PAIR_INTEGER("CPUSchedulingPriority", exec_context_get_cpu_sched_priority(c)),
SD_JSON_BUILD_PAIR_BOOLEAN("CPUSchedulingResetOnFork", c->cpu_sched_reset_on_fork),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("CPUAffinity", cpu_affinity_build_json, c),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("NUMAPolicy", numa_policy_build_json, c),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("NUMAMask", numa_mask_build_json, c),
SD_JSON_BUILD_PAIR_CALLBACK("IOSchedulingClass", ioprio_class_build_json, c),
SD_JSON_BUILD_PAIR_INTEGER("IOSchedulingPriority", ioprio_prio_data(exec_context_get_effective_ioprio(c))),
/* Sandboxing */
SD_JSON_BUILD_PAIR_STRING("ProtectSystem", protect_system_to_string(c->protect_system)),
SD_JSON_BUILD_PAIR_STRING("ProtectHome", protect_home_to_string(c->protect_home)),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("RuntimeDirectory", exec_dir_build_json, &c->directories[EXEC_DIRECTORY_RUNTIME]),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("StateDirectory", exec_dir_build_json, &c->directories[EXEC_DIRECTORY_STATE]),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("CacheDirectory", exec_dir_build_json, &c->directories[EXEC_DIRECTORY_CACHE]),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("LogsDirectory", exec_dir_build_json, &c->directories[EXEC_DIRECTORY_LOGS]),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("ConfigurationDirectory", exec_dir_build_json, &c->directories[EXEC_DIRECTORY_CONFIGURATION]),
SD_JSON_BUILD_PAIR_STRING("RuntimeDirectoryPreserve", exec_preserve_mode_to_string(c->runtime_directory_preserve_mode)),
JSON_BUILD_PAIR_FINITE_USEC("TimeoutCleanUSec", c->timeout_clean_usec),
JSON_BUILD_PAIR_STRV_NON_EMPTY("ReadWritePaths", c->read_write_paths),
JSON_BUILD_PAIR_STRV_NON_EMPTY("ReadOnlyPaths", c->read_only_paths),
JSON_BUILD_PAIR_STRV_NON_EMPTY("InaccessiblePaths", c->inaccessible_paths),
JSON_BUILD_PAIR_STRV_NON_EMPTY("ExecPaths", c->exec_paths),
JSON_BUILD_PAIR_STRV_NON_EMPTY("NoExecPaths", c->no_exec_paths),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("TemporaryFileSystem", temporary_filesystems_build_json, c),
/* XXX should we make all these Private/Protect strings??? */
SD_JSON_BUILD_PAIR_STRING("PrivateTmp", private_tmp_to_string(c->private_tmp)),
JSON_BUILD_PAIR_YES_NO("PrivateDevices", c->private_devices),
JSON_BUILD_PAIR_YES_NO("PrivateNetwork", c->private_network),
JSON_BUILD_PAIR_STRING_NON_EMPTY("NetworkNamespacePath", c->network_namespace_path),
JSON_BUILD_PAIR_YES_NO("PrivateIPC", c->private_ipc),
JSON_BUILD_PAIR_STRING_NON_EMPTY("IPCNamespacePath", c->ipc_namespace_path),
JSON_BUILD_PAIR_TRISTATE_NON_NULL("MemoryKSM", c->memory_ksm),
SD_JSON_BUILD_PAIR_STRING("PrivatePIDs", private_pids_to_string(c->private_pids)),
SD_JSON_BUILD_PAIR_STRING("PrivateUsers", private_users_to_string(c->private_users)),
SD_JSON_BUILD_PAIR_STRING("ProtectHostname", protect_hostname_to_string(c->protect_hostname)),
JSON_BUILD_PAIR_YES_NO("ProtectClock", c->protect_clock),
JSON_BUILD_PAIR_YES_NO("ProtectKernelTunables", c->protect_kernel_tunables),
JSON_BUILD_PAIR_YES_NO("ProtectKernelModules", c->protect_kernel_modules),
JSON_BUILD_PAIR_YES_NO("ProtectKernelLogs", c->protect_kernel_logs),
SD_JSON_BUILD_PAIR_STRING("ProtectControlGroups", protect_control_groups_to_string(c->protect_control_groups)),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("RestrictAddressFamilies", address_families_build_json, c),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("RestrictFileSystems", restrict_filesystems_build_json, c),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("RestrictNamespaces", namespace_flags_build_json, ULONG_TO_PTR(c->restrict_namespaces)),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("DelegateNamespaces", namespace_flags_build_json, ULONG_TO_PTR(c->delegate_namespaces)),
SD_JSON_BUILD_PAIR_STRING("PrivatePBF", private_bpf_to_string(c->private_bpf)),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("BPFDelegateCommands", private_bpf_delegate_commands_build_json, c),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("BPFDelegateMaps", private_bpf_delegate_maps_build_json, c),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("BPFDelegatePrograms", private_bpf_delegate_programs_build_json, c),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("BPFDelegateAttachments", private_bpf_delegate_attachments_build_json, c),
SD_JSON_BUILD_PAIR_BOOLEAN("LockPersonality", c->lock_personality),
SD_JSON_BUILD_PAIR_BOOLEAN("MemoryDenyWriteExecute", c->memory_deny_write_execute),
SD_JSON_BUILD_PAIR_BOOLEAN("RestrictRealtime", c->restrict_realtime),
SD_JSON_BUILD_PAIR_BOOLEAN("RestrictSUIDSGID", c->restrict_suid_sgid),
SD_JSON_BUILD_PAIR_BOOLEAN("RemoveIPC", c->remove_ipc),
JSON_BUILD_PAIR_TRISTATE_NON_NULL("PrivateMounts", c->private_mounts),
JSON_BUILD_PAIR_STRING_NON_EMPTY("MountFlags", mount_propagation_flag_to_string(c->mount_propagation_flag)),
/* System Call Filtering */
JSON_BUILD_PAIR_CALLBACK_NON_NULL("SystemCallFilter", syscall_filter_build_json, c),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("SystemCallErrorNumber", syscall_error_number_build_json, c),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("SystemCallArchitectures", syscall_archs_build_json, c),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("SystemCallLog", syscall_log_build_json, c),
/* Environment */
JSON_BUILD_PAIR_STRV_NON_EMPTY("Environment", c->environment),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("EnvironmentFiles", environment_files_build_json, c->environment_files),
JSON_BUILD_PAIR_STRV_NON_EMPTY("PassEnvironment", c->pass_environment),
JSON_BUILD_PAIR_STRV_NON_EMPTY("UnsetEnvironment", c->unset_environment),
/* Logging and Standard Input/Output */
SD_JSON_BUILD_PAIR_STRING("StandardInput", exec_input_to_string(c->std_input)),
SD_JSON_BUILD_PAIR_STRING("StandardOutput", exec_output_to_string(c->std_output)),
SD_JSON_BUILD_PAIR_STRING("StandardError", exec_output_to_string(c->std_error)),
JSON_BUILD_PAIR_STRING_NON_EMPTY("StandardInputFileDescriptorName", exec_context_fdname(c, STDIN_FILENO)),
JSON_BUILD_PAIR_STRING_NON_EMPTY("StandardOutputFileDescriptorName", exec_context_fdname(c, STDOUT_FILENO)),
JSON_BUILD_PAIR_STRING_NON_EMPTY("StandardErrorFileDescriptorName", exec_context_fdname(c, STDERR_FILENO)),
JSON_BUILD_PAIR_BASE64_NON_EMPTY("StandardInputData", c->stdin_data, c->stdin_data_size),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("LogLevelMax", log_level_build_json, INT_TO_PTR(exec_log_level_max(c))),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("LogExtraFields", log_extra_fields_build_json, c),
JSON_BUILD_PAIR_RATELIMIT_ENABLED("LogRateLimit", &c->log_ratelimit),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("LogFilterPatterns", log_filter_patterns_build_json, c),
JSON_BUILD_PAIR_STRING_NON_EMPTY("LogNamespace", c->log_namespace),
JSON_BUILD_PAIR_STRING_NON_EMPTY("SyslogIdentifier", c->syslog_identifier),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("SyslogFacility", syslog_facility_build_json, INT_TO_PTR(LOG_FAC(c->syslog_priority))),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("SyslogLevel", log_level_build_json, INT_TO_PTR(LOG_PRI(c->syslog_priority))),
SD_JSON_BUILD_PAIR_BOOLEAN("SyslogLevelPrefix", c->syslog_level_prefix),
JSON_BUILD_PAIR_STRING_NON_EMPTY("TTYPath", c->tty_path),
JSON_BUILD_PAIR_CONDITION_BOOLEAN(!!c->tty_path, "TTYReset", c->tty_reset),
JSON_BUILD_PAIR_CONDITION_BOOLEAN(!!c->tty_path, "TTYVHangup", c->tty_vhangup),
JSON_BUILD_PAIR_CONDITION_UNSIGNED(!!c->tty_path, "TTYRows", c->tty_rows),
JSON_BUILD_PAIR_CONDITION_UNSIGNED(!!c->tty_path, "TTYColumns", c->tty_cols),
JSON_BUILD_PAIR_CONDITION_BOOLEAN(!!c->tty_path, "TTYVTDisallocate", c->tty_vt_disallocate),
/* Credentials */
JSON_BUILD_PAIR_CALLBACK_NON_NULL("LoadCredential", load_credential_build_json, c->load_credentials),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("LoadCredentialEncrypted", load_credential_build_json, c->load_credentials),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("ImportCredential", import_credential_build_json, c->import_credentials),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("SetCredential", set_credential_build_json, c->set_credentials),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("SetCredentialEncrypted", set_credential_build_json, c->set_credentials),
/* System V Compatibility */
JSON_BUILD_PAIR_STRING_NON_EMPTY("UtmpIdentifier", c->utmp_id),
SD_JSON_BUILD_PAIR_STRING("UtmpMode", exec_utmp_mode_to_string(c->utmp_mode)));
}

View File

@ -0,0 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include "shared-forward.h"
int unit_exec_context_build_json(sd_json_variant **ret, const char *name, void *userdata);

View File

@ -14,6 +14,8 @@
#include "strv.h"
#include "unit.h"
#include "varlink-cgroup.h"
#include "varlink-common.h"
#include "varlink-execute.h"
#include "varlink-unit.h"
#include "varlink-util.h"
@ -182,8 +184,8 @@ static int unit_context_build_json(sd_json_variant **ret, const char *name, void
SD_JSON_BUILD_PAIR_BOOLEAN("Perpetual", u->perpetual),
SD_JSON_BUILD_PAIR_BOOLEAN("DebugInvocation", u->debug_invocation),
/* CGroup */
JSON_BUILD_PAIR_CALLBACK_NON_NULL("CGroup", unit_cgroup_context_build_json, u));
JSON_BUILD_PAIR_CALLBACK_NON_NULL("CGroup", unit_cgroup_context_build_json, u),
JSON_BUILD_PAIR_CALLBACK_NON_NULL("Exec", unit_exec_context_build_json, u));
// TODO follow up PRs:
// JSON_BUILD_PAIR_CALLBACK_NON_NULL("Exec", exec_context_build_json, u)

View File

@ -2311,6 +2311,7 @@ static int run(int argc, char *argv[]) {
arg_image,
userns_fd,
arg_image_policy,
&arg_verity_settings,
arg_flags,
&m);
if (r < 0)

View File

@ -130,8 +130,6 @@ static const char* const transfer_type_table[_TRANSFER_TYPE_MAX] = {
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(transfer_type, TransferType);
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(varlink_hash_ops, void, trivial_hash_func, trivial_compare_func, sd_varlink, sd_varlink_unref);
static Transfer *transfer_unref(Transfer *t) {
if (!t)
return NULL;

View File

@ -1078,3 +1078,8 @@ global:
sd_varlink_reset_fds;
sd_varlink_server_listen_name;
} LIBSYSTEMD_257;
LIBSYSTEMD_259 {
global:
sd_varlink_is_connected;
} LIBSYSTEMD_258;

View File

@ -25,6 +25,24 @@
#include "unit-name.h"
#include "user-util.h"
int json_dispatch_unhex_iovec(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata) {
_cleanup_free_ void *buffer = NULL;
struct iovec *iov = ASSERT_PTR(userdata);
size_t sz;
int r;
if (!sd_json_variant_is_string(variant))
return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a string.", strna(name));
r = sd_json_variant_unhex(variant, &buffer, &sz);
if (r < 0)
return json_log(variant, flags, r, "JSON field '%s' is not valid hex data.", strna(name));
free_and_replace(iov->iov_base, buffer);
iov->iov_len = sz;
return 0;
}
int json_dispatch_unbase64_iovec(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata) {
_cleanup_free_ void *buffer = NULL;
struct iovec *iov = ASSERT_PTR(userdata);

View File

@ -108,6 +108,7 @@ int json_log_internal(sd_json_variant *variant, int level, int error, const char
#define json_log_oom(variant, flags) \
json_log(variant, flags, SYNTHETIC_ERRNO(ENOMEM), "Out of memory.")
int json_dispatch_unhex_iovec(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
int json_dispatch_unbase64_iovec(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
int json_dispatch_byte_array_iovec(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
int json_dispatch_user_group_name(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
@ -250,6 +251,12 @@ enum {
#define JSON_BUILD_PAIR_TRISTATE(name, i) SD_JSON_BUILD_PAIR(name, JSON_BUILD_TRISTATE(i))
#define JSON_BUILD_PAIR_PIDREF(name, p) SD_JSON_BUILD_PAIR(name, JSON_BUILD_PIDREF(p))
#define JSON_BUILD_PAIR_DEVNUM(name, d) SD_JSON_BUILD_PAIR(name, JSON_BUILD_DEVNUM(d))
#define JSON_BUILD_PAIR_YES_NO(name, b) SD_JSON_BUILD_PAIR(name, SD_JSON_BUILD_STRING(yes_no(b)))
#define JSON_BUILD_PAIR_CONDITION_UNSIGNED(condition, name, value) \
SD_JSON_BUILD_PAIR_CONDITION(condition, name, SD_JSON_BUILD_UNSIGNED(value))
#define JSON_BUILD_PAIR_CONDITION_BOOLEAN(condition, name, value) \
SD_JSON_BUILD_PAIR_CONDITION(condition, name, SD_JSON_BUILD_BOOLEAN(value))
int json_variant_new_pidref(sd_json_variant **ret, PidRef *pidref);
int json_variant_new_devnum(sd_json_variant **ret, dev_t devnum);

View File

@ -1688,6 +1688,14 @@ _public_ int sd_varlink_is_idle(sd_varlink *v) {
return IN_SET(v->state, VARLINK_DISCONNECTED, VARLINK_IDLE_CLIENT, VARLINK_IDLE_SERVER);
}
_public_ int sd_varlink_is_connected(sd_varlink *v) {
assert_return(v, -EINVAL);
/* Returns true if the connection is still connected */
return v->state != VARLINK_DISCONNECTED;
}
_public_ int sd_varlink_get_fd(sd_varlink *v) {
assert_return(v, -EINVAL);

View File

@ -203,3 +203,11 @@ int varlink_check_privileged_peer(sd_varlink *vl) {
return 0;
}
DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
varlink_hash_ops,
void,
trivial_hash_func,
trivial_compare_func,
sd_varlink,
sd_varlink_unref);

View File

@ -27,3 +27,5 @@ int varlink_server_new(
void *userdata);
int varlink_check_privileged_peer(sd_varlink *vl);
extern const struct hash_ops varlink_hash_ops;

View File

@ -23,6 +23,7 @@
#include "hashmap.h"
#include "image-policy.h"
#include "io-util.h"
#include "iovec-util.h"
#include "json-util.h"
#include "loop-util.h"
#include "main-func.h"
@ -92,6 +93,9 @@ typedef struct MountImageParameters {
char *password;
ImagePolicy *image_policy;
bool verity_sharing;
struct iovec verity_root_hash;
struct iovec verity_root_hash_sig;
unsigned verity_data_fd_idx;
} MountImageParameters;
static void mount_image_parameters_done(MountImageParameters *p) {
@ -99,6 +103,8 @@ static void mount_image_parameters_done(MountImageParameters *p) {
p->password = erase_and_free(p->password);
p->image_policy = image_policy_free(p->image_policy);
iovec_done(&p->verity_root_hash);
iovec_done(&p->verity_root_hash_sig);
}
static int validate_image_fd(int fd, MountImageParameters *p) {
@ -293,6 +299,9 @@ static int vl_method_mount_image(
{ "password", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(MountImageParameters, password), 0 },
{ "imagePolicy", SD_JSON_VARIANT_STRING, json_dispatch_image_policy, offsetof(MountImageParameters, image_policy), 0 },
{ "veritySharing", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_stdbool, offsetof(MountImageParameters, verity_sharing), 0 },
{ "verityDataFileDescriptor", SD_JSON_VARIANT_UNSIGNED, sd_json_dispatch_uint, offsetof(MountImageParameters, verity_data_fd_idx), 0 },
{ "verityRootHash", SD_JSON_VARIANT_STRING, json_dispatch_unhex_iovec, offsetof(MountImageParameters, verity_root_hash), 0 },
{ "verityRootHashSignature", SD_JSON_VARIANT_STRING, json_dispatch_unbase64_iovec, offsetof(MountImageParameters, verity_root_hash_sig), 0 },
VARLINK_DISPATCH_POLKIT_FIELD,
{}
};
@ -301,13 +310,14 @@ static int vl_method_mount_image(
_cleanup_(mount_image_parameters_done) MountImageParameters p = {
.image_fd_idx = UINT_MAX,
.userns_fd_idx = UINT_MAX,
.verity_data_fd_idx = UINT_MAX,
.read_only = -1,
.growfs = -1,
};
_cleanup_(dissected_image_unrefp) DissectedImage *di = NULL;
_cleanup_(loop_device_unrefp) LoopDevice *loop = NULL;
_cleanup_(sd_json_variant_unrefp) sd_json_variant *aj = NULL;
_cleanup_close_ int image_fd = -EBADF, userns_fd = -EBADF;
_cleanup_close_ int image_fd = -EBADF, userns_fd = -EBADF, verity_data_fd = -EBADF;
_cleanup_(image_policy_freep) ImagePolicy *use_policy = NULL;
Hashmap **polkit_registry = ASSERT_PTR(userdata);
_cleanup_free_ char *ps = NULL;
@ -323,6 +333,13 @@ static int vl_method_mount_image(
if (r != 0)
return r;
/* Verity data and roothash have to be either both set, or both unset. The sig can be set only if
* the roothash is set. */
if ((p.verity_data_fd_idx != UINT_MAX) != (p.verity_root_hash.iov_len > 0))
return sd_varlink_error_invalid_parameter_name(link, "verityDataFileDescriptor");
if (p.verity_root_hash_sig.iov_len > 0 && p.verity_root_hash.iov_len == 0)
return sd_varlink_error_invalid_parameter_name(link, "verityRootHashSignature");
if (p.image_fd_idx != UINT_MAX) {
image_fd = sd_varlink_peek_dup_fd(link, p.image_fd_idx);
if (image_fd < 0)
@ -348,6 +365,30 @@ static int vl_method_mount_image(
return r;
image_is_trusted = r;
if (p.verity_data_fd_idx != UINT_MAX) {
verity_data_fd = sd_varlink_peek_dup_fd(link, p.verity_data_fd_idx);
if (verity_data_fd < 0)
return log_debug_errno(verity_data_fd, "Failed to peek verity data fd from client: %m");
r = fd_verify_safe_flags(verity_data_fd);
if (r < 0)
return log_debug_errno(r, "Verity data file descriptor has unsafe flags set: %m");
verity.data_path = strdup(FORMAT_PROC_FD_PATH(verity_data_fd));
if (!verity.data_path)
return -ENOMEM;
verity.designator = PARTITION_ROOT;
verity.root_hash = TAKE_PTR(p.verity_root_hash.iov_base);
verity.root_hash_size = p.verity_root_hash.iov_len;
p.verity_root_hash.iov_len = 0;
verity.root_hash_sig = TAKE_PTR(p.verity_root_hash_sig.iov_base);
verity.root_hash_sig_size = p.verity_root_hash_sig.iov_len;
p.verity_root_hash_sig.iov_len = 0;
}
const char *polkit_details[] = {
"read_only", one_zero(p.read_only > 0),
NULL,
@ -408,6 +449,7 @@ static int vl_method_mount_image(
DISSECT_IMAGE_ADD_PARTITION_DEVICES |
DISSECT_IMAGE_PIN_PARTITION_DEVICES |
(p.verity_sharing ? DISSECT_IMAGE_VERITY_SHARE : 0) |
(p.verity_data_fd_idx != UINT_MAX ? DISSECT_IMAGE_NO_PARTITION_TABLE : 0) |
DISSECT_IMAGE_ALLOW_USERSPACE_VERITY;
/* Let's see if we have acquired the privilege to mount untrusted images already */

View File

@ -6349,6 +6349,7 @@ static int run(int argc, char *argv[]) {
arg_image,
userns_fd,
arg_image_policy,
&arg_verity_settings,
dissect_image_flags,
&dissected_image);
if (r < 0)

View File

@ -881,7 +881,7 @@ static int dissect_image(
encrypted = streq_ptr(fstype, "crypto_LUKS");
if (verity_settings_data_covers(verity, PARTITION_ROOT))
found_flags = verity->root_hash_sig ? PARTITION_POLICY_SIGNED : PARTITION_POLICY_VERITY;
found_flags = verity->root_hash_sig_size > 0 ? PARTITION_POLICY_SIGNED : PARTITION_POLICY_VERITY;
else
found_flags = encrypted ? PARTITION_POLICY_ENCRYPTED : PARTITION_POLICY_UNPROTECTED;
@ -4513,6 +4513,7 @@ int verity_dissect_and_mount(
src_fd >= 0 ? FORMAT_PROC_FD_PATH(src_fd) : src,
userns_fd,
image_policy,
verity,
dissect_image_flags,
&dissected_image);
if (r < 0)
@ -4679,6 +4680,7 @@ int mountfsd_mount_image(
const char *path,
int userns_fd,
const ImagePolicy *image_policy,
const VeritySettings *verity,
DissectImageFlags flags,
DissectedImage **ret) {
@ -4695,13 +4697,14 @@ int mountfsd_mount_image(
};
_cleanup_(dissected_image_unrefp) DissectedImage *di = NULL;
_cleanup_close_ int image_fd = -EBADF;
_cleanup_close_ int image_fd = -EBADF, verity_data_fd = -EBADF;
_cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL;
_cleanup_free_ char *ps = NULL;
const char *error_id;
int r;
assert(path);
assert(verity);
assert(ret);
r = sd_varlink_connect_address(&vl, "/run/systemd/io.systemd.MountFileSystem");
@ -4736,6 +4739,16 @@ int mountfsd_mount_image(
return log_error_errno(r, "Failed to format image policy to string: %m");
}
if (verity->data_path) {
verity_data_fd = open(verity->data_path, O_RDONLY|O_CLOEXEC);
if (verity_data_fd < 0)
return log_error_errno(errno, "Failed to open verity data file '%s': %m", verity->data_path);
r = sd_varlink_push_dup_fd(vl, verity_data_fd);
if (r < 0)
return log_error_errno(r, "Failed to push verity data fd into varlink connection: %m");
}
sd_json_variant *reply = NULL;
r = varlink_callbo_and_log(
vl,
@ -4748,6 +4761,9 @@ int mountfsd_mount_image(
SD_JSON_BUILD_PAIR("growFileSystems", SD_JSON_BUILD_BOOLEAN(FLAGS_SET(flags, DISSECT_IMAGE_GROWFS))),
SD_JSON_BUILD_PAIR_CONDITION(!!ps, "imagePolicy", SD_JSON_BUILD_STRING(ps)),
SD_JSON_BUILD_PAIR("veritySharing", SD_JSON_BUILD_BOOLEAN(FLAGS_SET(flags, DISSECT_IMAGE_VERITY_SHARE))),
SD_JSON_BUILD_PAIR_CONDITION(verity_data_fd >= 0, "verityDataFileDescriptor", SD_JSON_BUILD_UNSIGNED(userns_fd >= 0 ? 2 : 1)),
JSON_BUILD_PAIR_IOVEC_HEX("verityRootHash", &((struct iovec) { .iov_base = verity->root_hash, .iov_len = verity->root_hash_size })),
JSON_BUILD_PAIR_IOVEC_BASE64("verityRootHashSignature", &((struct iovec) { .iov_base = verity->root_hash_sig, .iov_len = verity->root_hash_sig_size })),
SD_JSON_BUILD_PAIR("allowInteractiveAuthentication", SD_JSON_BUILD_BOOLEAN(FLAGS_SET(flags, DISSECT_IMAGE_ALLOW_INTERACTIVE_AUTH))));
if (r < 0)
return r;

View File

@ -257,5 +257,5 @@ static inline const char* dissected_partition_fstype(const DissectedPartition *m
int get_common_dissect_directory(char **ret);
int mountfsd_mount_image(const char *path, int userns_fd, const ImagePolicy *image_policy, DissectImageFlags flags, DissectedImage **ret);
int mountfsd_mount_image(const char *path, int userns_fd, const ImagePolicy *image_policy, const VeritySettings *verity, DissectImageFlags flags, DissectedImage **ret);
int mountfsd_mount_directory(const char *path, int userns_fd, DissectImageFlags flags, int *ret_mount_fd);

View File

@ -5,6 +5,7 @@
#include "namespace-util.h"
#include "nsflags.h"
#include "string-util.h"
#include "strv.h"
int namespace_flags_from_string(const char *name, unsigned long *ret) {
unsigned long flags = 0;
@ -40,19 +41,41 @@ int namespace_flags_from_string(const char *name, unsigned long *ret) {
}
int namespace_flags_to_string(unsigned long flags, char **ret) {
_cleanup_strv_free_ char **l = NULL;
_cleanup_free_ char *s = NULL;
int r;
assert(ret);
r = namespace_flags_to_strv(flags, &l);
if (r < 0)
return r;
s = strv_join(l, NULL);
if (!s)
return -ENOMEM;
*ret = TAKE_PTR(s);
return 0;
}
int namespace_flags_to_strv(unsigned long flags, char ***ret) {
_cleanup_strv_free_ char **s = NULL;
unsigned i;
int r;
assert(ret);
for (i = 0; namespace_info[i].proc_name; i++) {
if ((flags & namespace_info[i].clone_flag) != namespace_info[i].clone_flag)
continue;
if (!strextend_with_separator(&s, " ", namespace_info[i].proc_name))
return -ENOMEM;
r = strv_extend(&s, namespace_info[i].proc_name);
if (r < 0)
return r;
}
*ret = TAKE_PTR(s);
return 0;
}

View File

@ -23,4 +23,5 @@
int namespace_flags_from_string(const char *name, unsigned long *ret);
int namespace_flags_to_string(unsigned long flags, char **ret);
int namespace_flags_to_strv(unsigned long flags, char ***ret);
const char* namespace_single_flag_to_string(unsigned long flag) _const_;

View File

@ -6,30 +6,71 @@
#include "extract-word.h"
#include "securebits-util.h"
#include "string-util.h"
#include "strv.h"
int secure_bits_to_string_alloc(int i, char **s) {
_cleanup_free_ char *str = NULL;
size_t len;
static inline const char* secure_bit_to_string(int i) {
/* match a single bit */
switch (i) {
case SECURE_KEEP_CAPS:
return "keep-caps";
case SECURE_KEEP_CAPS_LOCKED:
return "keep-caps-locked";
case SECURE_NO_SETUID_FIXUP:
return "no-setuid-fixup";
case SECURE_NO_SETUID_FIXUP_LOCKED:
return "no-setuid-fixup-locked";
case SECURE_NOROOT:
return "noroot";
case SECURE_NOROOT_LOCKED:
return "noroot-locked";
default:
assert_not_reached();
}
}
int secure_bits_to_string_alloc(int i, char **ret) {
_cleanup_strv_free_ char **sv = NULL;
_cleanup_free_ char *joined = NULL;
int r;
assert(s);
assert(ret);
r = asprintf(&str, "%s%s%s%s%s%s",
(i & (1 << SECURE_KEEP_CAPS)) ? "keep-caps " : "",
(i & (1 << SECURE_KEEP_CAPS_LOCKED)) ? "keep-caps-locked " : "",
(i & (1 << SECURE_NO_SETUID_FIXUP)) ? "no-setuid-fixup " : "",
(i & (1 << SECURE_NO_SETUID_FIXUP_LOCKED)) ? "no-setuid-fixup-locked " : "",
(i & (1 << SECURE_NOROOT)) ? "noroot " : "",
(i & (1 << SECURE_NOROOT_LOCKED)) ? "noroot-locked " : "");
r = secure_bits_to_strv(i, &sv);
if (r < 0)
return r;
joined = strv_join(sv, " ");
if (!joined)
return -ENOMEM;
len = strlen(str);
if (len != 0)
str[len - 1] = '\0';
*ret = TAKE_PTR(joined);
return 0;
}
*s = TAKE_PTR(str);
int secure_bits_to_strv(int i, char ***ret) {
_cleanup_strv_free_ char **sv = NULL;
static const int bits[] = {
SECURE_KEEP_CAPS,
SECURE_KEEP_CAPS_LOCKED,
SECURE_NO_SETUID_FIXUP,
SECURE_NO_SETUID_FIXUP_LOCKED,
SECURE_NOROOT,
SECURE_NOROOT_LOCKED,
};
int r;
assert(ret);
FOREACH_ELEMENT(bit, bits) {
if (i & (1 << *bit)) {
r = strv_extend(&sv, secure_bit_to_string(*bit));
if (r < 0)
return r;
}
}
*ret = TAKE_PTR(sv);
return 0;
}

View File

@ -5,7 +5,8 @@
#include "shared-forward.h"
int secure_bits_to_string_alloc(int i, char **s);
int secure_bits_to_strv(int i, char ***ret);
int secure_bits_to_string_alloc(int i, char **ret);
int secure_bits_from_string(const char *s);
static inline bool secure_bits_is_valid(int i) {

View File

@ -62,6 +62,12 @@ static SD_VARLINK_DEFINE_METHOD(
SD_VARLINK_DEFINE_INPUT(imagePolicy, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("Whether to automatically reuse already set up dm-verity devices that share the same roothash."),
SD_VARLINK_DEFINE_INPUT(veritySharing, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("File descriptor of the file containing the dm-verity data, if the image is a bare filesystem rather than a DDI."),
SD_VARLINK_DEFINE_INPUT(verityDataFileDescriptor, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("The expected dm-verity root hash as an hex encoded string, if the image is a bare filesystem rather than a DDI."),
SD_VARLINK_DEFINE_INPUT(verityRootHash, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("The expected signature for the dm-verity root hash as a Base64 encoded string, if the image is a bare filesystem rather than a DDI."),
SD_VARLINK_DEFINE_INPUT(verityRootHashSignature, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
VARLINK_DEFINE_POLKIT_INPUT,
SD_VARLINK_FIELD_COMMENT("An array with information about contained partitions that have been prepared for mounting, as well as their mount file descriptors."),
SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(partitions, PartitionInfo, SD_VARLINK_ARRAY),

View File

@ -4,6 +4,7 @@
#include "varlink-idl-common.h"
#include "varlink-io.systemd.Unit.h"
/* CGroupContext */
static SD_VARLINK_DEFINE_STRUCT_TYPE(
CGroupTasksMax,
SD_VARLINK_FIELD_COMMENT("The maximum amount of tasks"),
@ -237,6 +238,485 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
SD_VARLINK_FIELD_COMMENT("Reflects whether to forward coredumps for processes that crash within this cgroup"),
SD_VARLINK_DEFINE_FIELD(CoredumpReceive, SD_VARLINK_BOOL, 0));
/* ExecContext */
static SD_VARLINK_DEFINE_STRUCT_TYPE(
WorkingDirectory,
SD_VARLINK_FIELD_COMMENT("The path to the working directory"),
SD_VARLINK_DEFINE_FIELD(path, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("Whether the path to the working directory is allowed to not exist"),
SD_VARLINK_DEFINE_FIELD(missingOK, SD_VARLINK_BOOL, 0));
static SD_VARLINK_DEFINE_STRUCT_TYPE(
PartitionMountOptions,
SD_VARLINK_FIELD_COMMENT("The partition designator to which the options apply"),
SD_VARLINK_DEFINE_FIELD(partitionDesignator, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("The mount options for this partition"),
SD_VARLINK_DEFINE_FIELD(options, SD_VARLINK_STRING, 0));
static SD_VARLINK_DEFINE_STRUCT_TYPE(
BindPath,
SD_VARLINK_FIELD_COMMENT("The mount source path"),
SD_VARLINK_DEFINE_FIELD(source, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("The mount destination path"),
SD_VARLINK_DEFINE_FIELD(destination, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("Whether a missing source path should be ignored"),
SD_VARLINK_DEFINE_FIELD(ignoreEnoent, SD_VARLINK_BOOL, 0),
SD_VARLINK_FIELD_COMMENT("Mount options"),
SD_VARLINK_DEFINE_FIELD(options, SD_VARLINK_STRING, SD_VARLINK_ARRAY));
static SD_VARLINK_DEFINE_STRUCT_TYPE(
MountImage,
SD_VARLINK_FIELD_COMMENT("The path to the image to mount"),
SD_VARLINK_DEFINE_FIELD(source, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("The destination path where to mount the image"),
SD_VARLINK_DEFINE_FIELD(destination, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("Whether failure to find the image is considered fatal"),
SD_VARLINK_DEFINE_FIELD(ignoreEnoent, SD_VARLINK_BOOL, 0),
SD_VARLINK_FIELD_COMMENT("The mount options to use for the partitions of the image"),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(mountOptions, PartitionMountOptions, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE));
static SD_VARLINK_DEFINE_STRUCT_TYPE(
ExtensionImage,
SD_VARLINK_FIELD_COMMENT("The path to the extension image"),
SD_VARLINK_DEFINE_FIELD(source, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("Whether failure to find the extension image is considered fatal"),
SD_VARLINK_DEFINE_FIELD(ignoreEnoent, SD_VARLINK_BOOL, 0),
SD_VARLINK_FIELD_COMMENT("The mount options to use for the partitions of the extension image"),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(mountOptions, PartitionMountOptions, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE));
static SD_VARLINK_DEFINE_STRUCT_TYPE(
SELinuxContext,
SD_VARLINK_FIELD_COMMENT("Whether failure to set the SELinux context is ignored"),
SD_VARLINK_DEFINE_FIELD(ignore, SD_VARLINK_BOOL, 0),
SD_VARLINK_FIELD_COMMENT("The SELinux context"),
SD_VARLINK_DEFINE_FIELD(context, SD_VARLINK_STRING, 0));
static SD_VARLINK_DEFINE_STRUCT_TYPE(
AppArmorProfile,
SD_VARLINK_FIELD_COMMENT("Whether failure to configure the apparmor profile will be ignored"),
SD_VARLINK_DEFINE_FIELD(ignore, SD_VARLINK_BOOL, 0),
SD_VARLINK_FIELD_COMMENT("The AppArmor profile"),
SD_VARLINK_DEFINE_FIELD(profile, SD_VARLINK_STRING, 0));
static SD_VARLINK_DEFINE_STRUCT_TYPE(
SmackProcessLabel,
SD_VARLINK_FIELD_COMMENT("Whether failure to configure the smack process label will be ignored"),
SD_VARLINK_DEFINE_FIELD(ignore, SD_VARLINK_BOOL, 0),
SD_VARLINK_FIELD_COMMENT("The smack process label"),
SD_VARLINK_DEFINE_FIELD(label, SD_VARLINK_STRING, 0));
static SD_VARLINK_DEFINE_STRUCT_TYPE(
CPUAffinity,
SD_VARLINK_FIELD_COMMENT("CPU affinity of the executed processes"),
SD_VARLINK_DEFINE_FIELD(affinity, SD_VARLINK_INT, SD_VARLINK_ARRAY),
SD_VARLINK_FIELD_COMMENT("CPU affinity from NUMA"),
SD_VARLINK_DEFINE_FIELD(fromNUMA, SD_VARLINK_BOOL, 0));
static SD_VARLINK_DEFINE_STRUCT_TYPE(
ExecDirectoryQuota,
SD_VARLINK_FIELD_COMMENT("Whether the quota is accounted"),
SD_VARLINK_DEFINE_FIELD(accounting, SD_VARLINK_BOOL, 0),
SD_VARLINK_FIELD_COMMENT("Whether the quota is enforced"),
SD_VARLINK_DEFINE_FIELD(enforce, SD_VARLINK_BOOL, 0),
SD_VARLINK_FIELD_COMMENT("The absolute quota in bytes"),
SD_VARLINK_DEFINE_FIELD(quotaAbsolute, SD_VARLINK_INT, 0),
SD_VARLINK_FIELD_COMMENT("The scaling factor for the quota"),
SD_VARLINK_DEFINE_FIELD(quotaScale, SD_VARLINK_INT, 0));
static SD_VARLINK_DEFINE_STRUCT_TYPE(
ExecDirectoryPath,
SD_VARLINK_FIELD_COMMENT("The path to the directory"),
SD_VARLINK_DEFINE_FIELD(path, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("A list of symlinks pointing to the directory"),
SD_VARLINK_DEFINE_FIELD(symlinks, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE));
static SD_VARLINK_DEFINE_STRUCT_TYPE(
ExecDirectory,
SD_VARLINK_FIELD_COMMENT("Exec directory paths"),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(paths, ExecDirectoryPath, SD_VARLINK_ARRAY),
SD_VARLINK_FIELD_COMMENT("The access mode of the directory"),
SD_VARLINK_DEFINE_FIELD(mode, SD_VARLINK_INT, 0),
SD_VARLINK_FIELD_COMMENT("The quota for the directory"),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(quota, ExecDirectoryQuota, 0));
static SD_VARLINK_DEFINE_STRUCT_TYPE(
TemporaryFilesystem,
SD_VARLINK_FIELD_COMMENT("The destination path where the temporary filesystem should be mounted"),
SD_VARLINK_DEFINE_FIELD(path, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("The mount options for the temporary filesystem"),
SD_VARLINK_DEFINE_FIELD(options, SD_VARLINK_STRING, SD_VARLINK_NULLABLE));
static SD_VARLINK_DEFINE_STRUCT_TYPE(
AddressFamilyList,
SD_VARLINK_FIELD_COMMENT("Whether the list of address families is an allow list"),
SD_VARLINK_DEFINE_FIELD(isAllowList, SD_VARLINK_BOOL, 0),
SD_VARLINK_FIELD_COMMENT("The list of address families"),
SD_VARLINK_DEFINE_FIELD(addressFamilies, SD_VARLINK_STRING, SD_VARLINK_ARRAY));
static SD_VARLINK_DEFINE_STRUCT_TYPE(
FilesystemList,
SD_VARLINK_FIELD_COMMENT("Whether the list of filesystems is an allow list"),
SD_VARLINK_DEFINE_FIELD(isAllowList, SD_VARLINK_BOOL, 0),
SD_VARLINK_FIELD_COMMENT("The list of filesystems"),
SD_VARLINK_DEFINE_FIELD(filesystems, SD_VARLINK_STRING, SD_VARLINK_ARRAY));
static SD_VARLINK_DEFINE_STRUCT_TYPE(
SystemCallList,
SD_VARLINK_FIELD_COMMENT("Whether the list of system calls is an allow list"),
SD_VARLINK_DEFINE_FIELD(isAllowList, SD_VARLINK_BOOL, 0),
SD_VARLINK_FIELD_COMMENT("The list of system calls"),
SD_VARLINK_DEFINE_FIELD(systemCalls, SD_VARLINK_STRING, SD_VARLINK_ARRAY));
static SD_VARLINK_DEFINE_STRUCT_TYPE(
EnvironmentFile,
SD_VARLINK_FIELD_COMMENT("The path to the environment file"),
SD_VARLINK_DEFINE_FIELD(path, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("Whether failure to read the environment file is fatal or not"),
SD_VARLINK_DEFINE_FIELD(graceful, SD_VARLINK_BOOL, 0));
static SD_VARLINK_DEFINE_STRUCT_TYPE(
LogFilterPattern,
SD_VARLINK_FIELD_COMMENT("Whether this pattern is an allow pattern"),
SD_VARLINK_DEFINE_FIELD(isAllowList, SD_VARLINK_BOOL, 0),
SD_VARLINK_FIELD_COMMENT("The filtering pattern"),
SD_VARLINK_DEFINE_FIELD(pattern, SD_VARLINK_STRING, 0));
static SD_VARLINK_DEFINE_STRUCT_TYPE(
LoadCredential,
SD_VARLINK_FIELD_COMMENT("The credential ID"),
SD_VARLINK_DEFINE_FIELD(id, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("The credential path"),
SD_VARLINK_DEFINE_FIELD(path, SD_VARLINK_STRING, 0));
static SD_VARLINK_DEFINE_STRUCT_TYPE(
ImportCredential,
SD_VARLINK_FIELD_COMMENT("The glob pattern to find credentials"),
SD_VARLINK_DEFINE_FIELD(glob, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("The rename pattern to which matching credentials should be renamed"),
SD_VARLINK_DEFINE_FIELD(rename, SD_VARLINK_STRING, SD_VARLINK_NULLABLE));
static SD_VARLINK_DEFINE_STRUCT_TYPE(
SetCredential,
SD_VARLINK_FIELD_COMMENT("The credential ID"),
SD_VARLINK_DEFINE_FIELD(id, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("The credential value encoded in base64"),
SD_VARLINK_DEFINE_FIELD(value, SD_VARLINK_STRING, 0));
static SD_VARLINK_DEFINE_STRUCT_TYPE(
ExecContext,
/* Paths
* https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#Paths */
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#ExecSearchPath="),
SD_VARLINK_DEFINE_FIELD(ExecSearchPath, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#WorkingDirectory="),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(WorkingDirectory, WorkingDirectory, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#RootDirectory="),
SD_VARLINK_DEFINE_FIELD(RootDirectory, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#RootImage="),
SD_VARLINK_DEFINE_FIELD(RootImage, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#RootImageOptions="),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(RootImageOptions, PartitionMountOptions, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#RootEphemeral="),
SD_VARLINK_DEFINE_FIELD(RootEphemeral, SD_VARLINK_BOOL, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#RootHash="),
SD_VARLINK_DEFINE_FIELD(RootHash, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#RootHash="),
SD_VARLINK_DEFINE_FIELD(RootHashPath, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#RootHashSignature="),
SD_VARLINK_DEFINE_FIELD(RootHashSignature, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#RootHashSignature="),
SD_VARLINK_DEFINE_FIELD(RootHashSignaturePath, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#RootVerity="),
SD_VARLINK_DEFINE_FIELD(RootVerity, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#RootImagePolicy="),
SD_VARLINK_DEFINE_FIELD(RootImagePolicy, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#RootImagePolicy="),
SD_VARLINK_DEFINE_FIELD(MountImagePolicy, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#RootImagePolicy="),
SD_VARLINK_DEFINE_FIELD(ExtensionImagePolicy, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#MountAPIVFS="),
SD_VARLINK_DEFINE_FIELD(MountAPIVFS, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#BindLogSockets="),
SD_VARLINK_DEFINE_FIELD(BindLogSockets, SD_VARLINK_BOOL, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#ProtectProc="),
SD_VARLINK_DEFINE_FIELD(ProtectProc, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#ProcSubset="),
SD_VARLINK_DEFINE_FIELD(ProcSubset, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#BindPaths="),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(BindPaths, BindPath, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#BindPaths="),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(BindReadOnlyPaths, BindPath, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#MountImages="),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(MountImages, MountImage, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#ExtensionImages="),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(ExtensionImages, ExtensionImage, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#ExtensionDirectories="),
SD_VARLINK_DEFINE_FIELD(ExtensionDirectories, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
/* User/Group Identity
* https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#User/Group%20Identity */
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#User="),
SD_VARLINK_DEFINE_FIELD(User, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#User="),
SD_VARLINK_DEFINE_FIELD(Group, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#DynamicUser="),
SD_VARLINK_DEFINE_FIELD(DynamicUser, SD_VARLINK_BOOL, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#SupplementaryGroups="),
SD_VARLINK_DEFINE_FIELD(SupplementaryGroups, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#SetLoginEnvironment="),
SD_VARLINK_DEFINE_FIELD(SetLoginEnvironment, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#PAMName="),
SD_VARLINK_DEFINE_FIELD(PAMName, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
/* Capabilities
* https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#Capabilities */
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#CapabilityBoundingSet="),
SD_VARLINK_DEFINE_FIELD(CapabilityBoundingSet, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#AmbientCapabilities="),
SD_VARLINK_DEFINE_FIELD(AmbientCapabilities, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
/* Security
* https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#Security */
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#NoNewPrivileges="),
SD_VARLINK_DEFINE_FIELD(NoNewPrivileges, SD_VARLINK_BOOL, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#SecureBits="),
SD_VARLINK_DEFINE_FIELD(SecureBits, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
/* Mandatory Access Control
* https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#Mandatory%20Access%20Control */
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#SELinuxContext="),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(SELinuxContext, SELinuxContext, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#AppArmorProfile="),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(AppArmorProfile, AppArmorProfile, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#SmackProcessLabel="),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(SmackProcessLabel, SmackProcessLabel, SD_VARLINK_NULLABLE),
/* Process Properties
* https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#Process%20Properties */
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#LimitCPU="),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(Limits, ResourceLimitTable, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#UMask="),
SD_VARLINK_DEFINE_FIELD(UMask, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#CoredumpFilter="),
SD_VARLINK_DEFINE_FIELD(CoredumpFilter, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#KeyringMode="),
SD_VARLINK_DEFINE_FIELD(KeyringMode, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#OOMScoreAdjust="),
SD_VARLINK_DEFINE_FIELD(OOMScoreAdjust, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#TimerSlackNSec="),
SD_VARLINK_DEFINE_FIELD(TimerSlackNSec, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#Personality="),
SD_VARLINK_DEFINE_FIELD(Personality, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#IgnoreSIGPIPE="),
SD_VARLINK_DEFINE_FIELD(IgnoreSIGPIPE, SD_VARLINK_BOOL, 0),
/* Scheduling
* https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#Scheduling */
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#Nice="),
SD_VARLINK_DEFINE_FIELD(Nice, SD_VARLINK_INT, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#CPUSchedulingPolicy="),
SD_VARLINK_DEFINE_FIELD(CPUSchedulingPolicy, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#CPUSchedulingPriority="),
SD_VARLINK_DEFINE_FIELD(CPUSchedulingPriority, SD_VARLINK_INT, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#CPUSchedulingResetOnFork="),
SD_VARLINK_DEFINE_FIELD(CPUSchedulingResetOnFork, SD_VARLINK_BOOL, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#CPUAffinity="),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(CPUAffinity, CPUAffinity, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#NUMAPolicy="),
SD_VARLINK_DEFINE_FIELD(NUMAPolicy, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#NUMAMask="),
SD_VARLINK_DEFINE_FIELD(NUMAMask, SD_VARLINK_INT, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#IOSchedulingClass="),
SD_VARLINK_DEFINE_FIELD(IOSchedulingClass, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#IOSchedulingPriority="),
SD_VARLINK_DEFINE_FIELD(IOSchedulingPriority, SD_VARLINK_INT, 0),
/* Sandboxing
* https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#Sandboxing */
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#ProtectSystem="),
SD_VARLINK_DEFINE_FIELD(ProtectSystem, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#ProtectHome="),
SD_VARLINK_DEFINE_FIELD(ProtectHome, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#RuntimeDirectory="),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(RuntimeDirectory, ExecDirectory, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#RuntimeDirectory="),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(StateDirectory, ExecDirectory, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#RuntimeDirectory="),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(CacheDirectory, ExecDirectory, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#RuntimeDirectory="),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(LogsDirectory, ExecDirectory, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#RuntimeDirectory="),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(ConfigurationDirectory, ExecDirectory, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#RuntimeDirectoryPreserve="),
SD_VARLINK_DEFINE_FIELD(RuntimeDirectoryPreserve, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#TimeoutCleanSec="),
SD_VARLINK_DEFINE_FIELD(TimeoutCleanUSec, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#ReadWritePaths="),
SD_VARLINK_DEFINE_FIELD(ReadWritePaths, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#ReadWritePaths="),
SD_VARLINK_DEFINE_FIELD(ReadOnlyPaths, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#ReadWritePaths="),
SD_VARLINK_DEFINE_FIELD(InaccessiblePaths, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#ReadWritePaths="),
SD_VARLINK_DEFINE_FIELD(ExecPaths, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#ReadWritePaths="),
SD_VARLINK_DEFINE_FIELD(NoExecPaths, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#TemporaryFileSystem="),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(TemporaryFileSystem, TemporaryFilesystem, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#PrivateTmp="),
SD_VARLINK_DEFINE_FIELD(PrivateTmp, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#PrivateDevices="),
SD_VARLINK_DEFINE_FIELD(PrivateDevices, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#PrivateNetwork="),
SD_VARLINK_DEFINE_FIELD(PrivateNetwork, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#NetworkNamespacePath="),
SD_VARLINK_DEFINE_FIELD(NetworkNamespacePath, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#PrivateIPC="),
SD_VARLINK_DEFINE_FIELD(PrivateIPC, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#IPCNamespacePath="),
SD_VARLINK_DEFINE_FIELD(IPCNamespacePath, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#MemoryKSM="),
SD_VARLINK_DEFINE_FIELD(MemoryKSM, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#PrivatePIDs="),
SD_VARLINK_DEFINE_FIELD(PrivatePIDs, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#PrivateUsers="),
SD_VARLINK_DEFINE_FIELD(PrivateUsers, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#ProtectHostname="),
SD_VARLINK_DEFINE_FIELD(ProtectHostname, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#ProtectClock="),
SD_VARLINK_DEFINE_FIELD(ProtectClock, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#ProtectKernelTunables="),
SD_VARLINK_DEFINE_FIELD(ProtectKernelTunables, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#ProtectKernelModules="),
SD_VARLINK_DEFINE_FIELD(ProtectKernelModules, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#ProtectKernelLogs="),
SD_VARLINK_DEFINE_FIELD(ProtectKernelLogs, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#ProtectControlGroups="),
SD_VARLINK_DEFINE_FIELD(ProtectControlGroups, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#RestrictAddressFamilies="),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(RestrictAddressFamilies, AddressFamilyList, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#RestrictFileSystems="),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(RestrictFilesystems, FilesystemList, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#RestrictNamespaces="),
SD_VARLINK_DEFINE_FIELD(RestrictNamespaces, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#DelegateNamespaces="),
SD_VARLINK_DEFINE_FIELD(DelegateNamespaces, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#PrivatePBF="),
SD_VARLINK_DEFINE_FIELD(PrivatePBF, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#BPFDelegateCommands="),
SD_VARLINK_DEFINE_FIELD(BPFDelegateCommands, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#BPFDelegateMaps="),
SD_VARLINK_DEFINE_FIELD(BPFDelegateMaps, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#BPFDelegatePrograms="),
SD_VARLINK_DEFINE_FIELD(BPFDelegatePrograms, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#BPFDelegateAttachments="),
SD_VARLINK_DEFINE_FIELD(BPFDelegateAttachments, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#LockPersonality="),
SD_VARLINK_DEFINE_FIELD(LockPersonality, SD_VARLINK_BOOL, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#MemoryDenyWriteExecute="),
SD_VARLINK_DEFINE_FIELD(MemoryDenyWriteExecute, SD_VARLINK_BOOL, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#RestrictRealtime="),
SD_VARLINK_DEFINE_FIELD(RestrictRealtime, SD_VARLINK_BOOL, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#RestrictSUIDSGID="),
SD_VARLINK_DEFINE_FIELD(RestrictSUIDSGID, SD_VARLINK_BOOL, 0),
SD_VARLINK_FIELD_COMMENT("Whether to remove all System V and POSIX IPC objects owned by the user and group this unit runs under"),
SD_VARLINK_DEFINE_FIELD(RemoveIPC, SD_VARLINK_BOOL, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#PrivateMounts="),
SD_VARLINK_DEFINE_FIELD(PrivateMounts, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#MountFlags="),
SD_VARLINK_DEFINE_FIELD(MountFlags, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
/* System Call Filtering
* https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#System%20Call%20Filtering */
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#SystemCallFilter="),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(SystemCallFilter, SystemCallList, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#SystemCallErrorNumber="),
SD_VARLINK_DEFINE_FIELD(SystemCallErrorNumber, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#SystemCallArchitectures="),
SD_VARLINK_DEFINE_FIELD(SystemCallArchitectures, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#SystemCallLog="),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(SystemCallLog, SystemCallList, SD_VARLINK_NULLABLE),
/* Environment
* https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#Environment */
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#Environment="),
SD_VARLINK_DEFINE_FIELD(Environment, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#EnvironmentFile="),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(EnvironmentFiles, EnvironmentFile, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#PassEnvironment="),
SD_VARLINK_DEFINE_FIELD(PassEnvironment, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#UnsetEnvironment="),
SD_VARLINK_DEFINE_FIELD(UnsetEnvironment, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
/* Logging and Standard Input/Output
* https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#Logging%20and%20Standard%20Input/Output */
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#StandardInput="),
SD_VARLINK_DEFINE_FIELD(StandardInput, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#StandardOutput="),
SD_VARLINK_DEFINE_FIELD(StandardOutput, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#StandardError="),
SD_VARLINK_DEFINE_FIELD(StandardError, SD_VARLINK_STRING, 0),
SD_VARLINK_FIELD_COMMENT("The file descriptor name to connect standard input to"),
SD_VARLINK_DEFINE_FIELD(StandardInputFileDescriptorName, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("The file descriptor name to connect standard output to"),
SD_VARLINK_DEFINE_FIELD(StandardOutputFileDescriptorName, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("The file descriptor name to connect standard error to"),
SD_VARLINK_DEFINE_FIELD(StandardErrorFileDescriptorName, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#StandardInputText="),
SD_VARLINK_DEFINE_FIELD(StandardInputData, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#LogLevelMax="),
SD_VARLINK_DEFINE_FIELD(LogLevelMax, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#LogExtraFields="),
SD_VARLINK_DEFINE_FIELD(LogExtraFields, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#LogRateLimitIntervalSec="),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(LogRateLimit, RateLimit, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#LogFilterPatterns="),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(LogFilterPatterns, LogFilterPattern, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#LogNamespace="),
SD_VARLINK_DEFINE_FIELD(LogNamespace, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#SyslogIdentifier="),
SD_VARLINK_DEFINE_FIELD(SyslogIdentifier, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#SyslogFacility="),
SD_VARLINK_DEFINE_FIELD(SyslogFacility, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#SyslogLevel="),
SD_VARLINK_DEFINE_FIELD(SyslogLevel, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#SyslogLevelPrefix="),
SD_VARLINK_DEFINE_FIELD(SyslogLevelPrefix, SD_VARLINK_BOOL, 0),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#TTYPath="),
SD_VARLINK_DEFINE_FIELD(TTYPath, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#TTYReset="),
SD_VARLINK_DEFINE_FIELD(TTYReset, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#TTYVHangup="),
SD_VARLINK_DEFINE_FIELD(TTYVHangup, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#TTYRows="),
SD_VARLINK_DEFINE_FIELD(TTYRows, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#TTYRows="),
SD_VARLINK_DEFINE_FIELD(TTYColumns, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#TTYVTDisallocate="),
SD_VARLINK_DEFINE_FIELD(TTYVTDisallocate, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE),
/* Credentials
* https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#Credentials */
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#LoadCredential=ID:PATH"),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(LoadCredential, LoadCredential, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#LoadCredential=ID:PATH"),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(LoadCredentialEncrypted, LoadCredential, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#ImportCredential=GLOB"),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(ImportCredential, ImportCredential, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#SetCredential=ID:VALUE"),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(SetCredential, SetCredential, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#SetCredential=ID:VALUE"),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(SetCredentialEncrypted, SetCredential, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
/* System V Compatibility
* https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#System%20V%20Compatibility */
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#UtmpIdentifier="),
SD_VARLINK_DEFINE_FIELD(UtmpIdentifier, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man"PROJECT_VERSION_STR"systemd.exec.html#UtmpMode="),
SD_VARLINK_DEFINE_FIELD(UtmpMode, SD_VARLINK_STRING, 0));
/* UnitContext */
static SD_VARLINK_DEFINE_STRUCT_TYPE(
Condition,
SD_VARLINK_FIELD_COMMENT("The condition type"),
@ -388,8 +868,12 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
SD_VARLINK_DEFINE_FIELD(Perpetual, SD_VARLINK_BOOL, 0),
SD_VARLINK_FIELD_COMMENT("When true, logs about this unit will be at debug level regardless of other log level settings"),
SD_VARLINK_DEFINE_FIELD(DebugInvocation, SD_VARLINK_BOOL, 0),
/* Other contexts */
SD_VARLINK_FIELD_COMMENT("The cgroup context of the unit"),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(CGroup, CGroupContext, SD_VARLINK_NULLABLE));
SD_VARLINK_DEFINE_FIELD_BY_TYPE(CGroup, CGroupContext, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("The exec context of the unit"),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(Exec, ExecContext, SD_VARLINK_NULLABLE));
static SD_VARLINK_DEFINE_STRUCT_TYPE(
ActivationDetails,
@ -554,6 +1038,8 @@ SD_VARLINK_DEFINE_INTERFACE(
&vl_type_ActivationDetails,
SD_VARLINK_SYMBOL_COMMENT("An object for referencing UNIX processes"),
&vl_type_ProcessId,
/* CGroupContext */
&vl_type_CGroupTasksMax,
&vl_type_CGroupIODeviceWeight,
&vl_type_CGroupIODeviceLimit,
@ -568,5 +1054,34 @@ SD_VARLINK_DEFINE_INTERFACE(
&vl_type_CGroupContext,
SD_VARLINK_SYMBOL_COMMENT("CGroup runtime of a unit"),
&vl_type_CGroupRuntime,
/* ExecContext */
&vl_type_WorkingDirectory,
&vl_type_PartitionMountOptions,
&vl_type_BindPath,
&vl_type_MountImage,
&vl_type_ExtensionImage,
&vl_type_SELinuxContext,
&vl_type_AppArmorProfile,
&vl_type_SmackProcessLabel,
&vl_type_ResourceLimit,
&vl_type_ResourceLimitTable,
&vl_type_CPUAffinity,
&vl_type_ExecDirectoryQuota,
&vl_type_ExecDirectoryPath,
&vl_type_ExecDirectory,
&vl_type_TemporaryFilesystem,
&vl_type_AddressFamilyList,
&vl_type_FilesystemList,
&vl_type_SystemCallList,
&vl_type_EnvironmentFile,
&vl_type_LogFilterPattern,
&vl_type_LoadCredential,
&vl_type_ImportCredential,
&vl_type_SetCredential,
SD_VARLINK_SYMBOL_COMMENT("Exec context of a unit"),
&vl_type_ExecContext,
/* Errors */
SD_VARLINK_SYMBOL_COMMENT("No matching unit found"),
&vl_error_NoSuchUnit);

View File

@ -110,6 +110,7 @@ int sd_varlink_process(sd_varlink *v);
int sd_varlink_wait(sd_varlink *v, uint64_t timeout);
int sd_varlink_is_idle(sd_varlink *v);
int sd_varlink_is_connected(sd_varlink *v);
int sd_varlink_flush(sd_varlink *v);
int sd_varlink_close(sd_varlink *v);

View File

@ -15,20 +15,27 @@ static const char * const string_bits[] = {
};
TEST(secure_bits_basic) {
_cleanup_free_ char *joined = NULL, *str = NULL;
_cleanup_free_ char *joined = NULL, *str = NULL, *joined_ssv = NULL;
_cleanup_strv_free_ char **ssv = NULL;
int r;
/* Check if converting each bit from string and back to string yields
* the same value */
STRV_FOREACH(bit, string_bits) {
_cleanup_free_ char *s = NULL;
_cleanup_strv_free_ char **sv = NULL;
r = secure_bits_from_string(*bit);
assert_se(r > 0);
assert_se(secure_bits_is_valid(r));
assert_se(secure_bits_to_string_alloc(r, &s) >= 0);
printf("%s = 0x%x = %s\n", *bit, (unsigned)r, s);
ASSERT_STREQ(*bit, s);
ASSERT_OK(secure_bits_to_strv(r, &sv));
ASSERT_EQ(strv_length(sv), (size_t) 1);
ASSERT_STREQ(*bit, sv[0]);
}
/* Ditto, but with all bits at once */
@ -41,7 +48,12 @@ TEST(secure_bits_basic) {
printf("%s = 0x%x = %s\n", joined, (unsigned)r, str);
ASSERT_STREQ(joined, str);
ASSERT_OK(secure_bits_to_strv(r, &ssv));
joined_ssv = strv_join(ssv, " ");
ASSERT_STREQ(joined, joined_ssv);
str = mfree(str);
ssv = strv_free(ssv);
/* Empty string */
assert_se(secure_bits_from_string("") == 0);
@ -51,8 +63,10 @@ TEST(secure_bits_basic) {
assert_se(secure_bits_from_string("foo bar baz") == 0);
/* Empty secure bits */
assert_se(secure_bits_to_string_alloc(0, &str) >= 0);
assert_se(isempty(str));
ASSERT_OK(secure_bits_to_string_alloc(0, &str));
ASSERT_TRUE(isempty(str));
ASSERT_OK(secure_bits_to_strv(0, &ssv));
ASSERT_TRUE(strv_isempty(ssv));
str = mfree(str);

View File

@ -72,6 +72,25 @@ if [ "$VERITY_SIG_SUPPORTED" -eq 1 ]; then
systemd-run -M testuser@ --user --pipe --wait \
--property RootImage="$MINIMAL_IMAGE.gpt" \
test -e "/dev/mapper/${MINIMAL_IMAGE_ROOTHASH}-verity"
systemd-run -M testuser@ --user --pipe --wait \
--property RootImage="$MINIMAL_IMAGE.raw" \
--property ExtensionImages=/tmp/app0.raw \
sh -c "test -e \"/dev/mapper/${MINIMAL_IMAGE_ROOTHASH}-verity\" && test -e \"/dev/mapper/$(</tmp/app0.roothash)-verity\""
# Without a signature this should not work, as mountfsd should reject it, even if we explicitly ask to
# trust it
mv /tmp/app0.roothash.p7s /tmp/app0.roothash.p7s.bak
(! systemd-run -M testuser@ --user --pipe --wait \
--property RootImage="$MINIMAL_IMAGE.raw" \
--property ExtensionImages=/tmp/app0.raw \
sh -c "test -e \"/dev/mapper/${MINIMAL_IMAGE_ROOTHASH}-verity\" && test -e \"/dev/mapper/$(</tmp/app0.roothash)-verity\"")
(! systemd-run -M testuser@ --user --pipe --wait \
--property RootImage="$MINIMAL_IMAGE.raw" \
--property ExtensionImages=/tmp/app0.raw \
--property ExtensionImagePolicy=root=verity+signed+absent:usr=verity+signed+absent \
sh -c "test -e \"/dev/mapper/${MINIMAL_IMAGE_ROOTHASH}-verity\" && test -e \"/dev/mapper/$(</tmp/app0.roothash)-verity\"")
mv /tmp/app0.roothash.p7s.bak /tmp/app0.roothash.p7s
fi
# Install key in keychain