summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2023-05-05 21:35:19 +0200
committerLennart Poettering <lennart@poettering.net>2023-05-16 10:17:49 +0200
commita0cb33581630a54c89d088d36eb3bf6cf7459cd7 (patch)
tree1b79aa7d2e41dc911ec6783f9c1ad96246a22ffc /src
parentf7794e423ae79325bdbf7b3637b7cb7a1a57e62e (diff)
downloadsystemd-a0cb33581630a54c89d088d36eb3bf6cf7459cd7.tar.gz
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')
-rw-r--r--src/libsystemd/sd-bus/bus-socket.c49
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;