case KDBUS_ITEM_PAYLOAD_OFF:
if (!h) {
- h = (struct bus_header *)((uint8_t *)bus->kdbus_buffer + d->vec.offset);
+ h = (struct bus_header *)((uint8_t *)k + d->vec.offset);
if (!bus_header_is_complete(h, d->vec.size))
return -EBADMSG;
if (r < 0)
return r;
+ /* The well-known names list is different from the other
+ credentials. If we asked for it, but nothing is there, this
+ means that the list of well-known names is simply empty, not
+ that we lack any data */
+
+ m->creds.mask |= (SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_WELL_KNOWN_NAMES) & bus->creds_mask;
+
KDBUS_ITEM_FOREACH(d, k, items) {
size_t l;
if (idx >= begin_body) {
if (!part->is_zero)
- part->data = (uint8_t *)bus->kdbus_buffer + d->vec.offset;
+ part->data = (uint8_t *)k + d->vec.offset;
part->size = d->vec.size;
} else {
if (!part->is_zero)
- part->data = (uint8_t *)bus->kdbus_buffer + d->vec.offset + (begin_body - idx);
+ part->data = (uint8_t *)k + d->vec.offset + (begin_body - idx);
part->size = d->vec.size - (begin_body - idx);
}
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 & bus->creds_mask;
break;
case KDBUS_ITEM_FDS:
/* Override information from the user header with data from the kernel */
if (k->src_id == KDBUS_SRC_ID_KERNEL)
- m->sender = "org.freedesktop.DBus";
+ m->sender = m->creds.unique_name = (char*) "org.freedesktop.DBus";
else {
snprintf(m->sender_buffer, sizeof(m->sender_buffer), ":1.%llu", (unsigned long long) k->src_id);
m->sender = m->creds.unique_name = m->sender_buffer;
- m->creds.mask |= SD_BUS_CREDS_UNIQUE_NAME & bus->creds_mask;
}
- if (!m->destination) {
- if (destination)
- m->destination = destination;
- else if (k->dst_id != KDBUS_DST_ID_NAME &&
- k->dst_id != KDBUS_DST_ID_BROADCAST) {
- snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id);
- m->destination = m->destination_buffer;
- }
+ if (destination)
+ m->destination = destination;
+ else if (k->dst_id == KDBUS_DST_ID_BROADCAST)
+ m->destination = NULL;
+ else if (k->dst_id == KDBUS_DST_ID_NAME)
+ m->destination = bus->unique_name; /* fill in unique name if the well-known name is missing */
+ else {
+ snprintf(m->destination_buffer, sizeof(m->destination_buffer), ":1.%llu", (unsigned long long) k->dst_id);
+ m->destination = m->destination_buffer;
}
/* We take possession of the kmsg struct now */
return r < 0 ? r : 1;
}
-int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *size) {
+int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *mapped, size_t *allocated) {
struct memfd_cache *c;
int fd;
assert(address);
- assert(size);
+ assert(mapped);
+ assert(allocated);
if (!bus || !bus->is_kernel)
return -ENOTSUP;
return -errno;
*address = NULL;
- *size = 0;
+ *mapped = 0;
+ *allocated = 0;
return fd;
}
c = &bus->memfd_cache[--bus->n_memfd_cache];
assert(c->fd >= 0);
- assert(c->size == 0 || c->address);
+ assert(c->mapped == 0 || c->address);
*address = c->address;
- *size = c->size;
+ *mapped = c->mapped;
+ *allocated = c->allocated;
fd = c->fd;
assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
close_nointr_nofail(fd);
}
-void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t size) {
+void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t mapped, size_t allocated) {
struct memfd_cache *c;
- uint64_t max_sz = PAGE_ALIGN(MEMFD_CACHE_ITEM_SIZE_MAX);
+ uint64_t max_mapped = PAGE_ALIGN(MEMFD_CACHE_ITEM_SIZE_MAX);
assert(fd >= 0);
- assert(size == 0 || address);
+ assert(mapped == 0 || address);
if (!bus || !bus->is_kernel) {
- close_and_munmap(fd, address, size);
+ close_and_munmap(fd, address, mapped);
return;
}
if (bus->n_memfd_cache >= ELEMENTSOF(bus->memfd_cache)) {
assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
- close_and_munmap(fd, address, size);
+ close_and_munmap(fd, address, mapped);
return;
}
c->address = address;
/* If overly long, let's return a bit to the OS */
- if (size > max_sz) {
- assert_se(ioctl(fd, KDBUS_CMD_MEMFD_SIZE_SET, &max_sz) >= 0);
- assert_se(munmap((uint8_t*) address + max_sz, PAGE_ALIGN(size - max_sz)) >= 0);
- c->size = max_sz;
- } else
- c->size = size;
+ if (mapped > max_mapped) {
+ assert_se(ioctl(fd, KDBUS_CMD_MEMFD_SIZE_SET, &max_mapped) >= 0);
+ assert_se(munmap((uint8_t*) address + max_mapped, PAGE_ALIGN(mapped - max_mapped)) >= 0);
+ c->mapped = c->allocated = max_mapped;
+ } else {
+ c->mapped = mapped;
+ c->allocated = allocated;
+ }
assert_se(pthread_mutex_unlock(&bus->memfd_cache_mutex) >= 0);
}
assert(b);
for (i = 0; i < b->n_memfd_cache; i++)
- close_and_munmap(b->memfd_cache[i].fd, b->memfd_cache[i].address, b->memfd_cache[i].size);
+ 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) {
return fd;
}
+
+int bus_kernel_try_close(sd_bus *bus) {
+ assert(bus);
+ assert(bus->is_kernel);
+
+ if (ioctl(bus->input_fd, KDBUS_CMD_BYEBYE) < 0)
+ return -errno;
+
+ return 0;
+}