Skip to content

Commit

Permalink
core: introduce BindJournalSockets=
Browse files Browse the repository at this point in the history
  • Loading branch information
YHNdnzj committed Apr 26, 2024
1 parent 5e3dca9 commit 4bf703d
Show file tree
Hide file tree
Showing 12 changed files with 93 additions and 1 deletion.
25 changes: 25 additions & 0 deletions man/org.freedesktop.systemd1.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3310,6 +3310,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b MountAPIVFS = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b BindJournalSockets = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s KeyringMode = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s ProtectProc = '...';
Expand Down Expand Up @@ -3905,6 +3907,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {

<!--property MountAPIVFS is not documented!-->

<!--property BindJournalSockets is not documented!-->

<!--property KeyringMode is not documented!-->

<!--property ProtectProc is not documented!-->
Expand Down Expand Up @@ -4605,6 +4609,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {

<variablelist class="dbus-property" generated="True" extra-ref="MountAPIVFS"/>

<variablelist class="dbus-property" generated="True" extra-ref="BindJournalSockets"/>

<variablelist class="dbus-property" generated="True" extra-ref="KeyringMode"/>

<variablelist class="dbus-property" generated="True" extra-ref="ProtectProc"/>
Expand Down Expand Up @@ -5427,6 +5433,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b MountAPIVFS = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b BindJournalSockets = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s KeyringMode = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s ProtectProc = '...';
Expand Down Expand Up @@ -6034,6 +6042,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {

<!--property MountAPIVFS is not documented!-->

<!--property BindJournalSockets is not documented!-->

<!--property KeyringMode is not documented!-->

<!--property ProtectProc is not documented!-->
Expand Down Expand Up @@ -6714,6 +6724,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {

<variablelist class="dbus-property" generated="True" extra-ref="MountAPIVFS"/>

<variablelist class="dbus-property" generated="True" extra-ref="BindJournalSockets"/>

<variablelist class="dbus-property" generated="True" extra-ref="KeyringMode"/>

<variablelist class="dbus-property" generated="True" extra-ref="ProtectProc"/>
Expand Down Expand Up @@ -7400,6 +7412,8 @@ node /org/freedesktop/systemd1/unit/home_2emount {
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b MountAPIVFS = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b BindJournalSockets = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s KeyringMode = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s ProtectProc = '...';
Expand Down Expand Up @@ -7933,6 +7947,8 @@ node /org/freedesktop/systemd1/unit/home_2emount {

<!--property MountAPIVFS is not documented!-->

<!--property BindJournalSockets is not documented!-->

<!--property KeyringMode is not documented!-->

<!--property ProtectProc is not documented!-->
Expand Down Expand Up @@ -8525,6 +8541,8 @@ node /org/freedesktop/systemd1/unit/home_2emount {

<variablelist class="dbus-property" generated="True" extra-ref="MountAPIVFS"/>

<variablelist class="dbus-property" generated="True" extra-ref="BindJournalSockets"/>

<variablelist class="dbus-property" generated="True" extra-ref="KeyringMode"/>

<variablelist class="dbus-property" generated="True" extra-ref="ProtectProc"/>
Expand Down Expand Up @@ -9334,6 +9352,8 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b MountAPIVFS = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b BindJournalSockets = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s KeyringMode = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s ProtectProc = '...';
Expand Down Expand Up @@ -9853,6 +9873,8 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {

<!--property MountAPIVFS is not documented!-->

<!--property BindJournalSockets is not documented!-->

<!--property KeyringMode is not documented!-->

<!--property ProtectProc is not documented!-->
Expand Down Expand Up @@ -10431,6 +10453,8 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {

<variablelist class="dbus-property" generated="True" extra-ref="MountAPIVFS"/>

<variablelist class="dbus-property" generated="True" extra-ref="BindJournalSockets"/>

<variablelist class="dbus-property" generated="True" extra-ref="KeyringMode"/>

<variablelist class="dbus-property" generated="True" extra-ref="ProtectProc"/>
Expand Down Expand Up @@ -12222,6 +12246,7 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
<varname>EffectiveMemoryMax</varname>,
<varname>EffectiveTasksMax</varname>, and
<varname>MemoryZSwapWriteback</varname> were added in version 256.</para>
<para><varname>BindJournalSockets</varname> was added in version 257.</para>
</refsect2>
<refsect2>
<title>Job Objects</title>
Expand Down
16 changes: 16 additions & 0 deletions man/systemd.exec.xml
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,22 @@
<xi:include href="version-info.xml" xpointer="v233"/></listitem>
</varlistentry>

<varlistentry>
<term><varname>BindJournalSockets=</varname></term>

<listitem><para>Takes a boolean argument. If true, sockets from <citerefentry>
<refentrytitle>systemd-journald.socket</refentrytitle><manvolnum>8</manvolnum></citerefentry>
will be bind mounted into the mount namespace. This is particularly useful when a different rootfs
is used (through <varname>RootDirectory=</varname> or <varname>RootImage=</varname>), as
<varname>MountAPIVFS=yes</varname> mounts an empty <filename>/run/</filename> inside the new root.</para>

<para>This option is implied when <varname>LogNamespace=</varname> is used,
when <varname>MountAPIVFS=yes</varname>, or when <varname>PrivateDevices=yes</varname> is used
in conjunction with either <varname>RootDirectory=</varname> or <varname>RootImage=</varname>.</para>

<xi:include href="version-info.xml" xpointer="v257"/></listitem>
</varlistentry>

<varlistentry>
<term><varname>ProtectProc=</varname></term>

Expand Down
1 change: 1 addition & 0 deletions man/version-info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,5 @@
<para id="v254">Added in version 254.</para>
<para id="v255">Added in version 255.</para>
<para id="v256">Added in version 256.</para>
<para id="v257">Added in version 257.</para>
</refsect1>
5 changes: 5 additions & 0 deletions src/core/dbus-execute.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_protect_system, protect_system,
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_personality, personality, unsigned long);
static BUS_DEFINE_PROPERTY_GET(property_get_ioprio, "i", ExecContext, exec_context_get_effective_ioprio);
static BUS_DEFINE_PROPERTY_GET(property_get_mount_apivfs, "b", ExecContext, exec_context_get_effective_mount_apivfs);
static BUS_DEFINE_PROPERTY_GET(property_get_bind_journal_sockets, "b", ExecContext, exec_context_get_effective_bind_journal_sockets);
static BUS_DEFINE_PROPERTY_GET2(property_get_ioprio_class, "i", ExecContext, exec_context_get_effective_ioprio, ioprio_prio_class);
static BUS_DEFINE_PROPERTY_GET2(property_get_ioprio_priority, "i", ExecContext, exec_context_get_effective_ioprio, ioprio_prio_data);
static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_empty_string, "s", NULL);
Expand Down Expand Up @@ -1108,6 +1109,7 @@ const sd_bus_vtable bus_exec_vtable[] = {
SD_BUS_PROPERTY("BindReadOnlyPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("TemporaryFileSystem", "a(ss)", property_get_temporary_filesystems, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("MountAPIVFS", "b", property_get_mount_apivfs, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("BindJournalSockets", "b", property_get_bind_journal_sockets, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("KeyringMode", "s", property_get_exec_keyring_mode, offsetof(ExecContext, keyring_mode), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("ProtectProc", "s", property_get_protect_proc, offsetof(ExecContext, protect_proc), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("ProcSubset", "s", property_get_proc_subset, offsetof(ExecContext, proc_subset), SD_BUS_VTABLE_PROPERTY_CONST),
Expand Down Expand Up @@ -1744,6 +1746,9 @@ int bus_exec_context_set_transient_property(
if (streq(name, "PrivateMounts"))
return bus_set_transient_tristate(u, name, &c->private_mounts, message, flags, error);

if (streq(name, "BindJournalSockets"))
return bus_set_transient_tristate(u, name, &c->bind_journal_sockets, message, flags, error);

if (streq(name, "PrivateNetwork"))
return bus_set_transient_bool(u, name, &c->private_network, message, flags, error);

Expand Down
2 changes: 2 additions & 0 deletions src/core/exec-invoke.c
Original file line number Diff line number Diff line change
Expand Up @@ -3245,6 +3245,7 @@ static int apply_mount_namespace(
.private_ipc = needs_sandboxing && exec_needs_ipc_namespace(context),

.mount_apivfs = needs_sandboxing && exec_context_get_effective_mount_apivfs(context),
.bind_journal_sockets = needs_sandboxing && exec_context_get_effective_bind_journal_sockets(context),

/* If NNP is on, we can turn on MS_NOSUID, since it won't have any effect anymore. */
.mount_nosuid = needs_sandboxing && context->no_new_privileges && !mac_selinux_use(),
Expand Down Expand Up @@ -3862,6 +3863,7 @@ static bool exec_context_need_unprivileged_private_users(
context->ipc_namespace_path ||
context->private_mounts > 0 ||
context->mount_apivfs ||
context->bind_journal_sockets > 0 ||
context->n_bind_mounts > 0 ||
context->n_temporary_filesystems > 0 ||
context->root_directory ||
Expand Down
8 changes: 8 additions & 0 deletions src/core/execute-serialize.c
Original file line number Diff line number Diff line change
Expand Up @@ -1832,6 +1832,10 @@ static int exec_context_serialize(const ExecContext *c, FILE *f) {
if (r < 0)
return r;

r = serialize_item_tristate(f, "exec-context-bind-journal-sockets", c->bind_journal_sockets);
if (r < 0)
return r;

r = serialize_item_tristate(f, "exec-context-memory-ksm", c->memory_ksm);
if (r < 0)
return r;
Expand Down Expand Up @@ -2713,6 +2717,10 @@ static int exec_context_deserialize(ExecContext *c, FILE *f) {
r = safe_atoi(val, &c->private_mounts);
if (r < 0)
return r;
} else if ((val = startswith(l, "exec-context-bind-journal-sockets="))) {
r = safe_atoi(val, &c->bind_journal_sockets);
if (r < 0)
return r;
} else if ((val = startswith(l, "exec-context-memory-ksm="))) {
r = safe_atoi(val, &c->memory_ksm);
if (r < 0)
Expand Down
19 changes: 19 additions & 0 deletions src/core/execute.c
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,7 @@ void exec_context_init(ExecContext *c) {
.tty_rows = UINT_MAX,
.tty_cols = UINT_MAX,
.private_mounts = -1,
.bind_journal_sockets = -1,
.memory_ksm = -1,
.set_login_environment = -1,
};
Expand Down Expand Up @@ -943,6 +944,7 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
"%sProtectHome: %s\n"
"%sProtectSystem: %s\n"
"%sMountAPIVFS: %s\n"
"%sBindJournalSockets: %s\n"
"%sIgnoreSIGPIPE: %s\n"
"%sMemoryDenyWriteExecute: %s\n"
"%sRestrictRealtime: %s\n"
Expand All @@ -968,6 +970,7 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
prefix, protect_home_to_string(c->protect_home),
prefix, protect_system_to_string(c->protect_system),
prefix, yes_no(exec_context_get_effective_mount_apivfs(c)),
prefix, yes_no(exec_context_get_effective_bind_journal_sockets(c)),
prefix, yes_no(c->ignore_sigpipe),
prefix, yes_no(c->memory_deny_write_execute),
prefix, yes_no(c->restrict_realtime),
Expand Down Expand Up @@ -1450,6 +1453,22 @@ bool exec_context_get_effective_mount_apivfs(const ExecContext *c) {
return false;
}

bool exec_context_get_effective_bind_journal_sockets(const ExecContext *c) {
assert(c);

/* If log namespace is specified, "/run/systemd/journal.namespace/" would be bind mounted to
* "/run/systemd/journal/", which effectively means BindJournalSockets=yes */
if (c->log_namespace)
return true;

if (c->bind_journal_sockets >= 0)
return c->bind_journal_sockets > 0;

return exec_context_get_effective_mount_apivfs(c) ||
(exec_context_with_rootfs(c) && c->private_devices); /* When PrivateDevices=yes, /dev/log gets
symlinked to /run/systemd/journal/dev-log */
}

void exec_context_free_log_extra_fields(ExecContext *c) {
assert(c);

Expand Down
2 changes: 2 additions & 0 deletions src/core/execute.h
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ struct ExecContext {
ProcSubset proc_subset; /* subset= */

int private_mounts;
int bind_journal_sockets;
int memory_ksm;
bool private_tmp;
bool private_network;
Expand Down Expand Up @@ -517,6 +518,7 @@ bool exec_context_maintains_privileges(const ExecContext *c);

int exec_context_get_effective_ioprio(const ExecContext *c);
bool exec_context_get_effective_mount_apivfs(const ExecContext *c);
bool exec_context_get_effective_bind_journal_sockets(const ExecContext *c);

void exec_context_free_log_extra_fields(ExecContext *c);

Expand Down
1 change: 1 addition & 0 deletions src/core/load-fragment-gperf.gperf.in
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@
{{type}}.ProtectHome, config_parse_protect_home, 0, offsetof({{type}}, exec_context.protect_home)
{{type}}.MountFlags, config_parse_exec_mount_propagation_flag, 0, offsetof({{type}}, exec_context.mount_propagation_flag)
{{type}}.MountAPIVFS, config_parse_exec_mount_apivfs, 0, offsetof({{type}}, exec_context)
{{type}}.BindJournalSockets, config_parse_tristate, 0, offsetof({{type}}, exec_context.bind_journal_sockets)
{{type}}.Personality, config_parse_personality, 0, offsetof({{type}}, exec_context.personality)
{{type}}.RuntimeDirectoryPreserve, config_parse_exec_preserve_mode, 0, offsetof({{type}}, exec_context.runtime_directory_preserve_mode)
{{type}}.RuntimeDirectoryMode, config_parse_mode, 0, offsetof({{type}}, exec_context.directories[EXEC_DIRECTORY_RUNTIME].mode)
Expand Down
13 changes: 12 additions & 1 deletion src/core/namespace.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ typedef struct MountEntry {
const char *path_const; /* Memory allocated on stack or static */
MountMode mode;
bool ignore:1; /* Ignore if path does not exist? */
bool has_prefix:1; /* Already is prefixed by the root dir? */
bool has_prefix:1; /* Already prefixed by the root dir? */
bool read_only:1; /* Shall this mount point be read-only? */
bool nosuid:1; /* Shall set MS_NOSUID on the mount itself */
bool noexec:1; /* Shall set MS_NOEXEC on the mount itself */
Expand All @@ -116,6 +116,12 @@ typedef struct MountList {
size_t n_mounts;
} MountList;

static const BindMount bind_journal_sockets_table[] = {
{ (char*) "/run/systemd/journal/socket", (char*) "/run/systemd/journal/socket", .read_only = true, .ignore_enoent = true },
{ (char*) "/run/systemd/journal/stdout", (char*) "/run/systemd/journal/stdout", .read_only = true, .ignore_enoent = true },
{ (char*) "/run/systemd/journal/dev-log", (char*) "/run/systemd/journal/dev-log", .read_only = true, .ignore_enoent = true },
};

/* If MountAPIVFS= is used, let's mount /sys, /proc, /dev and /run into the it, but only as a fallback if the user hasn't mounted
* something there already. These mounts are hence overridden by any other explicitly configured mounts. */
static const MountEntry apivfs_table[] = {
Expand Down Expand Up @@ -2480,6 +2486,11 @@ int setup_namespace(const NamespaceParameters *p, char **error_path) {
.read_only = true,
.source_malloc = TAKE_PTR(q),
};

} else if (p->bind_journal_sockets) {
r = append_bind_mounts(&ml, bind_journal_sockets_table, ELEMENTSOF(bind_journal_sockets_table));
if (r < 0)
return r;
}

/* Will be used to add bind mounts at runtime */
Expand Down
1 change: 1 addition & 0 deletions src/core/namespace.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ struct NamespaceParameters {
bool private_ipc;

bool mount_apivfs;
bool bind_journal_sockets;
bool mount_nosuid;

ProtectHome protect_home;
Expand Down
1 change: 1 addition & 0 deletions src/shared/bus-unit-util.c
Original file line number Diff line number Diff line change
Expand Up @@ -1075,6 +1075,7 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
"ProtectClock",
"ProtectControlGroups",
"MountAPIVFS",
"BindJournalSockets",
"CPUSchedulingResetOnFork",
"LockPersonality",
"ProtectHostname",
Expand Down

0 comments on commit 4bf703d

Please sign in to comment.