While at it, make the bloom_size struct member a kdbus item.
/**
* kdbus_bus_new() - create a new bus
* @ns: The namespace to work on
- * @bus_make: Pointer to a struct kdbus_cmd_bus_make containing the
+ * @make: Pointer to a struct kdbus_cmd_make containing the
* details for the bus creation
* @name: Name of the bus
* @mode: The access mode for the device node
* Returns: 0 on success, negative errno on failure.
*/
int kdbus_bus_new(struct kdbus_ns *ns,
- struct kdbus_cmd_bus_make *bus_make, const char *name,
- umode_t mode, kuid_t uid, kgid_t gid, struct kdbus_bus **bus)
+ struct kdbus_cmd_make *make, const char *name,
+ size_t bloom_size, umode_t mode, kuid_t uid,
+ kgid_t gid, struct kdbus_bus **bus)
{
char prefix[16];
struct kdbus_bus *b;
kref_init(&b->kref);
b->uid_owner = uid;
- b->bus_flags = bus_make->flags;
- b->bloom_size = bus_make->bloom_size;
+ b->bus_flags = make->flags;
+ b->bloom_size = bloom_size;
b->conn_id_next = 1; /* connection 0 == kernel */
mutex_init(&b->lock);
hash_init(b->conn_hash);
}
/**
- * kdbus_bus_make_user() - create a kdbus_cmd_bus_make from user-supplied data
+ * kdbus_bus_make_user() - create a kdbus_cmd_make from user-supplied data
* @buf: The user supplied data from the ioctl() call
* @make: Reference to the location where to store the result
* @name: Shortcut to the requested name
+ * @bloom_size: The bloom filter size as denoted in the make items
*
* This function is part of the connection ioctl() interface and will parse
* the user-supplied data.
*
* Returns: 0 on success, negative errno on failure.
*/
-int kdbus_bus_make_user(void __user *buf,
- struct kdbus_cmd_bus_make **make, char **name)
+int kdbus_bus_make_user(void __user *buf, struct kdbus_cmd_make **make,
+ char **name, size_t *bloom_size)
{
u64 size;
- struct kdbus_cmd_bus_make *m;
+ struct kdbus_cmd_make *m;
const char *n = NULL;
const struct kdbus_item *item;
+ u64 bsize = 0;
int ret;
- if (kdbus_size_get_user(&size, buf, struct kdbus_cmd_bus_make))
+
+ if (kdbus_size_get_user(&size, buf, struct kdbus_cmd_make))
return -EFAULT;
- if (size < sizeof(struct kdbus_cmd_bus_make) || size > KDBUS_MAKE_MAX_SIZE)
+ if (size < sizeof(struct kdbus_cmd_make) || size > KDBUS_MAKE_MAX_SIZE)
return -EMSGSIZE;
m = memdup_user(buf, size);
}
n = item->str;
- continue;
+ break;
+
+ case KDBUS_ITEM_BLOOM_SIZE:
+ if (item->size < KDBUS_ITEM_HEADER_SIZE + sizeof(u64)) {
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ bsize = item->data64[0];
+ break;
default:
ret = -ENOTSUPP;
goto exit;
}
- if (!KDBUS_IS_ALIGNED8(m->bloom_size)) {
+ if (!KDBUS_IS_ALIGNED8(bsize)) {
ret = -EINVAL;
goto exit;
}
- if (m->bloom_size < 8 || m->bloom_size > 16 * 1024) {
+ if (bsize < 8 || bsize > SZ_16K) {
ret = -EINVAL;
goto exit;
}
*make = m;
*name = (char *)n;
+ *bloom_size = (size_t)bsize;
return 0;
exit:
u8 id128[16];
};
-int kdbus_bus_make_user(void __user *buf,
- struct kdbus_cmd_bus_make **make, char **name);
-int kdbus_bus_new(struct kdbus_ns *ns,
- struct kdbus_cmd_bus_make *make, const char *name,
+int kdbus_bus_make_user(void __user *buf, struct kdbus_cmd_make **make,
+ char **name, size_t *bsize);
+int kdbus_bus_new(struct kdbus_ns *ns, struct kdbus_cmd_make *make,
+ const char *name, size_t bloom_size,
umode_t mode, kuid_t uid, kgid_t gid, struct kdbus_bus **bus);
struct kdbus_bus *kdbus_bus_ref(struct kdbus_bus *bus);
struct kdbus_bus *kdbus_bus_unref(struct kdbus_bus *bus);
* Returns: 0 on success, negative errno on failure.
*/
int kdbus_ep_make_user(void __user *buf,
- struct kdbus_cmd_ep_make **make, char **name)
+ struct kdbus_cmd_make **make, char **name)
{
u64 size;
- struct kdbus_cmd_ep_make *m;
+ struct kdbus_cmd_make *m;
const struct kdbus_item *item;
const char *n = NULL;
int ret;
- if (kdbus_size_get_user(&size, buf, struct kdbus_cmd_ep_make))
+ if (kdbus_size_get_user(&size, buf, struct kdbus_cmd_make))
return -EFAULT;
- if (size < sizeof(struct kdbus_cmd_ep_make) || size > KDBUS_MAKE_MAX_SIZE)
+ if (size < sizeof(struct kdbus_cmd_make) || size > KDBUS_MAKE_MAX_SIZE)
return -EMSGSIZE;
m = memdup_user(buf, size);
struct kdbus_ep *kdbus_ep_unref(struct kdbus_ep *ep);
void kdbus_ep_disconnect(struct kdbus_ep *ep);
int kdbus_ep_make_user(void __user *buf,
- struct kdbus_cmd_ep_make **make, char **name);
+ struct kdbus_cmd_make **make, char **name);
#endif
void __user *buf)
{
struct kdbus_handle *handle = file->private_data;
- struct kdbus_cmd_bus_make *bus_make = NULL;
- struct kdbus_cmd_ns_make *ns_make = NULL;
+ struct kdbus_cmd_make *make = NULL;
struct kdbus_bus *bus = NULL;
struct kdbus_ns *ns = NULL;
umode_t mode = 0600;
switch (cmd) {
case KDBUS_CMD_BUS_MAKE: {
kgid_t gid = KGIDT_INIT(0);
+ size_t bloom_size;
char *name;
if (!KDBUS_IS_ALIGNED8((uintptr_t)buf)) {
break;
}
- ret = kdbus_bus_make_user(buf, &bus_make, &name);
+ ret = kdbus_bus_make_user(buf, &make, &name, &bloom_size);
if (ret < 0)
break;
- if (!kdbus_check_flags(bus_make->flags)) {
+ if (!kdbus_check_flags(make->flags)) {
ret = -ENOTSUPP;
break;
}
- if (bus_make->flags & KDBUS_MAKE_ACCESS_WORLD) {
+ if (make->flags & KDBUS_MAKE_ACCESS_WORLD) {
mode = 0666;
- } else if (bus_make->flags & KDBUS_MAKE_ACCESS_GROUP) {
+ } else if (make->flags & KDBUS_MAKE_ACCESS_GROUP) {
mode = 0660;
gid = current_fsgid();
}
- ret = kdbus_bus_new(handle->ns, bus_make, name,
+ ret = kdbus_bus_new(handle->ns, make, name, bloom_size,
mode, current_fsuid(), gid, &bus);
if (ret < 0)
break;
break;
}
- ret = kdbus_ns_make_user(buf, &ns_make, &name);
+ ret = kdbus_ns_make_user(buf, &make, &name);
if (ret < 0)
break;
- if (!kdbus_check_flags(ns_make->flags)) {
+ if (!kdbus_check_flags(make->flags)) {
ret = -ENOTSUPP;
break;
}
- if (ns_make->flags & KDBUS_MAKE_ACCESS_WORLD)
+ if (make->flags & KDBUS_MAKE_ACCESS_WORLD)
mode = 0666;
ret = kdbus_ns_new(kdbus_ns_init, name, mode, &ns);
break;
}
- kfree(bus_make);
- kfree(ns_make);
+ kfree(make);
return ret;
}
void __user *buf)
{
struct kdbus_handle *handle = file->private_data;
- struct kdbus_cmd_ep_make *m = NULL;
+ struct kdbus_cmd_make *make = NULL;
struct kdbus_cmd_hello *hello = NULL;
long ret = 0;
break;
}
- ret = kdbus_ep_make_user(buf, &m, &n);
+ ret = kdbus_ep_make_user(buf, &make, &n);
if (ret < 0)
break;
- if (!kdbus_check_flags(m->flags)) {
+ if (!kdbus_check_flags(make->flags)) {
ret = -ENOTSUPP;
break;
}
- if (m->flags & KDBUS_MAKE_ACCESS_WORLD) {
+ if (make->flags & KDBUS_MAKE_ACCESS_WORLD) {
mode = 0666;
- } else if (m->flags & KDBUS_MAKE_ACCESS_GROUP) {
+ } else if (make->flags & KDBUS_MAKE_ACCESS_GROUP) {
mode = 0660;
gid = current_fsgid();
}
ret = kdbus_ep_new(handle->ep->bus, handle->ep->bus->ns, n,
mode, current_fsuid(), gid,
- m->flags & KDBUS_MAKE_POLICY_OPEN);
+ make->flags & KDBUS_MAKE_POLICY_OPEN);
handle->type = KDBUS_HANDLE_EP_OWNER;
break;
break;
}
- kfree(m);
+ kfree(make);
kfree(hello);
return ret;
* @KDBUS_ITEM_PAYLOAD_MEMFD: Data as sealed memfd
* @KDBUS_ITEM_FDS: Attached file descriptors
* @KDBUS_ITEM_BLOOM: For broadcasts, carries bloom filter
+ * @KDBUS_ITEM_BLOOM_SIZE: Desired bloom size, used by KDBUS_CMD_BUS_MAKE
* @KDBUS_ITEM_DST_NAME: Destination's well-known name
* @KDBUS_ITEM_PRIORITY: Queue priority for message
* @KDBUS_ITEM_MAKE_NAME: Name of namespace, bus, endpoint
KDBUS_ITEM_PAYLOAD_MEMFD,
KDBUS_ITEM_FDS,
KDBUS_ITEM_BLOOM,
+ KDBUS_ITEM_BLOOM_SIZE,
KDBUS_ITEM_DST_NAME,
KDBUS_ITEM_PRIORITY,
KDBUS_ITEM_MAKE_NAME,
};
/**
- * struct kdbus_cmd_bus_make - struct to make a bus
+ * struct kdbus_cmd_make - struct to make a bus, an endpoint or a namespace
* @size: The total size of the struct
- * @flags: Properties for the bus to create
- * @bloom_size: Size of the bloom filter for this bus
- * @items: Items describing details such as the name of the bus
+ * @flags: Properties for the bus/ep/ns to create
+ * @items: Items describing details
*
- * This structure is used with the KDBUS_CMD_BUS_MAKE ioctl.
+ * This structure is used with the KDBUS_CMD_BUS_MAKE, KDBUS_CMD_EP_MAKE and
+ * KDBUS_CMD_NS_MAKE ioctls.
*/
-struct kdbus_cmd_bus_make {
- __u64 size;
- __u64 flags;
- __u64 bloom_size;
- struct kdbus_item items[0];
-} __attribute__((aligned(8)));
-
-/**
- * struct kdbus_cmd_ep_make - struct to make an endpoint
- * @size: The total size of the struct
- * @flags: Unused for now
- * @items: Items describing details such as the
- * name of the endpoint
- *
- * This structure is used with the KDBUS_CMD_EP_MAKE ioctl.
- */
-struct kdbus_cmd_ep_make {
- __u64 size;
- __u64 flags;
- struct kdbus_item items[0];
-} __attribute__((aligned(8)));
-
-/**
- * struct kdbus_cmd_ns_make - struct to make a namespace
- * @size: The total size of the struct
- * @flags: Unused for now
- * @items: Items describing details such as the
- * name of the namespace
- *
- * This structure is used with the KDBUS_CMD_NS_MAKE ioctl.
- */
-struct kdbus_cmd_ns_make {
+struct kdbus_cmd_make {
__u64 size;
__u64 flags;
struct kdbus_item items[0];
* be changed as long as the file is shared.
*/
enum kdbus_ioctl_type {
- KDBUS_CMD_BUS_MAKE = _IOW (KDBUS_IOC_MAGIC, 0x00, struct kdbus_cmd_bus_make),
- KDBUS_CMD_NS_MAKE = _IOR (KDBUS_IOC_MAGIC, 0x10, struct kdbus_cmd_ns_make),
- KDBUS_CMD_EP_MAKE = _IOW (KDBUS_IOC_MAGIC, 0x20, struct kdbus_cmd_ep_make),
+ KDBUS_CMD_BUS_MAKE = _IOW (KDBUS_IOC_MAGIC, 0x00, struct kdbus_cmd_make),
+ KDBUS_CMD_NS_MAKE = _IOR (KDBUS_IOC_MAGIC, 0x10, struct kdbus_cmd_make),
+ KDBUS_CMD_EP_MAKE = _IOW (KDBUS_IOC_MAGIC, 0x20, struct kdbus_cmd_make),
KDBUS_CMD_HELLO = _IOWR(KDBUS_IOC_MAGIC, 0x30, struct kdbus_cmd_hello),
* Returns: 0 on success, negative errno on failure.
*/
int kdbus_ns_make_user(void __user *buf,
- struct kdbus_cmd_ns_make **make, char **name)
+ struct kdbus_cmd_make **make, char **name)
{
u64 size;
- struct kdbus_cmd_ns_make *m;
+ struct kdbus_cmd_make *m;
const struct kdbus_item *item;
const char *n = NULL;
int ret;
- if (kdbus_size_get_user(&size, buf, struct kdbus_cmd_ns_make))
+ if (kdbus_size_get_user(&size, buf, struct kdbus_cmd_make))
return -EFAULT;
- if (size < sizeof(struct kdbus_cmd_ns_make) || size > KDBUS_MAKE_MAX_SIZE)
+ if (size < sizeof(struct kdbus_cmd_make) || size > KDBUS_MAKE_MAX_SIZE)
return -EMSGSIZE;
m = memdup_user(buf, size);
struct kdbus_ns *kdbus_ns_unref(struct kdbus_ns *ns);
void kdbus_ns_disconnect(struct kdbus_ns *ns);
int kdbus_ns_new(struct kdbus_ns *parent, const char *name, umode_t mode, struct kdbus_ns **ns);
-int kdbus_ns_make_user(void __user *buf, struct kdbus_cmd_ns_make **make, char **name);
+int kdbus_ns_make_user(void __user *buf, struct kdbus_cmd_make **make, char **name);
struct kdbus_ns *kdbus_ns_find_by_major(unsigned int major);
#endif
int main(int argc, char *argv[])
{
struct {
- struct kdbus_cmd_bus_make head;
+ struct kdbus_cmd_make head;
+
+ /* bloom size item */
+ struct {
+ uint64_t size;
+ uint64_t type;
+ uint64_t bloom_size;
+ } bs;
/* name item */
uint64_t n_size;
}
memset(&bus_make, 0, sizeof(bus_make));
- bus_make.head.bloom_size = 64;
+ bus_make.bs.size = sizeof(bus_make.bs);
+ bus_make.bs.type = KDBUS_ITEM_BLOOM_SIZE;
+ bus_make.bs.bloom_size = 64;
snprintf(bus_make.name, sizeof(bus_make.name), "%u-testbus", getuid());
bus_make.n_type = KDBUS_ITEM_MAKE_NAME;
bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1;
- bus_make.head.size = sizeof(struct kdbus_cmd_bus_make) +
+ bus_make.head.size = sizeof(struct kdbus_cmd_make) +
+ sizeof(bus_make.bs) +
bus_make.n_size;
printf("-- creating bus '%s'\n", bus_make.name);
int main(int argc, char *argv[])
{
struct {
- struct kdbus_cmd_bus_make head;
+ struct kdbus_cmd_make head;
+
+ /* bloom size item */
+ struct {
+ uint64_t size;
+ uint64_t type;
+ uint64_t bloom_size;
+ } bs;
/* name item */
uint64_t n_size;
}
memset(&bus_make, 0, sizeof(bus_make));
- bus_make.head.bloom_size = 64;
+ bus_make.bs.size = sizeof(bus_make.bs);
+ bus_make.bs.type = KDBUS_ITEM_BLOOM_SIZE;
+ bus_make.bs.bloom_size = 64;
snprintf(bus_make.name, sizeof(bus_make.name), "%u-testbus", getuid());
bus_make.n_type = KDBUS_ITEM_MAKE_NAME;
bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1;
- bus_make.head.size = sizeof(struct kdbus_cmd_bus_make) +
+ bus_make.head.size = sizeof(struct kdbus_cmd_make) +
+ sizeof(bus_make.bs) +
bus_make.n_size;
printf("-- creating bus '%s'\n", bus_make.name);
int main(int argc, char *argv[])
{
struct {
- struct kdbus_cmd_bus_make head;
+ struct kdbus_cmd_make head;
+
+ /* bloom size item */
+ struct {
+ uint64_t size;
+ uint64_t type;
+ uint64_t bloom_size;
+ } bs;
/* name item */
uint64_t n_size;
}
memset(&bus_make, 0, sizeof(bus_make));
- bus_make.head.bloom_size = 64;
+ bus_make.bs.size = sizeof(bus_make.bs);
+ bus_make.bs.type = KDBUS_ITEM_BLOOM_SIZE;
+ bus_make.bs.bloom_size = 64;
snprintf(bus_make.name, sizeof(bus_make.name), "%u-testbus", getuid());
bus_make.n_type = KDBUS_ITEM_MAKE_NAME;
bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1;
- bus_make.head.size = sizeof(struct kdbus_cmd_bus_make) +
+ bus_make.head.size = sizeof(struct kdbus_cmd_make) +
+ sizeof(bus_make.bs) +
bus_make.n_size;
printf("-- creating bus '%s'\n", bus_make.name);
int main(int argc, char *argv[])
{
struct {
- struct kdbus_cmd_bus_make head;
+ struct kdbus_cmd_make head;
+
+ /* bloom size item */
+ struct {
+ uint64_t size;
+ uint64_t type;
+ uint64_t bloom_size;
+ } bs;
+
uint64_t n_size;
uint64_t n_type;
char name[64];
}
memset(&bus_make, 0, sizeof(bus_make));
- bus_make.head.bloom_size = 64;
+ bus_make.bs.size = sizeof(bus_make.bs);
+ bus_make.bs.type = KDBUS_ITEM_BLOOM_SIZE;
+ bus_make.bs.bloom_size = 64;
snprintf(bus_make.name, sizeof(bus_make.name), "%u-testbus", getuid());
bus_make.n_type = KDBUS_ITEM_MAKE_NAME;
bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1;
- bus_make.head.size = sizeof(struct kdbus_cmd_bus_make) +
+ bus_make.head.size = sizeof(struct kdbus_cmd_make) +
+ sizeof(bus_make.bs) +
bus_make.n_size;
ret = ioctl(fd_owner, KDBUS_CMD_BUS_MAKE, &bus_make);
static int make_bus(void)
{
struct {
- struct kdbus_cmd_bus_make head;
+ struct kdbus_cmd_make head;
+
+ /* bloom size item */
+ struct {
+ uint64_t size;
+ uint64_t type;
+ uint64_t bloom_size;
+ } bs;
+
+ /* name item */
+ uint64_t n_size;
+ uint64_t n_type;
char name[64];
} bus_make;
char name[10];
memset(&bus_make, 0, sizeof(bus_make));
snprintf(bus_make.name, sizeof(bus_make.name), "%u-%s", getuid(), name);
bus_make.head.flags = KDBUS_MAKE_ACCESS_WORLD;
- bus_make.head.size = sizeof(struct kdbus_cmd_bus_make) + strlen(bus_make.name) + 1;
- bus_make.head.bloom_size = 64;
+ bus_make.head.size = sizeof(struct kdbus_cmd_make) + strlen(bus_make.name) + 1;
+
+ bus_make.bs.size = sizeof(bus_make.bs);
+ bus_make.bs.type = KDBUS_ITEM_BLOOM_SIZE;
+ bus_make.bs.bloom_size = 64;
printf("-- creating bus '%s'\n", bus_make.name);
ret = ioctl(fdc, KDBUS_CMD_BUS_MAKE, &bus_make);
{
int fd, fd2;
struct {
- struct kdbus_cmd_ns_make head;
+ struct kdbus_cmd_make head;
/* name item */
uint64_t n_size;
/* create a new namespace */
snprintf(ns_make.name, sizeof(ns_make.name), "blah");
ns_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(ns_make.name) + 1;
- ns_make.head.size = sizeof(struct kdbus_cmd_ns_make) + ns_make.n_size;
+ ns_make.head.size = sizeof(struct kdbus_cmd_make) + ns_make.n_size;
ret = ioctl(fd, KDBUS_CMD_NS_MAKE, &ns_make);
if (ret < 0 && errno == EPERM)
return CHECK_SKIP;
static int check_busmake(struct kdbus_check_env *env)
{
struct {
- struct kdbus_cmd_bus_make head;
+ struct kdbus_cmd_make head;
+
+ /* bloom size item */
+ struct {
+ uint64_t size;
+ uint64_t type;
+ uint64_t bloom_size;
+ } bs;
/* name item */
uint64_t n_size;
ASSERT_RETURN(env->control_fd >= 0);
memset(&bus_make, 0, sizeof(bus_make));
- bus_make.head.bloom_size = 64;
+
+ bus_make.bs.size = sizeof(bus_make.bs);
+ bus_make.bs.type = KDBUS_ITEM_BLOOM_SIZE;
+ bus_make.bs.bloom_size = 64;
bus_make.n_type = KDBUS_ITEM_MAKE_NAME;
/* check some illegal names */
snprintf(bus_make.name, sizeof(bus_make.name), "foo");
bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1;
- bus_make.head.size = sizeof(struct kdbus_cmd_bus_make) + bus_make.n_size;
+ bus_make.head.size = sizeof(struct kdbus_cmd_make) + bus_make.n_size;
ret = ioctl(env->control_fd, KDBUS_CMD_BUS_MAKE, &bus_make);
ASSERT_RETURN(ret == -1 && errno == EINVAL);
#endif
/* create a new bus */
snprintf(bus_make.name, sizeof(bus_make.name), "%u-blah", getuid());
bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1;
- bus_make.head.size = sizeof(struct kdbus_cmd_bus_make) + bus_make.n_size;
+ bus_make.head.size = sizeof(struct kdbus_cmd_make) +
+ sizeof(uint64_t) * 3 +
+ bus_make.n_size;
ret = ioctl(env->control_fd, KDBUS_CMD_BUS_MAKE, &bus_make);
ASSERT_RETURN(ret == 0);
snprintf(s, sizeof(s), "/dev/kdbus/%u-blah/bus", getuid());
{
if (c->flags & CHECK_CREATE_BUS) {
struct {
- struct kdbus_cmd_bus_make head;
+ struct kdbus_cmd_make head;
+
+ /* bloom size item */
+ struct {
+ uint64_t size;
+ uint64_t type;
+ uint64_t bloom_size;
+ } bs;
/* name item */
uint64_t n_size;
ASSERT_RETURN(env->control_fd >= 0);
memset(&bus_make, 0, sizeof(bus_make));
- bus_make.head.bloom_size = 64;
+ bus_make.bs.size = sizeof(bus_make.bs);
+ bus_make.bs.type = KDBUS_ITEM_BLOOM_SIZE;
+ bus_make.bs.bloom_size = 64;
for (i = 0; i < sizeof(n); i++)
n[i] = 'a' + (random() % ('z' - 'a'));
bus_make.n_type = KDBUS_ITEM_MAKE_NAME;
bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1;
- bus_make.head.size = sizeof(struct kdbus_cmd_bus_make) +
+ bus_make.head.size = sizeof(struct kdbus_cmd_make) +
+ sizeof(bus_make.bs) +
bus_make.n_size;
ret = ioctl(env->control_fd, KDBUS_CMD_BUS_MAKE, &bus_make);