chiark / gitweb /
bus: when allocating a memfd for usage in a bus connection, name the memfd after...
[elogind.git] / src / libsystemd / sd-bus / bus-kernel.c
index 99ac5b1ed3164687474147b574e0525ac9cd6fb8..833ea5574ddbde16fc180ace3973815287e3ec95 100644 (file)
@@ -26,6 +26,7 @@
 #include <fcntl.h>
 #include <malloc.h>
 #include <sys/mman.h>
+#include <sys/prctl.h>
 
 #include "util.h"
 #include "strv.h"
@@ -501,6 +502,7 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
                 case KDBUS_ITEM_TIMESTAMP:
                         m->realtime = d->timestamp.realtime_ns / NSEC_PER_USEC;
                         m->monotonic = d->timestamp.monotonic_ns / NSEC_PER_USEC;
+                        m->seqnum = d->timestamp.seqnum;
                         break;
 
                 case KDBUS_ITEM_PID_COMM:
@@ -627,7 +629,9 @@ fail:
 int bus_kernel_take_fd(sd_bus *b) {
         struct kdbus_cmd_hello *hello;
         struct kdbus_item *item;
-        size_t l = 0, sz;
+        _cleanup_free_ char *g = NULL;
+        const char *name;
+        size_t l = 0, m = 0, sz;
         int r;
 
         assert(b);
@@ -637,10 +641,52 @@ int bus_kernel_take_fd(sd_bus *b) {
 
         b->use_memfd = 1;
 
-        sz = ALIGN8(offsetof(struct kdbus_cmd_hello, items));
+        if (b->connection_name) {
+                g = sd_bus_label_escape(b->connection_name);
+                if (!g)
+                        return -ENOMEM;
+
+                name = g;
+        } else {
+                char pr[17] = {};
+
+                /* If no name is explicitly set, we'll include a hint
+                 * indicating the library implementation, a hint which
+                 * kind of bus this is and the thread name */
+
+                assert_se(prctl(PR_GET_NAME, (unsigned long) pr) >= 0);
+
+                if (isempty(pr)) {
+                        name = b->is_system ? "sd-system" :
+                                b->is_user ? "sd-user" : "sd";
+                } else {
+                        _cleanup_free_ char *e = NULL;
+
+                        e = sd_bus_label_escape(pr);
+                        if (!e)
+                                return -ENOMEM;
+
+                        g = strappend(b->is_system ? "sd-system-" :
+                                      b->is_user ? "sd-user-" : "sd-",
+                                      e);
+                        if (!g)
+                                return -ENOMEM;
+
+                        name = g;
+                }
+
+                b->connection_name = sd_bus_label_unescape(name);
+                if (!b->connection_name)
+                        return -ENOMEM;
+        }
+
+        m = strlen(name);
+
+        sz = ALIGN8(offsetof(struct kdbus_cmd_hello, items)) +
+                ALIGN8(offsetof(struct kdbus_item, str) + m + 1);
 
         if (b->fake_creds_valid)
-                sz += ALIGN8(offsetof(struct kdbus_item, creds)) + sizeof(struct kdbus_creds);
+                sz += ALIGN8(offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds));
 
         if (b->fake_label) {
                 l = strlen(b->fake_label);
@@ -655,6 +701,11 @@ int bus_kernel_take_fd(sd_bus *b) {
 
         item = hello->items;
 
+        item->size = offsetof(struct kdbus_item, str) + m + 1;
+        item->type = KDBUS_ITEM_CONN_NAME;
+        memcpy(item->str, name, m + 1);
+        item = KDBUS_ITEM_NEXT(item);
+
         if (b->fake_creds_valid) {
                 item->size = offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds);
                 item->type = KDBUS_ITEM_CREDS;
@@ -665,6 +716,7 @@ int bus_kernel_take_fd(sd_bus *b) {
 
         if (b->fake_label) {
                 item->size = offsetof(struct kdbus_item, str) + l + 1;
+                item->type = KDBUS_ITEM_SECLABEL;
                 memcpy(item->str, b->fake_label, l+1);
         }
 
@@ -1033,21 +1085,40 @@ int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *mapped, size_t *al
         assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0);
 
         if (bus->n_memfd_cache <= 0) {
-                struct kdbus_cmd_memfd_make cmd = {
-                        .size = sizeof(struct kdbus_cmd_memfd_make),
-                };
+                _cleanup_free_ char *g = NULL;
+                struct kdbus_cmd_memfd_make *cmd;
+                struct kdbus_item *item;
+                size_t l, sz;
                 int r;
 
                 assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
 
-                r = ioctl(bus->input_fd, KDBUS_CMD_MEMFD_NEW, &cmd);
+                assert(bus->connection_name);
+
+                g = sd_bus_label_escape(bus->connection_name);
+                if (!g)
+                        return -ENOMEM;
+
+                l = strlen(g);
+                sz = ALIGN8(offsetof(struct kdbus_cmd_memfd_make, items)) +
+                        ALIGN8(offsetof(struct kdbus_item, str)) +
+                        l + 1;
+                cmd = alloca0(sz);
+                cmd->size = sz;
+
+                item = cmd->items;
+                item->size = ALIGN8(offsetof(struct kdbus_item, str)) + l + 1;
+                item->type = KDBUS_ITEM_MEMFD_NAME;
+                memcpy(item->str, g, l + 1);
+
+                r = ioctl(bus->input_fd, KDBUS_CMD_MEMFD_NEW, cmd);
                 if (r < 0)
                         return -errno;
 
                 *address = NULL;
                 *mapped = 0;
                 *allocated = 0;
-                return cmd.fd;
+                return cmd->fd;
         }
 
         c = &bus->memfd_cache[--bus->n_memfd_cache];