break;
case KDBUS_ITEM_DST_NAME:
- if (!service_name_is_valid(d->str))
- return -EBADMSG;
+ if (!service_name_is_valid(d->str)) {
+ r = -EBADMSG;
+ goto fail;
+ }
destination = d->str;
break;
case KDBUS_ITEM_OWNED_NAME:
- if (!service_name_is_valid(d->name.name))
- return -EBADMSG;
-
- r = strv_extend(&m->creds.well_known_names, d->name.name);
- if (r < 0)
+ if (!service_name_is_valid(d->name.name)) {
+ r = -EBADMSG;
goto fail;
+ }
+
+ if (bus->creds_mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
+ r = strv_extend(&m->creds.well_known_names, d->name.name);
+ if (r < 0)
+ goto fail;
+
+ m->creds.mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
+ }
break;
case KDBUS_ITEM_CONN_DESCRIPTION:
}
static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
- struct kdbus_cmd_free cmd;
+ struct kdbus_cmd_free cmd = {};
struct kdbus_item *d;
assert(bus);
assert(k);
- cmd.flags = 0;
cmd.offset = (uint8_t *)k - (uint8_t *)bus->kdbus_buffer;
KDBUS_ITEM_FOREACH(d, k, items) {
if (errno == EAGAIN)
return 0;
+ if (errno == EOVERFLOW) {
+ log_debug("%s: kdbus reports %" PRIu64 " dropped broadcast messages, ignoring.", strna(bus->description), (uint64_t) recv.dropped_msgs);
+ return 0;
+ }
+
return -errno;
}
close_and_munmap(b->memfd_cache[i].fd, b->memfd_cache[i].address, b->memfd_cache[i].mapped);
}
-int kdbus_translate_request_name_flags(uint64_t flags, uint64_t *kdbus_flags) {
+uint64_t request_name_flags_to_kdbus(uint64_t flags) {
uint64_t f = 0;
- assert(kdbus_flags);
-
if (flags & SD_BUS_NAME_ALLOW_REPLACEMENT)
f |= KDBUS_NAME_ALLOW_REPLACEMENT;
if (flags & SD_BUS_NAME_QUEUE)
f |= KDBUS_NAME_QUEUE;
- *kdbus_flags = f;
- return 0;
+ return f;
}
-int kdbus_translate_attach_flags(uint64_t mask, uint64_t *kdbus_mask) {
+uint64_t attach_flags_to_kdbus(uint64_t mask) {
uint64_t m = 0;
- assert(kdbus_mask);
-
if (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID))
m |= KDBUS_ATTACH_CREDS;
if (mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS)
m |= KDBUS_ATTACH_AUXGROUPS;
- *kdbus_mask = m;
- return 0;
+ return m;
}
int bus_kernel_create_bus(const char *name, bool world, char **s) {
struct kdbus_cmd_make *make;
struct kdbus_item *n;
+ size_t l;
int fd;
assert(name);
if (fd < 0)
return -errno;
- make = alloca0_align(ALIGN8(offsetof(struct kdbus_cmd_make, items) +
- offsetof(struct kdbus_item, data64) + sizeof(uint64_t) +
- offsetof(struct kdbus_item, str) +
- DECIMAL_STR_MAX(uid_t) + 1 + strlen(name) + 1),
+ l = strlen(name);
+ make = alloca0_align(offsetof(struct kdbus_cmd_make, items) +
+ ALIGN8(offsetof(struct kdbus_item, bloom_parameter) + sizeof(struct kdbus_bloom_parameter)) +
+ ALIGN8(offsetof(struct kdbus_item, data64) + sizeof(uint64_t)) +
+ ALIGN8(offsetof(struct kdbus_item, str) + DECIMAL_STR_MAX(uid_t) + 1 + l + 1),
8);
make->size = offsetof(struct kdbus_cmd_make, items);
+ /* Set the bloom parameters */
n = make->items;
n->size = offsetof(struct kdbus_item, bloom_parameter) +
sizeof(struct kdbus_bloom_parameter);
n->type = KDBUS_ITEM_BLOOM_PARAMETER;
-
n->bloom_parameter.size = DEFAULT_BLOOM_SIZE;
n->bloom_parameter.n_hash = DEFAULT_BLOOM_N_HASH;
make->size += ALIGN8(n->size);
+ /* The busses we create make no restrictions on what metadata
+ * peers can read from incoming messages. */
+ n = KDBUS_ITEM_NEXT(n);
+ n->type = KDBUS_ITEM_ATTACH_FLAGS_RECV;
+ n->size = offsetof(struct kdbus_item, data64) + sizeof(uint64_t);
+ n->data64[0] = _KDBUS_ATTACH_ANY;
+ make->size += ALIGN8(n->size);
+
+ /* Set the a good name */
n = KDBUS_ITEM_NEXT(n);
sprintf(n->str, UID_FMT "-%s", getuid(), name);
n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
int fd;
size_t len;
+ assert(bus);
+
len = strlen("/sys/fs/kdbus/") + DECIMAL_STR_MAX(uid_t) + 1 + strlen(bus) + strlen("/bus") + 1;
if (path) {
- p = malloc(len);
+ p = new(char, len);
if (!p)
return -ENOMEM;
- *path = p;
} else
- p = alloca(len);
+ p = newa(char, len);
+
sprintf(p, "/sys/fs/kdbus/" UID_FMT "-%s/bus", getuid(), bus);
fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC);
- if (fd < 0)
+ if (fd < 0) {
+ if (path)
+ free(p);
+
return -errno;
+ }
+
+ if (path)
+ *path = p;
return fd;
}
if (world_policy >= 0)
policy_cnt++;
- size = ALIGN8(offsetof(struct kdbus_cmd_hello, items)) +
+ size = offsetof(struct kdbus_cmd_hello, items) +
ALIGN8(offsetof(struct kdbus_item, str) + strlen(name) + 1) +
policy_cnt * ALIGN8(offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access));
return 0;
}
+
+int bus_kernel_realize_attach_flags(sd_bus *bus) {
+ struct kdbus_cmd_update *update;
+ struct kdbus_item *n;
+
+ assert(bus);
+ assert(bus->is_kernel);
+
+ update = alloca0_align(offsetof(struct kdbus_cmd_update, items) +
+ ALIGN8(offsetof(struct kdbus_item, data64) + sizeof(uint64_t)),
+ 8);
+
+ n = update->items;
+ n->type = KDBUS_ITEM_ATTACH_FLAGS_RECV;
+ n->size = offsetof(struct kdbus_item, data64) + sizeof(uint64_t);
+ n->data64[0] = bus->attach_flags;
+
+ update->size =
+ offsetof(struct kdbus_cmd_update, items) +
+ ALIGN8(n->size);
+
+ if (ioctl(bus->input_fd, KDBUS_CMD_CONN_UPDATE, update) < 0)
+ return -errno;
+
+ return 0;
+}