diff --git a/man/org.freedesktop.systemd1.xml b/man/org.freedesktop.systemd1.xml index bede222670..0e1b5da333 100644 --- a/man/org.freedesktop.systemd1.xml +++ b/man/org.freedesktop.systemd1.xml @@ -2837,6 +2837,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly t RestrictNamespaces = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") + readonly (bas) RestrictFileSystems = ...; + @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly a(ssbt) BindPaths = [...]; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly a(ssbt) BindReadOnlyPaths = [...]; @@ -3362,6 +3364,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { + + @@ -3966,6 +3970,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { + + @@ -4677,6 +4683,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket { @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly t RestrictNamespaces = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") + readonly (bas) RestrictFileSystems = ...; + @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly a(ssbt) BindPaths = [...]; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly a(ssbt) BindReadOnlyPaths = [...]; @@ -5228,6 +5236,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket { + + @@ -5828,6 +5838,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket { + + @@ -6436,6 +6448,8 @@ node /org/freedesktop/systemd1/unit/home_2emount { @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly t RestrictNamespaces = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") + readonly (bas) RestrictFileSystems = ...; + @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly a(ssbt) BindPaths = [...]; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly a(ssbt) BindReadOnlyPaths = [...]; @@ -6915,6 +6929,8 @@ node /org/freedesktop/systemd1/unit/home_2emount { + + @@ -7433,6 +7449,8 @@ node /org/freedesktop/systemd1/unit/home_2emount { + + @@ -8162,6 +8180,8 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap { @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly t RestrictNamespaces = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") + readonly (bas) RestrictFileSystems = ...; + @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly a(ssbt) BindPaths = [...]; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly a(ssbt) BindReadOnlyPaths = [...]; @@ -8627,6 +8647,8 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap { + + @@ -9131,6 +9153,8 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap { + + diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index 488de1242a..87d6aefc84 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -37,6 +37,7 @@ #endif #include "securebits-util.h" #include "specifier.h" +#include "stat-util.h" #include "strv.h" #include "syslog-util.h" #include "unit-printf.h" @@ -681,6 +682,46 @@ static int property_get_input_data( return sd_bus_message_append_array(reply, 'y', c->stdin_data, c->stdin_data_size); } +static int property_get_restrict_filesystems( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + ExecContext *c = userdata; + _cleanup_free_ char **l = NULL; + int r; + + assert(bus); + assert(reply); + assert(c); + + r = sd_bus_message_open_container(reply, 'r', "bas"); + if (r < 0) + return r; + + r = sd_bus_message_append(reply, "b", c->restrict_filesystems_allow_list); + if (r < 0) + return r; + +#if HAVE_LIBBPF + l = set_get_strv(c->restrict_filesystems); + if (!l) + return -ENOMEM; +#endif + + strv_sort(l); + + r = sd_bus_message_append_strv(reply, l); + if (r < 0) + return r; + + return sd_bus_message_close_container(reply); +} + static int property_get_bind_paths( sd_bus *bus, const char *path, @@ -1199,6 +1240,7 @@ const sd_bus_vtable bus_exec_vtable[] = { SD_BUS_PROPERTY("RestrictRealtime", "b", bus_property_get_bool, offsetof(ExecContext, restrict_realtime), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("RestrictSUIDSGID", "b", bus_property_get_bool, offsetof(ExecContext, restrict_suid_sgid), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("RestrictNamespaces", "t", bus_property_get_ulong, offsetof(ExecContext, restrict_namespaces), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("RestrictFileSystems", "(bas)", property_get_restrict_filesystems, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("BindPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST), 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), @@ -1875,6 +1917,64 @@ int bus_exec_context_set_transient_property( if (streq(name, "RestrictNamespaces")) return bus_set_transient_namespace_flag(u, name, &c->restrict_namespaces, message, flags, error); + if (streq(name, "RestrictFileSystems")) { + int allow_list; + _cleanup_strv_free_ char **l = NULL; + + r = sd_bus_message_enter_container(message, 'r', "bas"); + if (r < 0) + return r; + + r = sd_bus_message_read(message, "b", &allow_list); + if (r < 0) + return r; + + r = sd_bus_message_read_strv(message, &l); + if (r < 0) + return r; + + r = sd_bus_message_exit_container(message); + if (r < 0) + return r; + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + _cleanup_free_ char *joined = NULL; + FilesystemParseFlags invert_flag = allow_list ? 0 : FILESYSTEM_PARSE_INVERT; + char **s; + + if (strv_isempty(l)) { + c->restrict_filesystems_allow_list = false; + c->restrict_filesystems = set_free(c->restrict_filesystems); + + unit_write_setting(u, flags, name, "RestrictFileSystems="); + return 1; + } + + if (!c->restrict_filesystems) + c->restrict_filesystems_allow_list = allow_list; + + STRV_FOREACH(s, l) { + r = lsm_bpf_parse_filesystem( + *s, + &c->restrict_filesystems, + FILESYSTEM_PARSE_LOG| + (invert_flag ? FILESYSTEM_PARSE_INVERT : 0)| + (c->restrict_filesystems_allow_list ? FILESYSTEM_PARSE_ALLOW_LIST : 0), + u->id, NULL, 0); + if (r < 0) + return r; + } + + joined = strv_join(l, " "); + if (!joined) + return -ENOMEM; + + unit_write_settingf(u, flags, name, "%s=%s%s", name, allow_list ? "" : "~", joined); + } + + return 1; + } + if (streq(name, "MountFlags")) return bus_set_transient_mount_flags(u, name, &c->mount_flags, message, flags, error); diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c index 01b78952cd..8b81e8058b 100644 --- a/src/shared/bus-unit-util.c +++ b/src/shared/bus-unit-util.c @@ -1386,6 +1386,7 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con } if (STR_IN_SET(field, "RestrictAddressFamilies", + "RestrictFileSystems", "SystemCallFilter", "SystemCallLog", "RestrictNetworkInterfaces")) {