Beispiel #1
0
struct kdbus_conn *
kdbus_hello_registrar(const char *path, const char *name,
		      const struct kdbus_policy_access *access,
		      size_t num_access, uint64_t flags)
{
	struct kdbus_item *item, *items;
	size_t i, size;

	size = KDBUS_ITEM_SIZE(strlen(name) + 1) +
		num_access * KDBUS_ITEM_SIZE(sizeof(*access));

	items = alloca(size);

	item = items;
	item->size = KDBUS_ITEM_HEADER_SIZE + strlen(name) + 1;
	item->type = KDBUS_ITEM_NAME;
	strcpy(item->str, name);
	item = KDBUS_ITEM_NEXT(item);

	for (i = 0; i < num_access; i++) {
		item->size = KDBUS_ITEM_HEADER_SIZE +
			     sizeof(struct kdbus_policy_access);
		item->type = KDBUS_ITEM_POLICY_ACCESS;

		item->policy_access.type = access[i].type;
		item->policy_access.access = access[i].access;
		item->policy_access.id = access[i].id;

		item = KDBUS_ITEM_NEXT(item);
	}

	return kdbus_hello(path, flags, items, size);
}
Beispiel #2
0
int kdbus_conn_update_policy(struct kdbus_conn *conn, const char *name,
			     const struct kdbus_policy_access *access,
			     size_t num_access)
{
	struct kdbus_cmd_update *update;
	struct kdbus_item *item;
	size_t i, size;
	int ret;

	size = sizeof(struct kdbus_cmd_update);
	size += KDBUS_ITEM_SIZE(strlen(name) + 1);
	size += num_access * KDBUS_ITEM_SIZE(sizeof(struct kdbus_policy_access));

	update = malloc(size);
	if (!update) {
		ret = -errno;
		kdbus_printf("error malloc: %d (%m)\n", ret);
		return ret;
	}

	memset(update, 0, size);
	update->size = size;

	item = update->items;

	item->type = KDBUS_ITEM_NAME;
	item->size = KDBUS_ITEM_HEADER_SIZE + strlen(name) + 1;
	strcpy(item->str, name);
	item = KDBUS_ITEM_NEXT(item);

	for (i = 0; i < num_access; i++) {
		item->size = KDBUS_ITEM_HEADER_SIZE +
			     sizeof(struct kdbus_policy_access);
		item->type = KDBUS_ITEM_POLICY_ACCESS;

		item->policy_access.type = access[i].type;
		item->policy_access.access = access[i].access;
		item->policy_access.id = access[i].id;

		item = KDBUS_ITEM_NEXT(item);
	}

	ret = ioctl(conn->fd, KDBUS_CMD_CONN_UPDATE, update);
	if (ret < 0) {
		ret = -errno;
		kdbus_printf("error conn update: %d (%m)\n", ret);
	}

	free(update);

	return ret;
}
Beispiel #3
0
static int send_fd(struct kdbus_conn *conn, uint64_t dst_id, int fd)
{
	struct kdbus_item *item;
	struct kdbus_msg *msg;
	uint64_t size;
	int ret;

	size = sizeof(struct kdbus_msg);
	size += KDBUS_ITEM_SIZE(sizeof(int[2]));

	msg = alloca(size);

	memset(msg, 0, size);
	msg->size = size;
	msg->src_id = conn->id;
	msg->dst_id = dst_id;
	msg->payload_type = KDBUS_PAYLOAD_DBUS;

	item = msg->items;

	item->type = KDBUS_ITEM_FDS;
	item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(int);
	item->fds[0] = fd;
	item = KDBUS_ITEM_NEXT(item);

	ret = ioctl(conn->fd, KDBUS_CMD_MSG_SEND, msg);
	if (ret) {
		kdbus_printf("error sending message: %d err %d (%m)\n",
			     ret, errno);
		return -errno;
	}

	return 0;
}
Beispiel #4
0
static struct conn *make_activator(const char *path, const char *name)
{
	int fd, ret;
	struct kdbus_cmd_hello *hello;
	struct kdbus_item *item;
	struct conn *conn;
	size_t size, slen;

	slen = strlen(name) + 1;
	size = sizeof(*hello) + KDBUS_ITEM_SIZE(slen);

	hello = alloca(size);
	memset(hello, 0, size);

	printf("-- opening ACTIVATOR bus connection %s\n", path);
	fd = open(path, O_RDWR|O_CLOEXEC);
	if (fd < 0) {
		fprintf(stderr, "--- error %d (%m)\n", fd);
		return NULL;
	}

	hello->size = size;
	hello->pool_size = POOL_SIZE;
	hello->conn_flags = KDBUS_HELLO_ACTIVATOR;

