__u64 starttime;
};
+/**
+ * struct kdbus_caps - process capabilities
+ * @last_cap: Highest currently known capability bit
+ * @caps: Variable number of 32-bit capabilities flags
+ *
+ * Contains a variable number of 32-bit capabilities flags.
+ *
+ * Attached to:
+ * KDBUS_ITEM_CAPS
+ */
+struct kdbus_caps {
+ __u32 last_cap;
+ __u32 caps[0];
+};
+
/**
* struct kdbus_audit - audit information
* @sessionid: The audit session ID
struct kdbus_vec vec;
struct kdbus_creds creds;
struct kdbus_audit audit;
+ struct kdbus_caps caps;
struct kdbus_timestamp timestamp;
struct kdbus_name name;
struct kdbus_bloom_parameter bloom_parameter;
Attaches an item of type KDBUS_ITEM_CGROUP with the task's cgroup path.
KDBUS_ATTACH_CAPS
- Attaches an item of type KDBUS_ITEM_CAPS, carrying 4 sets of capabilities:
- inheritable, permitted, effective and bset. Those should be accessed via
- kdbus_item.data32.
+ Attaches an item of type KDBUS_ITEM_CAPS, carrying sets of capabilities
+ that should be accessed via kdbus_item.caps.caps. Also, userspace should
+ be written in a way that it takes kdbus_item.caps.last_cap into account,
+ and derive the number of sets and rows from the item size and the reported
+ number of valid capability bits.
KDBUS_ATTACH_SECLABEL
Attaches an item of type KDBUS_ITEM_SECLABEL, which contains the SELinux
static int kdbus_meta_append_caps(struct kdbus_meta *meta)
{
struct caps {
- u32 cap[_KERNEL_CAPABILITY_U32S];
- } cap[4];
+ u32 last_cap;
+ struct {
+ u32 caps[_KERNEL_CAPABILITY_U32S];
+ } set[4];
+ } caps;
unsigned int i;
const struct cred *cred = current_cred();
+ caps.last_cap = CAP_LAST_CAP;
+
for (i = 0; i < _KERNEL_CAPABILITY_U32S; i++) {
- cap[0].cap[i] = cred->cap_inheritable.cap[i];
- cap[1].cap[i] = cred->cap_permitted.cap[i];
- cap[2].cap[i] = cred->cap_effective.cap[i];
- cap[3].cap[i] = cred->cap_bset.cap[i];
+ caps.set[0].caps[i] = cred->cap_inheritable.cap[i];
+ caps.set[1].caps[i] = cred->cap_permitted.cap[i];
+ caps.set[2].caps[i] = cred->cap_effective.cap[i];
+ caps.set[3].caps[i] = cred->cap_bset.cap[i];
}
/* clear unused bits */
for (i = 0; i < 4; i++)
- cap[i].cap[CAP_TO_INDEX(CAP_LAST_CAP)] &=
+ caps.set[i].caps[CAP_TO_INDEX(CAP_LAST_CAP)] &=
CAP_TO_MASK(CAP_LAST_CAP + 1) - 1;
return kdbus_meta_append_data(meta, KDBUS_ITEM_CAPS,
- cap, sizeof(cap));
+ &caps, sizeof(caps));
}
#ifdef CONFIG_CGROUPS
break;
case KDBUS_ITEM_CAPS: {
- int n;
const uint32_t *cap;
- int i;
+ int n, i;
- kdbus_printf(" +%s (%llu bytes) len=%llu bytes\n",
- enum_MSG(item->type), item->size,
- (unsigned long long)item->size -
- KDBUS_ITEM_HEADER_SIZE);
+ kdbus_printf(" +%s (%llu bytes) len=%llu bytes, last_cap %d\n",
+ enum_MSG(item->type), item->size,
+ (unsigned long long)item->size -
+ KDBUS_ITEM_HEADER_SIZE,
+ (int) item->caps.last_cap);
- cap = item->data32;
- n = (item->size - KDBUS_ITEM_HEADER_SIZE) / 4 / sizeof(uint32_t);
+ cap = item->caps.caps;
+ n = (item->size - offsetof(struct kdbus_item, caps.caps))
+ / 4 / sizeof(uint32_t);
kdbus_printf(" CapInh=");
for (i = 0; i < n; i++)