diff --git a/man/org.freedesktop.systemd1.xml b/man/org.freedesktop.systemd1.xml index 7ab560a654..31e6194bec 100644 --- a/man/org.freedesktop.systemd1.xml +++ b/man/org.freedesktop.systemd1.xml @@ -3207,6 +3207,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly b PrivateTmp = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") + readonly s PrivateTmpEx = '...'; + @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly b PrivateDevices = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly b ProtectClock = ...; @@ -3816,6 +3818,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { + + @@ -4504,6 +4508,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { + + @@ -5326,6 +5332,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket { @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly b PrivateTmp = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") + readonly s PrivateTmpEx = '...'; + @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly b PrivateDevices = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly b ProtectClock = ...; @@ -5949,6 +5957,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket { + + @@ -6613,6 +6623,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket { + + @@ -7299,6 +7311,8 @@ node /org/freedesktop/systemd1/unit/home_2emount { @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly b PrivateTmp = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") + readonly s PrivateTmpEx = '...'; + @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly b PrivateDevices = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly b ProtectClock = ...; @@ -7848,6 +7862,8 @@ node /org/freedesktop/systemd1/unit/home_2emount { + + @@ -8424,6 +8440,8 @@ node /org/freedesktop/systemd1/unit/home_2emount { + + @@ -9233,6 +9251,8 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap { @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly b PrivateTmp = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") + readonly s PrivateTmpEx = '...'; + @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly b PrivateDevices = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly b ProtectClock = ...; @@ -9768,6 +9788,8 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap { + + @@ -10330,6 +10352,8 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap { + + @@ -12019,7 +12043,7 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \ DumpUnitFileDescriptorStore() were added in version 254. StartAuxiliaryScope(), ShutdownStartTimestamp, - ShutdownStartTimestampMonotonic and + ShutdownStartTimestampMonotonic, and SoftRebootsCount were added in version 256. @@ -12074,6 +12098,9 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \ MemoryZSwapWriteback, ExecMainHandoffTimestampMonotonic, and ExecMainHandoffTimestamp were added in version 256. + StatusBusError, + StatusVarlinkError, and + PrivateTmpEx were added in version 257. Socket Unit Objects @@ -12110,6 +12137,7 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \ EffectiveTasksMax, MemoryZSwapWriteback, and PassFileDescriptorsToExec were added in version 256. + PrivateTmpEx was added in version 257. Mount Unit Objects @@ -12143,6 +12171,7 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \ EffectiveMemoryMax, EffectiveTasksMax, and MemoryZSwapWriteback were added in version 256. + PrivateTmpEx was added in version 257. Swap Unit Objects @@ -12176,6 +12205,7 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \ EffectiveMemoryMax, EffectiveTasksMax, and MemoryZSwapWriteback were added in version 256. + PrivateTmpEx was added in version 257. Slice Unit Objects @@ -12225,8 +12255,6 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \ EffectiveMemoryMax, EffectiveTasksMax, and MemoryZSwapWriteback were added in version 256. - StatusBusError - and StatusVarlinkError were added in version 257. Job Objects diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index 9e621b9aa3..7a2fc76b65 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -675,8 +675,8 @@ of IPC objects and temporary files created by the executed processes is bound to the runtime of the service, and hence the lifetime of the dynamic user/group. Since /tmp/ and /var/tmp/ are usually the only world-writable directories on a system, unless - PrivateTmp= is manually enabled, those directories will be placed on a private - tmpfs filesystem, as this ensures that a unit making use of dynamic user/group allocation cannot + PrivateTmp= is manually set to true, disconnected + would be implied. This ensures that a unit making use of dynamic user/group allocation cannot leave files around after unit termination. Furthermore NoNewPrivileges= and RestrictSUIDSGID= are implicitly enabled (and cannot be disabled), to ensure that processes invoked cannot take benefit or create SUID/SGID @@ -1748,20 +1748,27 @@ BindReadOnlyPaths=/var/lib/systemd PrivateTmp= - Takes a boolean argument. If true, sets up a new file system namespace for the - executed processes and mounts private /tmp/ and /var/tmp/ - directories inside it that are not shared by processes outside of the namespace. This is useful to - secure access to temporary files of the process, but makes sharing between processes via - /tmp/ or /var/tmp/ impossible. If true, all temporary files - created by a service in these directories will be removed after the service is stopped. Defaults to - false. It is possible to run two or more units within the same private /tmp/ and - /var/tmp/ namespace by using the JoinsNamespaceOf= directive, - see systemd.unit5 - for details. This setting is implied if DynamicUser= is set. For this setting, the - same restrictions regarding mount propagation and privileges apply as for - ReadOnlyPaths= and related calls, see above. Enabling this setting has the side - effect of adding Requires= and After= dependencies on all mount - units necessary to access /tmp/ and /var/tmp/. Moreover an + Takes a boolean argument, or disconnected. If enabled, a new + file system namespace will be set up for the executed processes, and /tmp/ + and /var/tmp/ directories inside it are not shared with processes outside of + the namespace, plus all temporary files created by a service in these directories will be removed after + the service is stopped. If true, the backing storage of the private temporary directories + will remain on the host's /tmp/ and /var/tmp/ directories. + If disconnected, the directories will be backed by a completely new tmpfs instance, + meaning that the storage is fully disconnected from the host namespace. Defaults to false. + + This setting is useful to secure access to temporary files of the process, but makes sharing + between processes via /tmp/ or /var/tmp/ impossible. + If not set to disconnected, it is possible to run two or more units within + the same private /tmp/ and /var/tmp/ namespace by using + the JoinsNamespaceOf= directive, see + systemd.unit5 + for details. This setting is implied if DynamicUser= is set. For this setting, + the same restrictions regarding mount propagation and privileges apply as for + ReadOnlyPaths= and related calls, see above. If set to true + (as opposed to disconnected), this has the side effect of adding + Requires= and After= dependencies on all mount units necessary + to access /tmp/ and /var/tmp/ on the host. Moreover an implicitly After= ordering on systemd-tmpfiles-setup.service8 is added. diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index 530a0f7a0b..0346ee1478 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -58,6 +58,7 @@ static BUS_DEFINE_PROPERTY_GET(property_get_mount_apivfs, "b", ExecContext, exec 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); +static BUS_DEFINE_PROPERTY_GET_REF(property_get_private_tmp_ex, "s", PrivateTmp, private_tmp_to_string); static BUS_DEFINE_PROPERTY_GET_REF(property_get_syslog_level, "i", int, LOG_PRI); static BUS_DEFINE_PROPERTY_GET_REF(property_get_syslog_facility, "i", int, LOG_FAC); static BUS_DEFINE_PROPERTY_GET(property_get_cpu_affinity_from_numa, "b", ExecContext, exec_context_get_cpu_affinity_from_numa); @@ -482,17 +483,16 @@ static int property_get_bind_paths( if (r < 0) return r; - for (size_t i = 0; i < c->n_bind_mounts; i++) { - - if (ro != c->bind_mounts[i].read_only) + FOREACH_ARRAY(i, c->bind_mounts, c->n_bind_mounts) { + if (ro != i->read_only) continue; r = sd_bus_message_append( reply, "(ssbt)", - c->bind_mounts[i].source, - c->bind_mounts[i].destination, - c->bind_mounts[i].ignore_enoent, - c->bind_mounts[i].recursive ? (uint64_t) MS_REC : UINT64_C(0)); + i->source, + i->destination, + i->ignore_enoent, + i->recursive ? (uint64_t) MS_REC : UINT64_C(0)); if (r < 0) return r; } @@ -520,9 +520,7 @@ static int property_get_temporary_filesystems( if (r < 0) return r; - for (unsigned i = 0; i < c->n_temporary_filesystems; i++) { - TemporaryFileSystem *t = c->temporary_filesystems + i; - + FOREACH_ARRAY(t, c->temporary_filesystems, c->n_temporary_filesystems) { r = sd_bus_message_append( reply, "(ss)", t->path, @@ -554,8 +552,8 @@ static int property_get_log_extra_fields( if (r < 0) return r; - for (size_t i = 0; i < c->n_log_extra_fields; i++) { - r = sd_bus_message_append_array(reply, 'y', c->log_extra_fields[i].iov_base, c->log_extra_fields[i].iov_len); + FOREACH_ARRAY(i, c->log_extra_fields, c->n_log_extra_fields) { + r = sd_bus_message_append_array(reply, 'y', i->iov_base, i->iov_len); if (r < 0) return r; } @@ -777,30 +775,35 @@ static int property_get_mount_images( if (r < 0) return r; - for (size_t i = 0; i < c->n_mount_images; i++) { + FOREACH_ARRAY(i, c->mount_images, c->n_mount_images) { r = sd_bus_message_open_container(reply, SD_BUS_TYPE_STRUCT, "ssba(ss)"); if (r < 0) return r; + r = sd_bus_message_append( reply, "ssb", - c->mount_images[i].source, - c->mount_images[i].destination, - c->mount_images[i].ignore_enoent); + i->source, + i->destination, + i->ignore_enoent); if (r < 0) return r; + r = sd_bus_message_open_container(reply, 'a', "(ss)"); if (r < 0) return r; - LIST_FOREACH(mount_options, m, c->mount_images[i].mount_options) { + + LIST_FOREACH(mount_options, m, i->mount_options) { r = sd_bus_message_append(reply, "(ss)", partition_designator_to_string(m->partition_designator), m->options); if (r < 0) return r; } + r = sd_bus_message_close_container(reply); if (r < 0) return r; + r = sd_bus_message_close_container(reply); if (r < 0) return r; @@ -829,29 +832,34 @@ static int property_get_extension_images( if (r < 0) return r; - for (size_t i = 0; i < c->n_extension_images; i++) { + FOREACH_ARRAY(i, c->extension_images, c->n_extension_images) { r = sd_bus_message_open_container(reply, SD_BUS_TYPE_STRUCT, "sba(ss)"); if (r < 0) return r; + r = sd_bus_message_append( reply, "sb", - c->extension_images[i].source, - c->extension_images[i].ignore_enoent); + i->source, + i->ignore_enoent); if (r < 0) return r; + r = sd_bus_message_open_container(reply, 'a', "(ss)"); if (r < 0) return r; - LIST_FOREACH(mount_options, m, c->extension_images[i].mount_options) { + + LIST_FOREACH(mount_options, m, i->mount_options) { r = sd_bus_message_append(reply, "(ss)", partition_designator_to_string(m->partition_designator), m->options); if (r < 0) return r; } + r = sd_bus_message_close_container(reply); if (r < 0) return r; + r = sd_bus_message_close_container(reply); if (r < 0) return r; @@ -860,7 +868,7 @@ static int property_get_extension_images( return sd_bus_message_close_container(reply); } -static int bus_property_get_exec_dir( +static int property_get_exec_dir( sd_bus *bus, const char *path, const char *interface, @@ -880,8 +888,8 @@ static int bus_property_get_exec_dir( if (r < 0) return r; - for (size_t i = 0; i < d->n_items; i++) { - r = sd_bus_message_append_basic(reply, 's', d->items[i].path); + FOREACH_ARRAY(i, d->items, d->n_items) { + r = sd_bus_message_append_basic(reply, 's', i->path); if (r < 0) return r; } @@ -889,7 +897,7 @@ static int bus_property_get_exec_dir( return sd_bus_message_close_container(reply); } -static int bus_property_get_exec_dir_symlink( +static int property_get_exec_dir_symlink( sd_bus *bus, const char *path, const char *interface, @@ -909,9 +917,9 @@ static int bus_property_get_exec_dir_symlink( if (r < 0) return r; - for (size_t i = 0; i < d->n_items; i++) - STRV_FOREACH(dst, d->items[i].symlinks) { - r = sd_bus_message_append(reply, "(sst)", d->items[i].path, *dst, UINT64_C(0) /* flags, unused for now */); + FOREACH_ARRAY(i, d->items, d->n_items) + STRV_FOREACH(dst, i->symlinks) { + r = sd_bus_message_append(reply, "(sst)", i->path, *dst, UINT64_C(0) /* flags, unused for now */); if (r < 0) return r; } @@ -943,6 +951,21 @@ static int property_get_image_policy( return sd_bus_message_append(reply, "s", s); } +static int property_get_private_tmp( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + PrivateTmp *p = ASSERT_PTR(userdata); + int b = *p != PRIVATE_TMP_OFF; + + return sd_bus_message_append_basic(reply, 'b', &b); +} + const sd_bus_vtable bus_exec_vtable[] = { SD_BUS_VTABLE_START(0), SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(ExecContext, environment), SD_BUS_VTABLE_PROPERTY_CONST), @@ -1055,7 +1078,8 @@ const sd_bus_vtable bus_exec_vtable[] = { SD_BUS_PROPERTY("NoExecPaths", "as", NULL, offsetof(ExecContext, no_exec_paths), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("ExecSearchPath", "as", NULL, offsetof(ExecContext, exec_search_path), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("MountFlags", "t", bus_property_get_ulong, offsetof(ExecContext, mount_propagation_flag), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("PrivateTmp", "b", bus_property_get_private_tmp, offsetof(ExecContext, private_tmp), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("PrivateTmp", "b", property_get_private_tmp, offsetof(ExecContext, private_tmp), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("PrivateTmpEx", "s", property_get_private_tmp_ex, offsetof(ExecContext, private_tmp), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("PrivateDevices", "b", bus_property_get_bool, offsetof(ExecContext, private_devices), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("ProtectClock", "b", bus_property_get_bool, offsetof(ExecContext, protect_clock), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("ProtectKernelTunables", "b", bus_property_get_bool, offsetof(ExecContext, protect_kernel_tunables), SD_BUS_VTABLE_PROPERTY_CONST), @@ -1083,21 +1107,21 @@ const sd_bus_vtable bus_exec_vtable[] = { SD_BUS_PROPERTY("Personality", "s", property_get_personality, offsetof(ExecContext, personality), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("LockPersonality", "b", bus_property_get_bool, offsetof(ExecContext, lock_personality), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("RestrictAddressFamilies", "(bas)", property_get_address_families, 0, SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("RuntimeDirectorySymlink", "a(sst)", bus_property_get_exec_dir_symlink, offsetof(ExecContext, directories[EXEC_DIRECTORY_RUNTIME]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("RuntimeDirectorySymlink", "a(sst)", property_get_exec_dir_symlink, offsetof(ExecContext, directories[EXEC_DIRECTORY_RUNTIME]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("RuntimeDirectoryPreserve", "s", bus_property_get_exec_preserve_mode, offsetof(ExecContext, runtime_directory_preserve_mode), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("RuntimeDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_RUNTIME].mode), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("RuntimeDirectory", "as", bus_property_get_exec_dir, offsetof(ExecContext, directories[EXEC_DIRECTORY_RUNTIME]), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("StateDirectorySymlink", "a(sst)", bus_property_get_exec_dir_symlink, offsetof(ExecContext, directories[EXEC_DIRECTORY_STATE]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("RuntimeDirectory", "as", property_get_exec_dir, offsetof(ExecContext, directories[EXEC_DIRECTORY_RUNTIME]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("StateDirectorySymlink", "a(sst)", property_get_exec_dir_symlink, offsetof(ExecContext, directories[EXEC_DIRECTORY_STATE]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("StateDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_STATE].mode), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("StateDirectory", "as", bus_property_get_exec_dir, offsetof(ExecContext, directories[EXEC_DIRECTORY_STATE]), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("CacheDirectorySymlink", "a(sst)", bus_property_get_exec_dir_symlink, offsetof(ExecContext, directories[EXEC_DIRECTORY_CACHE]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("StateDirectory", "as", property_get_exec_dir, offsetof(ExecContext, directories[EXEC_DIRECTORY_STATE]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("CacheDirectorySymlink", "a(sst)", property_get_exec_dir_symlink, offsetof(ExecContext, directories[EXEC_DIRECTORY_CACHE]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("CacheDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_CACHE].mode), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("CacheDirectory", "as", bus_property_get_exec_dir, offsetof(ExecContext, directories[EXEC_DIRECTORY_CACHE]), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("LogsDirectorySymlink", "a(sst)", bus_property_get_exec_dir_symlink, offsetof(ExecContext, directories[EXEC_DIRECTORY_LOGS]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("CacheDirectory", "as", property_get_exec_dir, offsetof(ExecContext, directories[EXEC_DIRECTORY_CACHE]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("LogsDirectorySymlink", "a(sst)", property_get_exec_dir_symlink, offsetof(ExecContext, directories[EXEC_DIRECTORY_LOGS]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("LogsDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_LOGS].mode), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("LogsDirectory", "as", bus_property_get_exec_dir, offsetof(ExecContext, directories[EXEC_DIRECTORY_LOGS]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("LogsDirectory", "as", property_get_exec_dir, offsetof(ExecContext, directories[EXEC_DIRECTORY_LOGS]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("ConfigurationDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_CONFIGURATION].mode), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("ConfigurationDirectory", "as", bus_property_get_exec_dir, offsetof(ExecContext, directories[EXEC_DIRECTORY_CONFIGURATION]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("ConfigurationDirectory", "as", property_get_exec_dir, offsetof(ExecContext, directories[EXEC_DIRECTORY_CONFIGURATION]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("TimeoutCleanUSec", "t", bus_property_get_usec, offsetof(ExecContext, timeout_clean_usec), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("MemoryDenyWriteExecute", "b", bus_property_get_bool, offsetof(ExecContext, memory_deny_write_execute), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("RestrictRealtime", "b", bus_property_get_bool, offsetof(ExecContext, restrict_realtime), SD_BUS_VTABLE_PROPERTY_CONST), @@ -1735,8 +1759,40 @@ int bus_exec_context_set_transient_property( if (streq(name, "TTYColumns")) return bus_set_transient_unsigned(u, name, &c->tty_cols, message, flags, error); - if (streq(name, "PrivateTmp")) - return bus_set_transient_private_tmp(u, name, &c->private_tmp, message, flags, error); + if (streq(name, "PrivateTmp")) { + int v; + + r = sd_bus_message_read(message, "b", &v); + if (r < 0) + return r; + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + c->private_tmp = v ? PRIVATE_TMP_CONNECTED : PRIVATE_TMP_OFF; + (void) unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(v)); + } + + return 1; + + } else if (streq(name, "PrivateTmpEx")) { + const char *s; + PrivateTmp t; + + r = sd_bus_message_read(message, "s", &s); + if (r < 0) + return r; + + t = private_tmp_from_string(s); + if (t < 0) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s setting: %s", name, s); + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + c->private_tmp = t; + (void) unit_write_settingf(u, flags, name, "PrivateTmp=%s", + private_tmp_to_string(c->private_tmp)); + } + + return 1; + } if (streq(name, "PrivateDevices")) return bus_set_transient_bool(u, name, &c->private_devices, message, flags, error); diff --git a/src/core/dbus-util.c b/src/core/dbus-util.c index 46676d7a21..b871d89368 100644 --- a/src/core/dbus-util.c +++ b/src/core/dbus-util.c @@ -150,45 +150,6 @@ int bus_set_transient_usec_internal( return 1; } -int bus_set_transient_private_tmp( - Unit *u, - const char *name, - PrivateTmp *p, - sd_bus_message *message, - UnitWriteFlags flags, - sd_bus_error *error) { - - int v, r; - - assert(p); - - r = sd_bus_message_read(message, "b", &v); - if (r < 0) - return r; - - if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - *p = v ? PRIVATE_TMP_CONNECTED : PRIVATE_TMP_OFF; - unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(v)); - } - - return 1; -} - -int bus_property_get_private_tmp( - sd_bus *bus, - const char *path, - const char *interface, - const char *property, - sd_bus_message *reply, - void *userdata, - sd_bus_error *error) { - - PrivateTmp *p = ASSERT_PTR(userdata); - int b = *p != PRIVATE_TMP_OFF; - - return sd_bus_message_append_basic(reply, 'b', &b); -} - int bus_verify_manage_units_async_full( Unit *u, const char *verb, diff --git a/src/core/dbus-util.h b/src/core/dbus-util.h index 29796eb249..0fc3a94961 100644 --- a/src/core/dbus-util.h +++ b/src/core/dbus-util.h @@ -4,7 +4,6 @@ #include "sd-bus.h" #include "dissect-image.h" -#include "execute.h" #include "unit.h" int bus_property_get_triggered_unit(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error); @@ -245,7 +244,6 @@ int bus_set_transient_string(Unit *u, const char *name, char **p, sd_bus_message int bus_set_transient_bool(Unit *u, const char *name, bool *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); int bus_set_transient_tristate(Unit *u, const char *name, int *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); int bus_set_transient_usec_internal(Unit *u, const char *name, usec_t *p, bool fix_0, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); -int bus_set_transient_private_tmp(Unit *u, const char *name, PrivateTmp *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); static inline int bus_set_transient_usec(Unit *u, const char *name, usec_t *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error) { return bus_set_transient_usec_internal(u, name, p, false, message, flags, error); } @@ -257,4 +255,3 @@ int bus_verify_manage_units_async_full(Unit *u, const char *verb, const char *po int bus_read_mount_options(sd_bus_message *message, sd_bus_error *error, MountOptions **ret_options, char **ret_format_str, const char *separator); int bus_property_get_activation_details(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error); -int bus_property_get_private_tmp(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error); diff --git a/src/core/exec-invoke.c b/src/core/exec-invoke.c index 8b88ccb1e9..45f1539f75 100644 --- a/src/core/exec-invoke.c +++ b/src/core/exec-invoke.c @@ -3205,8 +3205,6 @@ static int apply_mount_namespace( .temporary_filesystems = context->temporary_filesystems, .n_temporary_filesystems = context->n_temporary_filesystems, - .private_tmp = context->private_tmp, - .mount_images = context->mount_images, .n_mount_images = context->n_mount_images, .mount_image_policy = context->mount_image_policy ?: &image_policy_service, @@ -3245,6 +3243,7 @@ static int apply_mount_namespace( .private_dev = needs_sandboxing && context->private_devices, .private_network = needs_sandboxing && exec_needs_network_namespace(context), .private_ipc = needs_sandboxing && exec_needs_ipc_namespace(context), + .private_tmp = needs_sandboxing ? context->private_tmp : false, .mount_apivfs = needs_sandboxing && exec_context_get_effective_mount_apivfs(context), diff --git a/src/core/load-fragment-gperf.gperf.in b/src/core/load-fragment-gperf.gperf.in index 46c2198ac7..e04450d869 100644 --- a/src/core/load-fragment-gperf.gperf.in +++ b/src/core/load-fragment-gperf.gperf.in @@ -119,7 +119,7 @@ {{type}}.BindPaths, config_parse_bind_paths, 0, offsetof({{type}}, exec_context) {{type}}.BindReadOnlyPaths, config_parse_bind_paths, 0, offsetof({{type}}, exec_context) {{type}}.TemporaryFileSystem, config_parse_temporary_filesystems, 0, offsetof({{type}}, exec_context) -{{type}}.PrivateTmp, config_parse_private_tmp, 0, offsetof({{type}}, exec_context) +{{type}}.PrivateTmp, config_parse_private_tmp, 0, offsetof({{type}}, exec_context.private_tmp) {{type}}.PrivateDevices, config_parse_bool, 0, offsetof({{type}}, exec_context.private_devices) {{type}}.ProtectKernelTunables, config_parse_bool, 0, offsetof({{type}}, exec_context.protect_kernel_tunables) {{type}}.ProtectKernelModules, config_parse_bool, 0, offsetof({{type}}, exec_context.protect_kernel_modules) diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 3701270ab5..deeeafe2b8 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -133,6 +133,7 @@ DEFINE_CONFIG_PARSE_ENUM(config_parse_device_policy, cgroup_device_policy, CGrou DEFINE_CONFIG_PARSE_ENUM(config_parse_exec_keyring_mode, exec_keyring_mode, ExecKeyringMode, "Failed to parse keyring mode"); DEFINE_CONFIG_PARSE_ENUM(config_parse_protect_proc, protect_proc, ProtectProc, "Failed to parse /proc/ protection mode"); DEFINE_CONFIG_PARSE_ENUM(config_parse_proc_subset, proc_subset, ProcSubset, "Failed to parse /proc/ subset mode"); +DEFINE_CONFIG_PARSE_ENUM(config_parse_private_tmp, private_tmp, PrivateTmp, "Failed to parse private tmp value"); DEFINE_CONFIG_PARSE_ENUM(config_parse_exec_utmp_mode, exec_utmp_mode, ExecUtmpMode, "Failed to parse utmp mode"); DEFINE_CONFIG_PARSE_ENUM(config_parse_job_mode, job_mode, JobMode, "Failed to parse job mode"); DEFINE_CONFIG_PARSE_ENUM(config_parse_notify_access, notify_access, NotifyAccess, "Failed to parse notify access specifier"); @@ -5199,34 +5200,6 @@ int config_parse_temporary_filesystems( } } -int config_parse_private_tmp( - const char* unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - - ExecContext *c = ASSERT_PTR(data); - int r; - - assert(filename); - assert(rvalue); - - r = parse_boolean(rvalue); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse boolean value: %s ignoring", rvalue); - return 0; - } - - c->private_tmp = r ? PRIVATE_TMP_CONNECTED : PRIVATE_TMP_OFF; - return 0; -} - int config_parse_bind_paths( const char *unit, const char *filename, diff --git a/src/core/namespace.c b/src/core/namespace.c index 0a1d20b5bb..6d3cadf05c 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -2314,7 +2314,10 @@ int setup_namespace(const NamespaceParameters *p, char **error_path) { .source_dir_mode = 01777, .create_source_dir = true, }; - } else { + + } else if (p->tmp_dir || p->var_tmp_dir) { + assert(p->private_tmp == PRIVATE_TMP_CONNECTED); + if (p->tmp_dir) { bool ro = streq(p->tmp_dir, RUN_SYSTEMD_EMPTY); @@ -3154,4 +3157,4 @@ static const char* const private_tmp_table[_PRIVATE_TMP_MAX] = { [PRIVATE_TMP_DISCONNECTED] = "disconnected", }; -DEFINE_STRING_TABLE_LOOKUP(private_tmp, PrivateTmp); +DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(private_tmp, PrivateTmp, PRIVATE_TMP_CONNECTED);