diff options
author | Lennart Poettering <lennart@poettering.net> | 2023-05-05 21:35:19 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2023-05-16 10:17:49 +0200 |
commit | a0cb33581630a54c89d088d36eb3bf6cf7459cd7 (patch) | |
tree | 1b79aa7d2e41dc911ec6783f9c1ad96246a22ffc /src/libsystemd | |
parent | test-bus-server: minor modernizations (diff) | |
download | systemd-a0cb33581630a54c89d088d36eb3bf6cf7459cd7.tar.xz systemd-a0cb33581630a54c89d088d36eb3bf6cf7459cd7.zip |
sd-bus: bind outgoing AF_UNIX sockets to abstract addresses conveying client comm + bus description string
Let's pass some additional meta information along bus connections
without actually altering the communication protocol.
Pass the client comm and client description string of the bus via
including it in the abstract namespace client socket address we connect
to. This is purely informational (and entirely user controlled), but has
the benefit that servers can make use of the information if they want,
but really don't have to. It works entirely transparently.
This takes inspiration from how we convey similar information via
credential socket connections.
Diffstat (limited to 'src/libsystemd')
-rw-r--r-- | src/libsystemd/sd-bus/bus-socket.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c index ceda20f289..11f4aa9669 100644 --- a/src/libsystemd/sd-bus/bus-socket.c +++ b/src/libsystemd/sd-bus/bus-socket.c @@ -22,6 +22,7 @@ #include "memory-util.h" #include "path-util.h" #include "process-util.h" +#include "random-util.h" #include "signal-util.h" #include "stdio-util.h" #include "string-util.h" @@ -889,6 +890,50 @@ fail: return r; } +static int bind_description(sd_bus *b, int fd, int family) { + _cleanup_free_ char *bind_name = NULL, *comm = NULL; + union sockaddr_union bsa; + const char *d = NULL; + int r; + + assert(b); + assert(fd >= 0); + + /* If this is an AF_UNIX socket, let's set our client's socket address to carry the description + * string for this bus connection. This is useful for debugging things, as the connection name is + * visible in various socket-related tools, and can even be queried by the server side. */ + + if (family != AF_UNIX) + return 0; + + (void) sd_bus_get_description(b, &d); + + /* Generate a recognizable source address in the abstract namespace. We'll include: + * - a random 64bit value (to avoid collisions) + * - our "comm" process name (suppressed if contains "/" to avoid parsing issues) + * - the description string of the bus connection. */ + (void) get_process_comm(0, &comm); + if (comm && strchr(comm, '/')) + comm = mfree(comm); + + if (!d && !comm) /* skip if we don't have either field, rely on kernel autobind instead */ + return 0; + + if (asprintf(&bind_name, "@%" PRIx64 "/bus/%s/%s", random_u64(), strempty(comm), strempty(d)) < 0) + return -ENOMEM; + + strshorten(bind_name, sizeof_field(struct sockaddr_un, sun_path)); + + r = sockaddr_un_set_path(&bsa.un, bind_name); + if (r < 0) + return r; + + if (bind(fd, &bsa.sa, r) < 0) + return -errno; + + return 0; +} + int bus_socket_connect(sd_bus *b) { bool inotify_done = false; int r; @@ -911,6 +956,10 @@ int bus_socket_connect(sd_bus *b) { if (b->input_fd < 0) return -errno; + r = bind_description(b, b->input_fd, b->sockaddr.sa.sa_family); + if (r < 0) + return r; + b->input_fd = fd_move_above_stdio(b->input_fd); b->output_fd = b->input_fd; |