diff options
Diffstat (limited to 'src/libsystemd/sd-bus/bus-kernel.c')
-rw-r--r-- | src/libsystemd/sd-bus/bus-kernel.c | 102 |
1 files changed, 50 insertions, 52 deletions
diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c index e90ee449d9..417e4d5903 100644 --- a/src/libsystemd/sd-bus/bus-kernel.c +++ b/src/libsystemd/sd-bus/bus-kernel.c @@ -38,8 +38,8 @@ #include "strv.h" #include "memfd-util.h" #include "capability.h" -#include "cgroup-util.h" #include "fileio.h" +#include "formats-util.h" #include "bus-internal.h" #include "bus-message.h" @@ -595,6 +595,14 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) { m->creds.mask |= SD_BUS_CREDS_TID & bus->creds_mask; } + if (d->pids.ppid > 0) { + m->creds.ppid = (pid_t) d->pids.ppid; + m->creds.mask |= SD_BUS_CREDS_PPID & bus->creds_mask; + } else if (d->pids.pid == 1) { + m->creds.ppid = 0; + m->creds.mask |= SD_BUS_CREDS_PPID & bus->creds_mask; + } + break; case KDBUS_ITEM_CREDS: @@ -681,15 +689,11 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) { break; case KDBUS_ITEM_AUDIT: - if ((uint32_t) d->audit.sessionid != (uint32_t) -1) { - m->creds.audit_session_id = (uint32_t) d->audit.sessionid; - m->creds.mask |= SD_BUS_CREDS_AUDIT_SESSION_ID & bus->creds_mask; - } + m->creds.audit_session_id = (uint32_t) d->audit.sessionid; + m->creds.mask |= SD_BUS_CREDS_AUDIT_SESSION_ID & bus->creds_mask; - if ((uid_t) d->audit.loginuid != UID_INVALID) { - m->creds.audit_login_uid = (uid_t) d->audit.loginuid; - m->creds.mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID & bus->creds_mask; - } + m->creds.audit_login_uid = (uid_t) d->audit.loginuid; + m->creds.mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID & bus->creds_mask; break; case KDBUS_ITEM_CAPS: @@ -749,10 +753,21 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) { case KDBUS_ITEM_AUXGROUPS: if (bus->creds_mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) { - assert_cc(sizeof(gid_t) == sizeof(uint32_t)); + size_t i, n; + gid_t *g; + + n = (d->size - offsetof(struct kdbus_item, data64)) / sizeof(uint64_t); + g = new(gid_t, n); + if (!g) { + r = -ENOMEM; + goto fail; + } - m->creds.n_supplementary_gids = (d->size - offsetof(struct kdbus_item, data32)) / sizeof(uint32_t); - m->creds.supplementary_gids = (gid_t*) d->data32; + for (i = 0; i < n; i++) + g[i] = d->data64[i]; + + m->creds.supplementary_gids = g; + m->creds.n_supplementary_gids = n; m->creds.mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS; } @@ -841,9 +856,8 @@ fail: int bus_kernel_take_fd(sd_bus *b) { struct kdbus_bloom_parameter *bloom = NULL; + struct kdbus_item *items, *item; struct kdbus_cmd_hello *hello; - struct kdbus_item_list *items; - struct kdbus_item *item; _cleanup_free_ char *g = NULL; const char *name; size_t l = 0, m = 0, sz; @@ -948,8 +962,16 @@ int bus_kernel_take_fd(sd_bus *b) { } r = ioctl(b->input_fd, KDBUS_CMD_HELLO, hello); - if (r < 0) + if (r < 0) { + if (errno == ENOTTY) + /* If the ioctl is not supported we assume that the + * API version changed in a major incompatible way, + * let's indicate an API incompatibility in this + * case. */ + return -ESOCKTNOSUPPORT; + return -errno; + } if (!b->kdbus_buffer) { b->kdbus_buffer = mmap(NULL, KDBUS_POOL_SIZE, PROT_READ, MAP_SHARED, b->input_fd, 0); @@ -963,13 +985,13 @@ int bus_kernel_take_fd(sd_bus *b) { /* The higher 32bit of the bus_flags fields are considered * 'incompatible flags'. Refuse them all for now. */ if (hello->bus_flags > 0xFFFFFFFFULL) { - r = -ENOTSUP; + r = -ESOCKTNOSUPPORT; goto fail; } /* extract bloom parameters from items */ items = (void*)((uint8_t*)b->kdbus_buffer + hello->offset); - KDBUS_ITEM_FOREACH(item, items, items) { + KDBUS_FOREACH(item, items, hello->items_size) { switch (item->type) { case KDBUS_ITEM_BLOOM_PARAMETER: bloom = &item->bloom_parameter; @@ -978,7 +1000,7 @@ int bus_kernel_take_fd(sd_bus *b) { } if (!bloom || !bloom_validate_parameters((size_t) bloom->size, (unsigned) bloom->n_hash)) { - r = -ENOTSUP; + r = -EOPNOTSUPP; goto fail; } @@ -1345,15 +1367,12 @@ int bus_kernel_read_message(sd_bus *bus, bool hint_priority, int64_t priority) { } r = ioctl(bus->input_fd, KDBUS_CMD_RECV, &recv); + if (recv.return_flags & KDBUS_RECV_RETURN_DROPPED_MSGS) + log_debug("%s: kdbus reports %" PRIu64 " dropped broadcast messages, ignoring.", strna(bus->description), (uint64_t) recv.dropped_msgs); if (r < 0) { 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; } @@ -1389,7 +1408,7 @@ int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *mapped, size_t *al assert(allocated); if (!bus || !bus->is_kernel) - return -ENOTSUP; + return -EOPNOTSUPP; assert_se(pthread_mutex_lock(&bus->memfd_cache_mutex) >= 0); @@ -1499,7 +1518,7 @@ uint64_t attach_flags_to_kdbus(uint64_t mask) { 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_PID|SD_BUS_CREDS_TID)) + if (mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_TID|SD_BUS_CREDS_PPID)) m |= KDBUS_ATTACH_PIDS; if (mask & SD_BUS_CREDS_COMM) @@ -1574,7 +1593,7 @@ int bus_kernel_create_bus(const char *name, bool world, char **s) { make->size += ALIGN8(n->size); - /* The busses we create make no restrictions on what metadata + /* The buses 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; @@ -1600,6 +1619,11 @@ int bus_kernel_create_bus(const char *name, bool world, char **s) { if (ioctl(fd, KDBUS_CMD_BUS_MAKE, make) < 0) { safe_close(fd); + + /* Major API change? then the ioctls got shuffled around. */ + if (errno == ENOTTY) + return -ESOCKTNOSUPPORT; + return -errno; } @@ -1746,32 +1770,6 @@ int bus_kernel_realize_attach_flags(sd_bus *bus) { return 0; } -int bus_kernel_fix_attach_mask(void) { - _cleanup_free_ char *mask = NULL; - uint64_t m = (uint64_t) -1; - char buf[2+16+2]; - int r; - - /* By default we don't want any kdbus metadata fields to be - * suppressed, hence we reset the kernel mask for it to - * (uint64_t) -1. If the module argument was overwritten by - * the kernel cmdline, we leave it as is. */ - - r = get_proc_cmdline_key("kdbus.attach_flags_mask=", &mask); - if (r < 0) - return log_warning_errno(r, "Failed to read kernel command line: %m"); - - if (r == 0) { - sprintf(buf, "0x%" PRIx64 "\n", m); - r = write_string_file("/sys/module/kdbus/parameters/attach_flags_mask", buf); - if (r < 0) - return log_full_errno(IN_SET(r, -ENOENT, -EROFS) ? LOG_DEBUG : LOG_WARNING, r, - "Failed to write kdbus attach mask: %m"); - } - - return 0; -} - int bus_kernel_get_bus_name(sd_bus *bus, char **name) { struct kdbus_cmd_info cmd = { .size = sizeof(struct kdbus_cmd_info), |