break;
}
- case KDBUS_ITEM_CREDS:
- /* UID/GID/PID are always valid */
- m->creds.uid = (uid_t) d->creds.uid;
- m->creds.gid = (gid_t) d->creds.gid;
- m->creds.pid = (pid_t) d->creds.pid;
- m->creds.mask |= (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID) & bus->creds_mask;
-
- /* The PID starttime/TID might be missing
- * however, when the data is faked by some
- * data bus proxy and it lacks that
- * information about the real client since
- * SO_PEERCRED is used for that */
-
- if (d->creds.starttime > 0) {
- m->creds.pid_starttime = d->creds.starttime / NSEC_PER_USEC;
+ case KDBUS_ITEM_PIDS:
+
+ /* The PID starttime/TID might be missing,
+ * when the data is faked by some data bus
+ * proxy and it lacks that information about
+ * the real client since SO_PEERCRED is used
+ * for that. */
+
+ if (d->pids.pid > 0) {
+ m->creds.pid = (pid_t) d->pids.pid;
+ m->creds.mask |= SD_BUS_CREDS_PID & bus->creds_mask;
+ }
+
+ if (d->pids.starttime > 0) {
+ m->creds.pid_starttime = d->pids.starttime / NSEC_PER_USEC;
m->creds.mask |= SD_BUS_CREDS_PID_STARTTIME & bus->creds_mask;
}
- if (d->creds.tid > 0) {
- m->creds.tid = (pid_t) d->creds.tid;
+ if (d->pids.tid > 0) {
+ m->creds.tid = (pid_t) d->pids.tid;
m->creds.mask |= SD_BUS_CREDS_TID & bus->creds_mask;
}
+
+ break;
+
+ case KDBUS_ITEM_CREDS:
+
+ /* EUID/SUID/FSUID/EGID/SGID/FSGID might be missing too (see above). */
+
+ if ((uid_t) d->creds.uid != (uid_t) -1) {
+ m->creds.uid = (uid_t) d->creds.uid;
+ m->creds.mask |= SD_BUS_CREDS_UID & bus->creds_mask;
+ }
+
+ if ((uid_t) d->creds.euid != (uid_t) -1) {
+ m->creds.euid = (uid_t) d->creds.euid;
+ m->creds.mask |= SD_BUS_CREDS_EUID & bus->creds_mask;
+ }
+
+ if ((uid_t) d->creds.suid != (uid_t) -1) {
+ m->creds.suid = (uid_t) d->creds.suid;
+ m->creds.mask |= SD_BUS_CREDS_SUID & bus->creds_mask;
+ }
+
+ if ((uid_t) d->creds.fsuid != (uid_t) -1) {
+ m->creds.fsuid = (uid_t) d->creds.fsuid;
+ m->creds.mask |= SD_BUS_CREDS_FSUID & bus->creds_mask;
+ }
+
+ if ((gid_t) d->creds.gid != (gid_t) -1) {
+ m->creds.gid = (gid_t) d->creds.gid;
+ m->creds.mask |= SD_BUS_CREDS_GID & bus->creds_mask;
+ }
+
+ if ((gid_t) d->creds.egid != (gid_t) -1) {
+ m->creds.egid = (gid_t) d->creds.egid;
+ m->creds.mask |= SD_BUS_CREDS_EGID & bus->creds_mask;
+ }
+
+ if ((gid_t) d->creds.sgid != (gid_t) -1) {
+ m->creds.sgid = (gid_t) d->creds.sgid;
+ m->creds.mask |= SD_BUS_CREDS_SGID & bus->creds_mask;
+ }
+
+ if ((gid_t) d->creds.fsgid != (gid_t) -1) {
+ m->creds.fsgid = (gid_t) d->creds.fsgid;
+ m->creds.mask |= SD_BUS_CREDS_FSGID & bus->creds_mask;
+ }
+
break;
case KDBUS_ITEM_TIMESTAMP:
break;
case KDBUS_ITEM_AUDIT:
- m->creds.audit_session_id = (uint32_t) d->audit.sessionid;
- m->creds.audit_login_uid = (uid_t) d->audit.loginuid;
- m->creds.mask |= (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID) & bus->creds_mask;
+ 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;
+ }
+
+ if ((uid_t) d->audit.loginuid != (uid_t) -1) {
+ 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:
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:
m->creds.mask |= SD_BUS_CREDS_DESCRIPTION & bus->creds_mask;
break;
+ case KDBUS_ITEM_AUXGROUPS:
+
+ if (bus->creds_mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
+ size_t i, n;
+ uid_t *u;
+ n = (d->size - offsetof(struct kdbus_item, data64)) / sizeof(uint64_t);
+ u = new(uid_t, n);
+ if (!u) {
+ r = -ENOMEM;
+ goto fail;
+ }
+
+ for (i = 0; i < n; i++)
+ u[i] = (uid_t) d->data64[i];
+
+ m->creds.supplementary_gids = u;
+ m->creds.n_supplementary_gids = n;
+
+ m->creds.mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
+ }
+
+ break;
+
case KDBUS_ITEM_FDS:
case KDBUS_ITEM_SECLABEL:
break;
if (b->fake_creds_valid)
sz += ALIGN8(offsetof(struct kdbus_item, creds) + sizeof(struct kdbus_creds));
+ if (b->fake_pids_valid)
+ sz += ALIGN8(offsetof(struct kdbus_item, pids) + sizeof(struct kdbus_pids));
+
if (b->fake_label) {
l = strlen(b->fake_label);
sz += ALIGN8(offsetof(struct kdbus_item, str) + l + 1);
item = KDBUS_ITEM_NEXT(item);
}
+ if (b->fake_pids_valid) {
+ item->size = offsetof(struct kdbus_item, pids) + sizeof(struct kdbus_pids);
+ item->type = KDBUS_ITEM_PIDS;
+ item->pids = b->fake_pids;
+
+ item = KDBUS_ITEM_NEXT(item);
+ }
+
if (b->fake_label) {
item->size = offsetof(struct kdbus_item, str) + l + 1;
item->type = KDBUS_ITEM_SECLABEL;
}
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;
}
assert(kdbus_mask);
- if (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID))
+ 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_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID))
+ m |= KDBUS_ATTACH_PIDS;
+
if (mask & SD_BUS_CREDS_COMM)
m |= KDBUS_ATTACH_PID_COMM;
if (mask & SD_BUS_CREDS_DESCRIPTION)
m |= KDBUS_ATTACH_CONN_DESCRIPTION;
+ if (mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS)
+ m |= KDBUS_ATTACH_AUXGROUPS;
+
*kdbus_mask = m;
return 0;
}
assert(name);
assert(s);
- fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
+ fd = open("/sys/fs/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
if (fd < 0)
return -errno;
if (s) {
char *p;
- p = strjoin("/dev/kdbus/", n->str, "/bus", NULL);
+ p = strjoin("/sys/fs/kdbus/", n->str, "/bus", NULL);
if (!p) {
safe_close(fd);
return -ENOMEM;
int fd;
size_t len;
- len = strlen("/dev/kdbus/") + DECIMAL_STR_MAX(uid_t) + 1 + strlen(bus) + strlen("/bus") + 1;
+ len = strlen("/sys/fs/kdbus/") + DECIMAL_STR_MAX(uid_t) + 1 + strlen(bus) + strlen("/bus") + 1;
if (path) {
p = malloc(len);
*path = p;
} else
p = alloca(len);
- sprintf(p, "/dev/kdbus/" UID_FMT "-%s/bus", getuid(), bus);
+ sprintf(p, "/sys/fs/kdbus/" UID_FMT "-%s/bus", getuid(), bus);
fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC);
if (fd < 0)
return fd;
}
-int bus_kernel_create_domain(const char *name, char **s) {
- struct kdbus_cmd_make *make;
- struct kdbus_item *n;
- int fd;
-
- assert(name);
- assert(s);
-
- fd = open("/dev/kdbus/control", O_RDWR|O_NOCTTY|O_CLOEXEC);
- if (fd < 0)
- return -errno;
-
- make = alloca0_align(ALIGN8(offsetof(struct kdbus_cmd_make, items) +
- offsetof(struct kdbus_item, str) +
- strlen(name) + 1),
- 8);
-
- n = make->items;
- strcpy(n->str, name);
- n->size = offsetof(struct kdbus_item, str) + strlen(n->str) + 1;
- n->type = KDBUS_ITEM_MAKE_NAME;
-
- make->size = ALIGN8(offsetof(struct kdbus_cmd_make, items) + n->size);
- make->flags = KDBUS_MAKE_ACCESS_WORLD;
-
- if (ioctl(fd, KDBUS_CMD_DOMAIN_MAKE, make) < 0) {
- safe_close(fd);
- return -errno;
- }
-
- /* The higher 32bit of the flags field are considered
- * 'incompatible flags'. Refuse them all for now. */
- if (make->flags > 0xFFFFFFFFULL) {
- safe_close(fd);
- return -ENOTSUP;
- }
-
- if (s) {
- char *p;
-
- p = strappend("/dev/kdbus/domain/", name);
- if (!p) {
- safe_close(fd);
- return -ENOMEM;
- }
-
- *s = p;
- }
-
- return fd;
-}
-
int bus_kernel_try_close(sd_bus *bus) {
assert(bus);
assert(bus->is_kernel);