From: Lennart Poettering Date: Mon, 15 Sep 2025 16:17:59 +0000 (+0200) Subject: sd-varlink: optionally handle SIGTERM/SIGINT explicitly in simple varlink event loop X-Git-Tag: v259-rc1~511^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cba8c099a93050274be57d78c0093a19d1cbcc1e;p=thirdparty%2Fsystemd.git sd-varlink: optionally handle SIGTERM/SIGINT explicitly in simple varlink event loop --- diff --git a/man/rules/meson.build b/man/rules/meson.build index 50432f0b8d8..299aa5d66f8 100644 --- a/man/rules/meson.build +++ b/man/rules/meson.build @@ -916,6 +916,7 @@ manpages = [ 'HAVE_PAM'], ['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', [], ''], ['sd_varlink_set_description', '3', ['sd_varlink_get_description'], ''], ['sd_varlink_set_relative_timeout', '3', [], ''], ['sd_watchdog_enabled', '3', [], ''], diff --git a/man/sd_varlink_server_new.xml b/man/sd_varlink_server_new.xml new file mode 100644 index 00000000000..7d799c27d1c --- /dev/null +++ b/man/sd_varlink_server_new.xml @@ -0,0 +1,145 @@ + + + + + + + + sd_varlink_server_new + systemd + + + + sd_varlink_server_new + 3 + + + + sd_varlink_server_new + + Allocate Varlink server object + + + + + #include <systemd/sd-varlink.h> + + + int sd_varlink_server_new + sd_varlink_server** ret + sd_varlink_server_flags_t flags + + + + + + + Description + + sd_varlink_server_new() allocates a new Varlink server object. Initially the + server does not listen on any socket or file descriptor. The newly allocated server object is returned in + the ret parameter. Use sd_varlink_server_unref() to release + the server object again after use. + + The following flags may be passed in the flags parameter: + + + SD_VARLINK_SERVER_ROOT_ONLY: only allow connections from UID 0 + (i.e. the root user). This has two effects: any incoming connections is authenticated via + SO_PEERCRED ensuring the UID reported by the kernel is zero. If this check fails + the connection is immediately terminated. Moreover, when binding a socket inode in the file system, the + access mode is set to 0600 (rather than 0666). If this option is used connections on + non-AF_UNIX sockets or via pipes are never permitted. + + SD_VARLINK_SERVER_MYSELF_ONLY: this is very similar to + SD_VARLINK_SERVER_ROOT_ONLY but enforces that the connecting client's UID must + match the server's UID (i.e. the UID this function is invoked as). For servers that run as UID 0 the + flags are equivalent. If both flags are specified in combination, connections are allowed by both UID 0 + and the server's own UID. + + SD_VARLINK_SERVER_ACCOUNT_UID: if set connection accounting per + client UID is enabled, and a limit on concurrent connections from the same UID is enforced. The limit can + be set via sd_varlink_server_set_connections_per_uid_max(), and defaults to 3/4th + of the total concurrent connection limit, as settable via + sd_varlink_server_set_connections_max(). + + SD_VARLINK_SERVER_INHERIT_USERDATA: if set the user data field for + incoming connection (i.e. sd_varlink) objects (as settable via + sd_varlink_set_userdata()) is automatically set to the userdata field of the + server (i.e. sd_varlink_server) object (as settable via + sd_varlink_server_set_userdata()). If this flag is not specified the connection's + user data field will default to NULL. + + SD_VARLINK_SERVER_INPUT_SENSITIVE: mark all incoming method call + parameters as security sensitive (equivalent to calling + sd_json_variant_sensitive()). This is useful for services that deal with secrets + and similar, as it ensures that the parameters are kept out of debug logging, and memory used by the + parameters is erased after use. + + SD_VARLINK_SERVER_ALLOW_FD_PASSING_INPUT: if set, allow receiving + UNIX file descriptors via the connections, equivalent to calling + sd_varlink_set_allow_fd_passing_input() immediately for each incoming + connection. Note that this only has an effect if AF_UNIX sockets are used for + communication. + + SD_VARLINK_SERVER_ALLOW_FD_PASSING_OUTPUT: similar, but controls + sending of UNIX file descriptors. + + SD_VARLINK_SERVER_FD_PASSING_INPUT_STRICT: this flag can be used + in conjunction with SD_VARLINK_SERVER_ALLOW_FD_PASSING_INPUT. If so, file + descriptor passing is turned off on the listening sockets already, ensuring that the connection sockets + derived from it at no time have file descriptor passing enabled. If + SD_VARLINK_SERVER_ALLOW_FD_PASSING_INPUT is used without + SD_VARLINK_SERVER_FD_PASSING_INPUT_STRICT then a choice when to prohibit or allow + file descriptor passing can still be made after the connection came in, however permitting a time + window where file descriptors might already be enqueued, that then need to be dropped + again. + + SD_VARLINK_SERVER_HANDLE_SIGINT: if set, and + sd_varlink_server_loop_auto() is used, incoming SIGINT + process signals will be caught gracefully and cause the event loop to exit cleanly. + + SD_VARLINK_SERVER_HANDLE_SIGTERM: similar, but does the same for + SIGTERM. + + + + + Return Value + + On success, sd_varlink_server_new() returns a non-negative integer. On + failure, it returns a negative errno-style error code. + + + Errors + + Returned errors may indicate the following problems: + + + + -EINVAL + + An argument is invalid. + + + + + + + + + History + sd_varlink_server_new() was added in version 257. + + + + See Also + + + systemd1 + sd-varlink3 + + + + diff --git a/src/libsystemd/sd-varlink/sd-varlink.c b/src/libsystemd/sd-varlink/sd-varlink.c index ee2272f9433..e0d5bf20aaa 100644 --- a/src/libsystemd/sd-varlink/sd-varlink.c +++ b/src/libsystemd/sd-varlink/sd-varlink.c @@ -3309,7 +3309,9 @@ _public_ int sd_varlink_server_new(sd_varlink_server **ret, sd_varlink_server_fl SD_VARLINK_SERVER_INPUT_SENSITIVE| SD_VARLINK_SERVER_ALLOW_FD_PASSING_INPUT| SD_VARLINK_SERVER_ALLOW_FD_PASSING_OUTPUT| - SD_VARLINK_SERVER_FD_PASSING_INPUT_STRICT)) == 0, -EINVAL); + SD_VARLINK_SERVER_FD_PASSING_INPUT_STRICT| + SD_VARLINK_SERVER_HANDLE_SIGINT| + SD_VARLINK_SERVER_HANDLE_SIGTERM)) == 0, -EINVAL); s = new(sd_varlink_server, 1); if (!s) @@ -3882,6 +3884,18 @@ _public_ int sd_varlink_server_loop_auto(sd_varlink_server *server) { if (r < 0) return r; + if (FLAGS_SET(server->flags, SD_VARLINK_SERVER_HANDLE_SIGINT)) { + r = sd_event_add_signal(event, /* ret= */ NULL, SIGINT|SD_EVENT_SIGNAL_PROCMASK, /* callback= */ NULL, /* userdata= */ NULL); + if (r < 0) + return r; + } + + if (FLAGS_SET(server->flags, SD_VARLINK_SERVER_HANDLE_SIGTERM)) { + r = sd_event_add_signal(event, /* ret= */ NULL, SIGTERM|SD_EVENT_SIGNAL_PROCMASK, /* callback= */ NULL, /* userdata= */ NULL); + if (r < 0) + return r; + } + r = sd_varlink_server_attach_event(server, event, 0); if (r < 0) return r; diff --git a/src/systemd/sd-varlink.h b/src/systemd/sd-varlink.h index 9d3dc48a444..27ad5bf7f8d 100644 --- a/src/systemd/sd-varlink.h +++ b/src/systemd/sd-varlink.h @@ -69,6 +69,8 @@ __extension__ typedef enum _SD_ENUM_TYPE_S64(sd_varlink_server_flags_t) { SD_VARLINK_SERVER_ALLOW_FD_PASSING_INPUT = 1 << 5, /* Allow receiving fds over all connections */ SD_VARLINK_SERVER_ALLOW_FD_PASSING_OUTPUT = 1 << 6, /* Allow sending fds over all connections */ SD_VARLINK_SERVER_FD_PASSING_INPUT_STRICT = 1 << 7, /* Reject input messages with fds if fd passing is disabled (needs kernel v6.16+) */ + SD_VARLINK_SERVER_HANDLE_SIGINT = 1 << 8, /* Exit cleanly on SIGINT */ + SD_VARLINK_SERVER_HANDLE_SIGTERM = 1 << 9, /* Exit cleanly on SIGTERM */ _SD_ENUM_FORCE_S64(SD_VARLINK_SERVER) } sd_varlink_server_flags_t;