	item = hello->items;
	item->size = KDBUS_ITEM_HEADER_SIZE + slen;
	item->type = KDBUS_ITEM_NAME;
	strcpy(item->str, name);

	ret = ioctl(fd, KDBUS_CMD_HELLO, hello);
	if (ret < 0) {
		fprintf(stderr, "--- error when saying hello: %d (%m)\n", ret);
		return NULL;
	}
	printf("-- Our peer ID for activator %s: %llu\n", name, (unsigned long long) hello->id);

	conn = malloc(sizeof(*conn));
	if (!conn) {
		fprintf(stderr, "unable to malloc()!?\n");
		return NULL;
	}

	conn->fd = fd;
	conn->id = hello->id;

	return conn;
}
Beispiel #5
0
int kdbus_conn_update_attach_flags(struct kdbus_conn *conn, uint64_t flags)
{
	int ret;
	size_t size;
	struct kdbus_cmd_update *update;
	struct kdbus_item *item;

	size = sizeof(struct kdbus_cmd_update);
	size += KDBUS_ITEM_SIZE(sizeof(uint64_t));

	update = malloc(size);
	if (!update) {
		ret = -errno;
		kdbus_printf("error malloc: %d (%m)\n", ret);
		return ret;
	}

	memset(update, 0, size);
	update->size = size;

	item = update->items;

	item->type = KDBUS_ITEM_ATTACH_FLAGS;
	item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(uint64_t);
	item->data64[0] = flags;
	item = KDBUS_ITEM_NEXT(item);

	ret = ioctl(conn->fd, KDBUS_CMD_CONN_UPDATE, update);
	if (ret < 0) {
		ret = -errno;
		kdbus_printf("error conn update: %d (%m)\n", ret);
	}

	free(update);

	return ret;
}
Beispiel #6
0
static int kdbus_notify_reply(struct kdbus_ep *ep, u64 src_id,
			      u64 cookie, u64 msg_type)
{
	struct kdbus_conn *dst_conn;
	struct kdbus_kmsg *kmsg;
	struct kdbus_item *item;
	int ret;

	dst_conn = kdbus_bus_find_conn_by_id(ep->bus, src_id);
	if (!dst_conn)
		return -ENXIO;

	ret = kdbus_kmsg_new(KDBUS_ITEM_SIZE(0), &kmsg);
	if (ret < 0)
		return ret;

	/*
	 * a kernel-generated notification can only contain one
	 * struct kdbus_item, so make a shortcut here for
	 * faster lookup in the match db.
	 */
	kmsg->notification_type = msg_type;

	kmsg->msg.dst_id = src_id;
	kmsg->msg.src_id = KDBUS_SRC_ID_KERNEL;
	kmsg->msg.payload_type = KDBUS_PAYLOAD_KERNEL;
	kmsg->msg.cookie_reply = cookie;

	item = kmsg->msg.items;
	item->type = msg_type;

	ret = kdbus_conn_kmsg_send(ep, NULL, kmsg);
	kdbus_kmsg_free(kmsg);

	return ret;
}
Beispiel #7
0
static int
send_echo_request(struct conn *conn, uint64_t dst_id)
{
	struct kdbus_msg *msg;
	struct kdbus_item *item;
	uint64_t size;
	int memfd = -1;
	int ret;
	struct timeval now;

	gettimeofday(&now, NULL);

	size = sizeof(struct kdbus_msg);
	size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));

	ret = ioctl(conn->fd, KDBUS_CMD_MEMFD_NEW, &memfd);
	if (ret < 0) {
		fprintf(stderr, "KDBUS_CMD_MEMFD_NEW failed: %m\n");
		return EXIT_FAILURE;
	}

	if (write(memfd, &now, sizeof(now)) != sizeof(now)) {
		fprintf(stderr, "writing to memfd failed: %m\n");
		return EXIT_FAILURE;
	}

	ret = ioctl(memfd, KDBUS_CMD_MEMFD_SEAL_SET, true);
	if (ret < 0) {
		fprintf(stderr, "memfd sealing failed: %m\n");
		return EXIT_FAILURE;
	}

	size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_memfd));

	msg = malloc(size);
	if (!msg) {
		fprintf(stderr, "unable to malloc()!?\n");
		return EXIT_FAILURE;
	}

	memset(msg, 0, size);
	msg->size = size;
	msg->src_id = conn->id;
	msg->dst_id = dst_id;
	msg->payload_type = KDBUS_PAYLOAD_DBUS;

	item = msg->items;

	item->type = KDBUS_ITEM_PAYLOAD_VEC;
	item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec);
	item->vec.address = (uint64_t) stress_payload;
	item->vec.size = sizeof(stress_payload);
	item = KDBUS_ITEM_NEXT(item);

	item->type = KDBUS_ITEM_PAYLOAD_MEMFD;
	item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_memfd);
	item->memfd.size = 16;
	item->memfd.fd = memfd;
	item = KDBUS_ITEM_NEXT(item);

	ret = ioctl(conn->fd, KDBUS_CMD_MSG_SEND, msg);
	if (ret) {
		fprintf(stderr, "error sending message: %d err %d (%m)\n", ret, errno);
		return EXIT_FAILURE;
	}

	if (memfd >= 0)
		close(memfd);
	free(msg);

	return 0;
}
Beispiel #8
0
int msg_send(const struct conn *conn,
		    const char *name,
		    uint64_t cookie,
		    uint64_t dst_id)
{
	struct kdbus_msg *msg;
	const char ref1[1024 * 1024 + 3] = "0123456789_0";
	const char ref2[] = "0123456789_1";
	struct kdbus_item *item;
	uint64_t size;
	int memfd = -1;
	int ret;

	size = sizeof(struct kdbus_msg);
	size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
	size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
	size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));

	if (dst_id == KDBUS_DST_ID_BROADCAST)
		size += KDBUS_ITEM_HEADER_SIZE + 64;
	else {
		struct {
			struct kdbus_cmd_memfd_make cmd;
			uint64_t size;
			uint64_t type;
			char name[16];
		} m = {};

		m.cmd.size = sizeof(m);
		m.cmd.file_size = 1024 * 1024;
		m.cmd.items[0].type = KDBUS_ITEM_MEMFD_NAME;
		m.cmd.items[0].size = KDBUS_ITEM_HEADER_SIZE + sizeof(m.name);
		strcpy(m.name, "my-name-is-nice");
		ret = ioctl(conn->fd, KDBUS_CMD_MEMFD_NEW, &m);
		if (ret < 0) {
			fprintf(stderr, "KDBUS_CMD_MEMFD_NEW failed: %m\n");
			return EXIT_FAILURE;
		}
		memfd = m.cmd.fd;

		if (write(memfd, "kdbus memfd 1234567", 19) != 19) {
			fprintf(stderr, "writing to memfd failed: %m\n");
			return EXIT_FAILURE;
		}

		ret = ioctl(memfd, KDBUS_CMD_MEMFD_SEAL_SET, true);
		if (ret < 0) {
			fprintf(stderr, "memfd sealing failed: %m\n");
			return EXIT_FAILURE;
		}

		size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_memfd));
	}

	if (name)
		size += KDBUS_ITEM_SIZE(strlen(name) + 1);

	msg = malloc(size);
	if (!msg) {
		fprintf(stderr, "unable to malloc()!?\n");
		return EXIT_FAILURE;
	}

	memset(msg, 0, size);
	msg->size = size;
	msg->src_id = conn->id;
	msg->dst_id = name ? 0 : dst_id;
	msg->cookie = cookie;
	msg->payload_type = KDBUS_PAYLOAD_DBUS;

	item = msg->items;

	if (name) {
		item->type = KDBUS_ITEM_DST_NAME;
		item->size = KDBUS_ITEM_HEADER_SIZE + strlen(name) + 1;
		strcpy(item->str, name);
		item = KDBUS_ITEM_NEXT(item);
	}

	item->type = KDBUS_ITEM_PAYLOAD_VEC;
	item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec);
	item->vec.address = (uintptr_t)&ref1;
	item->vec.size = sizeof(ref1);
	item = KDBUS_ITEM_NEXT(item);

	/* data padding for ref1 */
	item->type = KDBUS_ITEM_PAYLOAD_VEC;
	item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec);
	item->vec.address = (uintptr_t)NULL;
	item->vec.size =  KDBUS_ALIGN8(sizeof(ref1)) - sizeof(ref1);
	item = KDBUS_ITEM_NEXT(item);

	item->type = KDBUS_ITEM_PAYLOAD_VEC;
	item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec);
	item->vec.address = (uintptr_t)&ref2;
	item->vec.size = sizeof(ref2);
	item = KDBUS_ITEM_NEXT(item);

	if (dst_id == KDBUS_DST_ID_BROADCAST) {
		item->type = KDBUS_ITEM_BLOOM;
		item->size = KDBUS_ITEM_HEADER_SIZE + 64;
	} else {
		item->type = KDBUS_ITEM_PAYLOAD_MEMFD;
		item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_memfd);
		item->memfd.size = 16;
		item->memfd.fd = memfd;
	}
	item = KDBUS_ITEM_NEXT(item);

	ret = ioctl(conn->fd, KDBUS_CMD_MSG_SEND, msg);
	if (ret < 0) {
		fprintf(stderr, "error sending message: %d err %d (%m)\n", ret, errno);
		return EXIT_FAILURE;
	}

	if (memfd >= 0)
		close(memfd);
	free(msg);

	return 0;
}
Beispiel #9
0
int kdbus_msg_send(const struct kdbus_conn *conn,
		   const char *name,
		   uint64_t cookie,
		   uint64_t flags,
		   uint64_t timeout,
		   int64_t priority,
		   uint64_t dst_id)
{
	struct kdbus_msg *msg;
	const char ref1[1024 * 128 + 3] = "0123456789_0";
	const char ref2[] = "0123456789_1";
	struct kdbus_item *item;
	uint64_t size;
	int memfd = -1;
	int ret;

	size = sizeof(struct kdbus_msg);
	size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
	size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
	size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));

	if (dst_id == KDBUS_DST_ID_BROADCAST)
		size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter)) + 64;
	else {
		memfd = sys_memfd_create("my-name-is-nice", 1024 * 1024);
		if (memfd < 0) {
			kdbus_printf("failed to create memfd: %m\n");
			return memfd;
		}

		if (write(memfd, "kdbus memfd 1234567", 19) != 19) {
			ret = -errno;
			kdbus_printf("writing to memfd failed: %m\n");
			return ret;
		}

		ret = sys_memfd_seal_set(memfd);
		if (ret < 0) {
			ret = -errno;
			kdbus_printf("memfd sealing failed: %m\n");
			return ret;
		}

		size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_memfd));
	}

	if (name)
		size += KDBUS_ITEM_SIZE(strlen(name) + 1);

	msg = malloc(size);
	if (!msg) {
		ret = -errno;
		kdbus_printf("unable to malloc()!?\n");
		return ret;
	}

	memset(msg, 0, size);
	msg->flags = flags;
	msg->timeout_ns = timeout;
	msg->priority = priority;
	msg->size = size;
	msg->src_id = conn->id;
	msg->dst_id = name ? 0 : dst_id;
	msg->cookie = cookie;
	msg->payload_type = KDBUS_PAYLOAD_DBUS;

	item = msg->items;

	if (name) {
		item->type = KDBUS_ITEM_DST_NAME;
		item->size = KDBUS_ITEM_HEADER_SIZE + strlen(name) + 1;
		strcpy(item->str, name);
		item = KDBUS_ITEM_NEXT(item);
	}

	item->type = KDBUS_ITEM_PAYLOAD_VEC;
	item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec);
	item->vec.address = (uintptr_t)&ref1;
	item->vec.size = sizeof(ref1);
	item = KDBUS_ITEM_NEXT(item);

	/* data padding for ref1 */
	item->type = KDBUS_ITEM_PAYLOAD_VEC;
	item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec);
	item->vec.address = (uintptr_t)NULL;
	item->vec.size =  KDBUS_ALIGN8(sizeof(ref1)) - sizeof(ref1);
	item = KDBUS_ITEM_NEXT(item);

	item->type = KDBUS_ITEM_PAYLOAD_VEC;
	item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec);
	item->vec.address = (uintptr_t)&ref2;
	item->vec.size = sizeof(ref2);
	item = KDBUS_ITEM_NEXT(item);

	if (dst_id == KDBUS_DST_ID_BROADCAST) {
		item->type = KDBUS_ITEM_BLOOM_FILTER;
		item->size = KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter)) + 64;
		item->bloom_filter.generation = 0;
	} else {
		item->type = KDBUS_ITEM_PAYLOAD_MEMFD;
		item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_memfd);
		item->memfd.size = 16;
		item->memfd.fd = memfd;
	}
	item = KDBUS_ITEM_NEXT(item);

	ret = ioctl(conn->fd, KDBUS_CMD_MSG_SEND, msg);
	if (ret < 0) {
		ret = -errno;
		kdbus_printf("error sending message: %d (%m)\n", ret);
		return ret;
	}

	if (memfd >= 0)
		close(memfd);

	if (flags & KDBUS_MSG_FLAGS_SYNC_REPLY) {
		struct kdbus_msg *reply;

		kdbus_printf("SYNC REPLY @offset %llu:\n", msg->offset_reply);
		reply = (struct kdbus_msg *)(conn->buf + msg->offset_reply);
		kdbus_msg_dump(conn, reply);

		ret = kdbus_free(conn, msg->offset_reply);
		if (ret < 0)
			return ret;
	}

	free(msg);

	return 0;
}