From 3f6551fc823cadcaad10bea58d0fb09fbcee6b3e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 22 Apr 2024 12:03:00 +0200 Subject: [PATCH 01/16] man: run update-man-rules again --- man/rules/meson.build | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/man/rules/meson.build b/man/rules/meson.build index cf2be55bbd..a9a2a25c0d 100644 --- a/man/rules/meson.build +++ b/man/rules/meson.build @@ -553,7 +553,8 @@ manpages = [ '3', ['sd_event_add_inotify_fd', 'sd_event_inotify_handler_t', - 'sd_event_source_get_inotify_mask'], + 'sd_event_source_get_inotify_mask', + 'sd_event_source_get_inotify_path'], ''], ['sd_event_add_io', '3', From 3c7f0d6b4401ab3ca62f6021adeb533a8e3802a6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 22 Apr 2024 11:18:45 +0200 Subject: [PATCH 02/16] man: explicitly say that BindPaths=/BindReadOnlyPaths= opens a new mount namespace Fixes: #32339 --- man/systemd.exec.xml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index 64b7b07fc7..598a399b93 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -443,6 +443,9 @@ that in this case both read-only and regular bind mounts are reset, regardless which of the two settings is used. + Using this option implies that a mount namespace is allocated for the unit, i.e. it implies the + effect of PrivateMounts= (see below). + This option is particularly useful when RootDirectory=/RootImage= is used. In this case the source path refers to a path on the host file system, while the destination path refers to a path below the root directory of the unit. @@ -2372,8 +2375,9 @@ RestrictNamespaces=~cgroup net Other file system namespace unit settings — PrivateTmp=, PrivateDevices=, ProtectSystem=, ProtectHome=, ReadOnlyPaths=, - InaccessiblePaths=, ReadWritePaths=, … — also enable file - system namespacing in a fashion equivalent to this option. Hence it is primarily useful to explicitly + InaccessiblePaths=, ReadWritePaths=, + BindPaths=, BindReadOnlyPaths=, … — also enable file system + namespacing in a fashion equivalent to this option. Hence it is primarily useful to explicitly request this behaviour if none of the other settings are used. From db2b49942313bf44c63b162e603045b7e2114e08 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 22 Apr 2024 11:26:26 +0200 Subject: [PATCH 03/16] journald: bring order of MaxLevelXYZ= setting explanations in sync with listed names --- man/journald.conf.xml | 39 +++++++++++++-------------------------- 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/man/journald.conf.xml b/man/journald.conf.xml index 4aa8a0ef42..4882ea816b 100644 --- a/man/journald.conf.xml +++ b/man/journald.conf.xml @@ -434,32 +434,19 @@ MaxLevelWall= MaxLevelSocket= - Controls the maximum log level of messages - that are stored in the journal, forwarded to syslog, kmsg, the - console, a socket, or wall (if that is enabled, see above). - As argument, takes one of - emerg, - alert, - crit, - err, - warning, - notice, - info, - debug, - or integer values in the range of 0–7 (corresponding to the - same levels). Messages equal or below the log level specified - are stored/forwarded, messages above are dropped. Defaults to - debug for MaxLevelStore=, - MaxLevelSyslog= and - MaxLevelSocket=, to ensure that the all - messages are stored in the journal, forwarded to syslog and - the socket if one exists. - Defaults to - notice for MaxLevelKMsg=, - info for MaxLevelConsole=, - and emerg for - MaxLevelWall=. These settings may be - overridden at boot time with the kernel command line options + Controls the maximum log level of messages that are stored in the journal, forwarded + to syslog, kmsg, the console, the wall, or a socket (if that is enabled, see above). As argument, + takes one of emerg, alert, crit, + err, warning, notice, + info, debug, or integer values in the range of 0–7 + (corresponding to the same levels). Messages equal or below the log level specified are + stored/forwarded, messages above are dropped. Defaults to debug for + MaxLevelStore=, MaxLevelSyslog= and + MaxLevelSocket=, to ensure that the all messages are stored in the journal, + forwarded to syslog and the socket if one exists. Defaults to notice for + MaxLevelKMsg=, info for MaxLevelConsole=, + and emerg for MaxLevelWall=. These settings may be overridden + at boot time with the kernel command line options systemd.journald.max_level_store=, systemd.journald.max_level_syslog=, systemd.journald.max_level_kmsg=, From 0adce85ebe7a4621c23a53466fd405e4fdd82b68 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 22 Apr 2024 11:26:42 +0200 Subject: [PATCH 04/16] man: explicitly document the various systemd.journald.max_level_*= kernel cmdline options Fixes: #31327 --- man/systemd-journald.service.xml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/man/systemd-journald.service.xml b/man/systemd-journald.service.xml index 91be3178dd..8eeb209b07 100644 --- a/man/systemd-journald.service.xml +++ b/man/systemd-journald.service.xml @@ -247,6 +247,24 @@ systemd-tmpfiles --create --prefix /var/log/journal + + + systemd.journald.max_level_store= + systemd.journald.max_level_syslog= + systemd.journald.max_level_kmsg= + systemd.journald.max_level_console= + systemd.journald.max_level_wall= + systemd.journald.max_level_socket= + + Controls the maximum log level of messages that are stored in the journal, forwarded + to syslog, kmsg, the console, the wall, or a socket. This kernel command line options override the + settings of the same names in the + journald.conf5 + file. + + + + Note that these kernel command line options are only honoured by the default namespace, see From 6b7a1a3679f1facbc192d4abd209530002510f34 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 22 Apr 2024 11:34:59 +0200 Subject: [PATCH 05/16] man: document explicitly that bind restrictions cannot be escaped by opening a new netns And while we are at it reword the introductary sentence a bit to make it clearer. Fixes: #30555 --- man/systemd.resource-control.xml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/man/systemd.resource-control.xml b/man/systemd.resource-control.xml index d5b77dc833..b6efb5b990 100644 --- a/man/systemd.resource-control.xml +++ b/man/systemd.resource-control.xml @@ -890,8 +890,10 @@ CPUWeight=20 DisableControllers=cpu / \ SocketBindDeny=bind-rule - Allow or deny binding a socket address to a socket by matching it with the bind-rule and - applying a corresponding action if there is a match. + Configures restrictions on the ability of unit processes to invoke bind2 on a + socket. Both allow and deny rules may defined that restrict which addresses a socket may be bound + to. bind-rule describes socket properties such as address-family, transport-protocol and ip-ports. @@ -938,6 +940,13 @@ CPUWeight=20 DisableControllers=cpu / \ The feature is implemented with cgroup/bind4 and cgroup/bind6 cgroup-bpf hooks. + + Note that these settings apply to any bind2 + system call invocation by the unit processes, regardless in which network namespace they are + placed. Or in other words: changing the network namespace is not a suitable mechanism for escaping + these restrictions on bind(). + Examples:… # Allow binding IPv6 socket addresses with a port greater than or equal to 10000. [Service] From 552dc4a97c3de76afb0bb0ef8dbe463382e93838 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 22 Apr 2024 11:37:41 +0200 Subject: [PATCH 06/16] man: document explicitly that LogExtraFields= and LogFilterPatterns= are for system service only for now Fixes: #29956 --- man/systemd.exec.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index 598a399b93..7e49d8e267 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -3136,6 +3136,9 @@ StandardInputData=V2XigLJyZSBubyBzdHJhbmdlcnMgdG8gbG92ZQpZb3Uga25vdyB0aGUgcnVsZX values are indexed may also be used to implement cross-unit log record matching. Assign an empty string to reset the list. + Note that this functionality is currently only available in system services, not in per-user + services. + @@ -3191,6 +3194,9 @@ StandardInputData=V2XigLJyZSBubyBzdHJhbmdlcnMgdG8gbG92ZQpZb3Uga25vdyB0aGUgcnVsZX the kernel log buffer (kmsg), the systemd console, or sent as wall messages to all logged-in users. + Note that this functionality is currently only available in system services, not in per-user + services. + From 04366e06938c64ff1140a7b82c6cbfd898449c92 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 22 Apr 2024 11:48:20 +0200 Subject: [PATCH 07/16] man: document that StateDirectory= trumps ProtectSystem=strict explicitly Fixes: #29798 --- man/systemd.exec.xml | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index 7e49d8e267..c11c7db706 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -1396,14 +1396,16 @@ CapabilityBoundingSet=~CAP_B CAP_C mounted read-only, except for the API file system subtrees /dev/, /proc/ and /sys/ (protect these directories using PrivateDevices=, ProtectKernelTunables=, - ProtectControlGroups=). This setting ensures that any modification of the vendor-supplied - operating system (and optionally its configuration, and local mounts) is prohibited for the service. It is - recommended to enable this setting for all long-running services, unless they are involved with system updates - or need to modify the operating system in other ways. If this option is used, - ReadWritePaths= may be used to exclude specific directories from being made read-only. This - setting is implied if DynamicUser= is set. This setting cannot ensure protection in all - cases. In general it has the same limitations as ReadOnlyPaths=, see below. Defaults to - off. + ProtectControlGroups=). This setting ensures that any modification of the + vendor-supplied operating system (and optionally its configuration, and local mounts) is prohibited + for the service. It is recommended to enable this setting for all long-running services, unless they + are involved with system updates or need to modify the operating system in other ways. If this option + is used, ReadWritePaths= may be used to exclude specific directories from being + made read-only. Similar, StateDirectory=, LogsDirectory=, … and + related directory settings (see below) also exclude the specific directories from the effect of + ProtectSystem=. This setting is implied if DynamicUser= is + set. This setting cannot ensure protection in all cases. In general it has the same limitations as + ReadOnlyPaths=, see below. Defaults to off. From 403492793a63d85737cfee4fd80f5d3778b1c901 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 22 Apr 2024 12:02:51 +0200 Subject: [PATCH 08/16] man: document missing resolved D-Bus APIs Fixes: #29598 --- man/org.freedesktop.resolve1.xml | 41 ++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/man/org.freedesktop.resolve1.xml b/man/org.freedesktop.resolve1.xml index c70e5c1cb3..1cf55fea7c 100644 --- a/man/org.freedesktop.resolve1.xml +++ b/man/org.freedesktop.resolve1.xml @@ -103,7 +103,7 @@ node /org/freedesktop/resolve1 { SetLinkDNSSECNegativeTrustAnchors(in i ifindex, in as names); RevertLink(in i ifindex); - RegisterService(in s name, + RegisterService(in s id, in s name_template, in s type, in q service_port, @@ -156,16 +156,6 @@ node /org/freedesktop/resolve1 { }; - - - - - - - - - - @@ -433,6 +423,30 @@ node /org/freedesktop/resolve1 { The RevertLink() method may be used to revert all per-link settings described above to the defaults. + The FlushCaches() flushes all resource record caches maintained by the + resolver, and ensures that any subsequent lookups re-request their responses from their sources. + + The ResetServerFeatures() flushes any feature information learned about + remote DNS servers. This ensures that subsequent lookups will be initially attempted at the highest DNS + protocol feature level again, possibly requiring a (potentially slow) downgrade cycle to recognize the + supported feature level again. + + The RegisterService() method may be used to register a DNS-SD service on the + host. This functionality is closely related to the functionality provided by + systemd.dnssd5 + files. It takes a server identifier string as first parameter (this is jus a local identifier, and + should be chosen so that it neither collides with the basename of *.dnssd files + nor with names chosen by other IPC clients). It also takes a name template string for the DNS-SD + service name visible on the network. This string is subject to specifier expansation, as documented for + the Name= setting in *.dnssd files. It also takes a service + type string containing the DNS-SD service type, as well as an IP port, a priority/weight pair for the + DNS-SD SRV record. Finally, it takes an array of TXT record data. It returns an object path which may be + used as handle to the registered service. + + The UnregisterService() method undoes the effect of + RegisterService() and deletes a DNS-SD service previously created via IPC + again. + The Flags Parameter @@ -636,6 +650,9 @@ node /org/freedesktop/resolve1 { enabled. Possible values are yes (enabled), no (disabled), udp (only the UDP listener is enabled), and tcp (only the TCP listener is enabled). + + The DNSSECNegativeTrustAnchors property contains a list of recognized DNSSEC + negative trust anchors and contains a list of domains. @@ -690,8 +707,6 @@ node /org/freedesktop/resolve1/link/_1 { }; - - From 407630164e20f0555cd9b20f38e35a0555c1af63 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 22 Apr 2024 12:23:03 +0200 Subject: [PATCH 09/16] resolved: rename DnssdService.filename field to .path It contains a full path, not just a filename, hence name it appropriately. --- src/resolve/resolved-dnssd.c | 14 +++++++------- src/resolve/resolved-dnssd.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/resolve/resolved-dnssd.c b/src/resolve/resolved-dnssd.c index aadac3f102..6837b0e140 100644 --- a/src/resolve/resolved-dnssd.c +++ b/src/resolve/resolved-dnssd.c @@ -48,7 +48,7 @@ DnssdService *dnssd_service_free(DnssdService *service) { dnssd_txtdata_free_all(service->txt_data_items); - free(service->filename); + free(service->path); free(service->name); free(service->type); free(service->subtype); @@ -67,7 +67,7 @@ void dnssd_service_clear_on_reload(Hashmap *services) { } } -static int dnssd_service_load(Manager *manager, const char *filename) { +static int dnssd_service_load(Manager *manager, const char *path) { _cleanup_(dnssd_service_freep) DnssdService *service = NULL; _cleanup_(dnssd_txtdata_freep) DnssdTxtData *txt_data = NULL; char *d; @@ -75,17 +75,17 @@ static int dnssd_service_load(Manager *manager, const char *filename) { int r; assert(manager); - assert(filename); + assert(path); service = new0(DnssdService, 1); if (!service) return log_oom(); - service->filename = strdup(filename); - if (!service->filename) + service->path = strdup(path); + if (!service->path) return log_oom(); - service->name = strdup(basename(filename)); + service->name = strdup(basename(path)); if (!service->name) return log_oom(); @@ -100,7 +100,7 @@ static int dnssd_service_load(Manager *manager, const char *filename) { dropin_dirname = strjoina(service->name, ".dnssd.d"); r = config_parse_many( - STRV_MAKE_CONST(filename), DNSSD_SERVICE_DIRS, dropin_dirname, /* root = */ NULL, + STRV_MAKE_CONST(path), DNSSD_SERVICE_DIRS, dropin_dirname, /* root = */ NULL, "Service\0", config_item_perf_lookup, resolved_dnssd_gperf_lookup, CONFIG_PARSE_WARN, diff --git a/src/resolve/resolved-dnssd.h b/src/resolve/resolved-dnssd.h index e7f2add397..cb0059fe55 100644 --- a/src/resolve/resolved-dnssd.h +++ b/src/resolve/resolved-dnssd.h @@ -26,7 +26,7 @@ struct DnssdTxtData { }; struct DnssdService { - char *filename; + char *path; char *name; char *name_template; char *type; From 0ef0e2691a6ec17ed4ba78292e5767e07a61dd8d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 22 Apr 2024 12:30:16 +0200 Subject: [PATCH 10/16] resolved: rename DnssdService "name" field to "id" "name" is a bit confusing since this field is *not* the DNS-SD service identifier, bust just some string derived from the .dnssd filename that is used as handle for the service. Let's hence give it a better name: "id". While we are at it, switch from basename() to path_extract_filename(). --- src/resolve/resolved-bus.c | 18 ++++----- src/resolve/resolved-dnssd-bus.c | 2 +- src/resolve/resolved-dnssd.c | 63 ++++++++++++++++++++------------ src/resolve/resolved-dnssd.h | 2 +- src/resolve/resolved-manager.c | 4 +- 5 files changed, 52 insertions(+), 37 deletions(-) diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c index 986a90f9f2..080a4becce 100644 --- a/src/resolve/resolved-bus.c +++ b/src/resolve/resolved-bus.c @@ -1866,7 +1866,7 @@ static int bus_method_register_service(sd_bus_message *message, void *userdata, _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL; _cleanup_(dnssd_service_freep) DnssdService *service = NULL; _cleanup_(sd_bus_track_unrefp) sd_bus_track *bus_track = NULL; - const char *name, *name_template, *type; + const char *id, *name_template, *type; _cleanup_free_ char *path = NULL; DnssdService *s = NULL; Manager *m = ASSERT_PTR(userdata); @@ -1892,21 +1892,21 @@ static int bus_method_register_service(sd_bus_message *message, void *userdata, service->originator = euid; service->config_source = RESOLVE_CONFIG_SOURCE_DBUS; - r = sd_bus_message_read(message, "sssqqq", &name, &name_template, &type, + r = sd_bus_message_read(message, "sssqqq", &id, &name_template, &type, &service->port, &service->priority, &service->weight); if (r < 0) return r; - s = hashmap_get(m->dnssd_services, name); + s = hashmap_get(m->dnssd_services, id); if (s) - return sd_bus_error_setf(error, BUS_ERROR_DNSSD_SERVICE_EXISTS, "DNS-SD service '%s' exists already", name); + return sd_bus_error_setf(error, BUS_ERROR_DNSSD_SERVICE_EXISTS, "DNS-SD service '%s' exists already", id); if (!dnssd_srv_type_is_valid(type)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "DNS-SD service type '%s' is invalid", type); - service->name = strdup(name); - if (!service->name) + service->id = strdup(id); + if (!service->id) return log_oom(); service->name_template = strdup(name_template); @@ -1999,7 +1999,7 @@ static int bus_method_register_service(sd_bus_message *message, void *userdata, txt_data = NULL; } - r = sd_bus_path_encode("/org/freedesktop/resolve1/dnssd", service->name, &path); + r = sd_bus_path_encode("/org/freedesktop/resolve1/dnssd", service->id, &path); if (r < 0) return r; @@ -2014,7 +2014,7 @@ static int bus_method_register_service(sd_bus_message *message, void *userdata, if (r == 0) return 1; /* Polkit will call us back */ - r = hashmap_ensure_put(&m->dnssd_services, &string_hash_ops, service->name, service); + r = hashmap_ensure_put(&m->dnssd_services, &string_hash_ops, service->id, service); if (r < 0) return r; @@ -2178,7 +2178,7 @@ static const sd_bus_vtable resolve_vtable[] = { bus_method_revert_link, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD_WITH_ARGS("RegisterService", - SD_BUS_ARGS("s", name, + SD_BUS_ARGS("s", id, "s", name_template, "s", type, "q", service_port, diff --git a/src/resolve/resolved-dnssd-bus.c b/src/resolve/resolved-dnssd-bus.c index bdb3c2a893..4857a92b01 100644 --- a/src/resolve/resolved-dnssd-bus.c +++ b/src/resolve/resolved-dnssd-bus.c @@ -107,7 +107,7 @@ static int dnssd_node_enumerator(sd_bus *bus, const char *path, void *userdata, HASHMAP_FOREACH(service, m->dnssd_services) { char *p; - r = sd_bus_path_encode("/org/freedesktop/resolve1/dnssd", service->name, &p); + r = sd_bus_path_encode("/org/freedesktop/resolve1/dnssd", service->id, &p); if (r < 0) return r; diff --git a/src/resolve/resolved-dnssd.c b/src/resolve/resolved-dnssd.c index 6837b0e140..5f66e3c501 100644 --- a/src/resolve/resolved-dnssd.c +++ b/src/resolve/resolved-dnssd.c @@ -3,10 +3,11 @@ #include "conf-files.h" #include "conf-parser.h" #include "constants.h" -#include "resolved-dnssd.h" -#include "resolved-dns-rr.h" -#include "resolved-manager.h" +#include "path-util.h" #include "resolved-conf.h" +#include "resolved-dns-rr.h" +#include "resolved-dnssd.h" +#include "resolved-manager.h" #include "specifier.h" #include "strv.h" @@ -40,7 +41,7 @@ DnssdService *dnssd_service_free(DnssdService *service) { return NULL; if (service->manager) - hashmap_remove(service->manager->dnssd_services, service->name); + hashmap_remove(service->manager->dnssd_services, service->id); dns_resource_record_unref(service->ptr_rr); dns_resource_record_unref(service->sub_ptr_rr); @@ -49,7 +50,7 @@ DnssdService *dnssd_service_free(DnssdService *service) { dnssd_txtdata_free_all(service->txt_data_items); free(service->path); - free(service->name); + free(service->id); free(service->type); free(service->subtype); free(service->name_template); @@ -62,16 +63,36 @@ void dnssd_service_clear_on_reload(Hashmap *services) { HASHMAP_FOREACH(service, services) if (service->config_source == RESOLVE_CONFIG_SOURCE_FILE) { - hashmap_remove(services, service->name); + hashmap_remove(services, service->id); dnssd_service_free(service); } } +static int dnssd_id_from_path(const char *path, char **ret_id) { + int r; + + assert(path); + assert(ret_id); + + _cleanup_free_ char *fn = NULL; + r = path_extract_filename(path, &fn); + if (r < 0) + return r; + + char *d = endswith(fn, ".dnssd"); + if (!d) + return -EINVAL; + + *d = '\0'; + + *ret_id = TAKE_PTR(fn); + return 0; +} + static int dnssd_service_load(Manager *manager, const char *path) { _cleanup_(dnssd_service_freep) DnssdService *service = NULL; _cleanup_(dnssd_txtdata_freep) DnssdTxtData *txt_data = NULL; - char *d; - const char *dropin_dirname; + _cleanup_free_ char *dropin_dirname = NULL; int r; assert(manager); @@ -85,20 +106,14 @@ static int dnssd_service_load(Manager *manager, const char *path) { if (!service->path) return log_oom(); - service->name = strdup(basename(path)); - if (!service->name) + r = dnssd_id_from_path(path, &service->id); + if (r < 0) + return log_error_errno(r, "Failed to extract DNS-SD service id from filename: %m"); + + dropin_dirname = strjoin(service->id, ".dnssd.d"); + if (!dropin_dirname) return log_oom(); - d = endswith(service->name, ".dnssd"); - if (!d) - return -EINVAL; - - assert(streq(d, ".dnssd")); - - *d = '\0'; - - dropin_dirname = strjoina(service->name, ".dnssd.d"); - r = config_parse_many( STRV_MAKE_CONST(path), DNSSD_SERVICE_DIRS, dropin_dirname, /* root = */ NULL, "Service\0", @@ -113,12 +128,12 @@ static int dnssd_service_load(Manager *manager, const char *path) { if (!service->name_template) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "%s doesn't define service instance name", - service->name); + service->id); if (!service->type) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "%s doesn't define service type", - service->name); + service->id); if (!service->txt_data_items) { txt_data = new0(DnssdTxtData, 1); @@ -133,7 +148,7 @@ static int dnssd_service_load(Manager *manager, const char *path) { TAKE_PTR(txt_data); } - r = hashmap_ensure_put(&manager->dnssd_services, &string_hash_ops, service->name, service); + r = hashmap_ensure_put(&manager->dnssd_services, &string_hash_ops, service->id, service); if (r < 0) return r; @@ -369,7 +384,7 @@ int dnssd_signal_conflict(Manager *manager, const char *name) { s->withdrawn = true; - r = sd_bus_path_encode("/org/freedesktop/resolve1/dnssd", s->name, &path); + r = sd_bus_path_encode("/org/freedesktop/resolve1/dnssd", s->id, &path); if (r < 0) return log_error_errno(r, "Can't get D-BUS object path: %m"); diff --git a/src/resolve/resolved-dnssd.h b/src/resolve/resolved-dnssd.h index cb0059fe55..84f7853b81 100644 --- a/src/resolve/resolved-dnssd.h +++ b/src/resolve/resolved-dnssd.h @@ -27,7 +27,7 @@ struct DnssdTxtData { struct DnssdService { char *path; - char *name; + char *id; char *name_template; char *type; char *subtype; diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c index 568ee00280..99787f7822 100644 --- a/src/resolve/resolved-manager.c +++ b/src/resolve/resolved-manager.c @@ -1349,7 +1349,7 @@ void manager_refresh_rrs(Manager *m) { if (m->mdns_support == RESOLVE_SUPPORT_YES) HASHMAP_FOREACH(s, m->dnssd_services) if (dnssd_update_rrs(s) < 0) - log_warning("Failed to refresh DNS-SD service '%s'", s->name); + log_warning("Failed to refresh DNS-SD service '%s'", s->id); HASHMAP_FOREACH(l, m->links) link_add_rrs(l, false); @@ -1778,7 +1778,7 @@ bool manager_next_dnssd_names(Manager *m) { r = manager_next_random_name(s->name_template, &new_name); if (r < 0) { - log_warning_errno(r, "Failed to get new name for service '%s': %m", s->name); + log_warning_errno(r, "Failed to get new name for service '%s': %m", s->id); continue; } From c903d3df6ff848c5f1c1e8a4aaaaa3d2d219c339 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 22 Apr 2024 12:32:54 +0200 Subject: [PATCH 11/16] resolved: tighten the rules a bit on valid DNS-SD service identifiers Let's insist that the ID is suitable for inclusion in a filename, as one of the most basic of requirements. --- src/resolve/resolved-bus.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c index 080a4becce..d6d2273dc9 100644 --- a/src/resolve/resolved-bus.c +++ b/src/resolve/resolved-bus.c @@ -11,6 +11,7 @@ #include "format-util.h" #include "memory-util.h" #include "missing_capability.h" +#include "path-util.h" #include "resolved-bus.h" #include "resolved-def.h" #include "resolved-dns-stream.h" @@ -1898,13 +1899,16 @@ static int bus_method_register_service(sd_bus_message *message, void *userdata, if (r < 0) return r; - s = hashmap_get(m->dnssd_services, id); - if (s) - return sd_bus_error_setf(error, BUS_ERROR_DNSSD_SERVICE_EXISTS, "DNS-SD service '%s' exists already", id); + if (!filename_part_is_valid(id)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "DNS-SD service identifier '%s' is invalid", id); if (!dnssd_srv_type_is_valid(type)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "DNS-SD service type '%s' is invalid", type); + s = hashmap_get(m->dnssd_services, id); + if (s) + return sd_bus_error_setf(error, BUS_ERROR_DNSSD_SERVICE_EXISTS, "DNS-SD service '%s' exists already", id); + service->id = strdup(id); if (!service->id) return log_oom(); From afc194a135fe6d3680e471eeb177961eeffbcfb3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 22 Apr 2024 12:39:30 +0200 Subject: [PATCH 12/16] man: say explicitly that $LESS + $LESSCHARSET have no effect on less invocations by systemd tools Fixes: #29479 --- man/common-variables.xml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/man/common-variables.xml b/man/common-variables.xml index 58a285c833..2d26bf7242 100644 --- a/man/common-variables.xml +++ b/man/common-variables.xml @@ -146,6 +146,9 @@ + Note that setting the regular $LESS environment variable has no effect + for less invocations by systemd tools. + See less1 for more discussion. @@ -155,7 +158,10 @@ $SYSTEMD_LESSCHARSET Override the charset passed to less (by default utf-8, if - the invoking terminal is determined to be UTF-8 compatible). + the invoking terminal is determined to be UTF-8 compatible). + + Note that setting the regular $LESSCHARSET environment variable has no effect + for less invocations by systemd tools. From c104d7a74edf0e22001adf02d4deb71d0b4661c1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 22 Apr 2024 12:57:38 +0200 Subject: [PATCH 13/16] man: document that "systemctl set-environment" cannot be used to unset env vars configured via config file Fixes: #28167 --- man/systemctl.xml | 68 ++++++++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/man/systemctl.xml b/man/systemctl.xml index a8bc85707b..a68ff5c958 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -1363,36 +1363,49 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err show-environment - Dump the systemd manager environment block. This is the environment - block that is passed to all processes the manager spawns. The environment - block will be dumped in straightforward form suitable for sourcing into - most shells. If no special characters or whitespace is present in the variable - values, no escaping is performed, and the assignments have the form - VARIABLE=value. If whitespace or characters which have - special meaning to the shell are present, dollar-single-quote escaping is - used, and assignments have the form VARIABLE=$'value'. - This syntax is known to be supported by - bash1, - zsh1, - ksh1, - and - busybox1's - ash1, - but not - dash1 - or - fish1. + Dump the systemd manager environment block. This is the environment block that is passed to + all processes the manager spawns. The environment block will be dumped in straightforward form + suitable for sourcing into most shells. If no special characters or whitespace is present in the + variable values, no escaping is performed, and the assignments have the form + VARIABLE=value. If whitespace or characters which have special meaning to the + shell are present, dollar-single-quote escaping is used, and assignments have the form + VARIABLE=$'value'. This syntax is known to be supported by bash1, + zsh1, + ksh1, and + busybox1's + ash1, but + not dash1 or + fish1. + + Note that this shows the effective block, i.e. the combination of + environment variables configured via configuration files, environment generators and via IPC + (i.e. via the set-environment described below). At the moment a unit process + is forked off this combined environment block will be further combined with per-unit environment + variables, which are not visible in this command. set-environment VARIABLE=VALUE… - Set one or more systemd manager environment variables, as specified on the command + Set one or more service manager environment variables, as specified on the command line. This command will fail if variable names and values do not conform to the rules listed above. + Note that this operates on an environment block separate from the environment block + configured from service manager configuration and environment generators. Whenever a process is + invoked the two blocks are combined (also incorporating any per-service environment variables), + and passed to it. The show-environment verb will show the combination of the + blocks, see above. + @@ -1400,11 +1413,16 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err unset-environment VARIABLE… - Unset one or more systemd manager environment - variables. If only a variable name is specified, it will be - removed regardless of its value. If a variable and a value - are specified, the variable is only removed if it has the - specified value. + Unset one or more systemd manager environment variables. If only a variable name is + specified, it will be removed regardless of its value. If a variable and a value are specified, + the variable is only removed if it has the specified value. + + Note that this operates on an environment block separate from the environment block + configured from service manager configuration and environment generators. Whenever a process is + invoked the two blocks are combined (also incorporating any per-service environment variables), + and passed to it. The show-environment verb will show the combination of the + blocks, see above. Note that this means this command cannot be used to unset environment + variables defined in the service manager configuration files or via generators. From fef46ffb5b3a98cb557c9f77d230fbb220355b9e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 22 Apr 2024 13:02:08 +0200 Subject: [PATCH 14/16] man: document that ReadOnlyPaths= doesn't affect ability to connect to AF_UNIX Fixes: #23470 --- man/systemd.exec.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index c11c7db706..44233d0265 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -1383,6 +1383,11 @@ CapabilityBoundingSet=~CAP_B CAP_C accessible to privileged processes. However, most namespacing settings, that will not work on their own in user services, will work when used in conjunction with PrivateUsers=. + Note that the various options that turn directories read-only (such as + ProtectSystem=, ReadOnlyPaths=, …) do not affect the ability for + programs to connect to and communicate with AF_UNIX sockets in these + directores. These options cannot be used to lock down access to IPC services hence. + From ef9262d0d178dd72488559ad88f2ce8980e5e6d7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 22 Apr 2024 13:06:48 +0200 Subject: [PATCH 15/16] man: be explicit that we don't proxy SO_PEER*, SCM_RIGHTS and co. Fixes: #22744 --- man/systemd-socket-proxyd.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/man/systemd-socket-proxyd.xml b/man/systemd-socket-proxyd.xml index 829cc95805..dde6d888ad 100644 --- a/man/systemd-socket-proxyd.xml +++ b/man/systemd-socket-proxyd.xml @@ -53,6 +53,11 @@ Accept=no and an event-driven design that scales better with the number of connections. + + Note that systemd-socket-proxyd will not forward socket side channel + information, i.e. will not forward SCM_RIGHTS, SCM_CREDENTIALS, + SCM_SECURITY, SO_PEERCRED, SO_PEERPIDFD, + SO_PEERSEC, SO_PEERGROUPS and similar. Options From a64411deb43897e107c7ddb2678622115f321801 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 22 Apr 2024 13:08:22 +0200 Subject: [PATCH 16/16] man: document that IPAccounting= works for system services only Fixes: #20356 --- man/systemd.resource-control.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/man/systemd.resource-control.xml b/man/systemd.resource-control.xml index b6efb5b990..4a91358623 100644 --- a/man/systemd.resource-control.xml +++ b/man/systemd.resource-control.xml @@ -774,6 +774,9 @@ CPUWeight=20 DisableControllers=cpu / \ The system default for this setting may be controlled with DefaultIPAccounting= in systemd-system.conf5. + Note that this functionality is currently only available for system services, not for + per-user services. +