summaryrefslogtreecommitdiff
path: root/tools/testing/selftests/kdbus/test-bus.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/testing/selftests/kdbus/test-bus.c')
-rw-r--r--tools/testing/selftests/kdbus/test-bus.c175
1 files changed, 175 insertions, 0 deletions
diff --git a/tools/testing/selftests/kdbus/test-bus.c b/tools/testing/selftests/kdbus/test-bus.c
new file mode 100644
index 000000000..762fb3039
--- /dev/null
+++ b/tools/testing/selftests/kdbus/test-bus.c
@@ -0,0 +1,175 @@
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <errno.h>
+#include <assert.h>
+#include <limits.h>
+#include <sys/mman.h>
+#include <stdbool.h>
+
+#include "kdbus-api.h"
+#include "kdbus-util.h"
+#include "kdbus-enum.h"
+#include "kdbus-test.h"
+
+static struct kdbus_item *kdbus_get_item(struct kdbus_info *info,
+ uint64_t type)
+{
+ struct kdbus_item *item;
+
+ KDBUS_ITEM_FOREACH(item, info, items)
+ if (item->type == type)
+ return item;
+
+ return NULL;
+}
+
+static int test_bus_creator_info(const char *bus_path)
+{
+ int ret;
+ uint64_t offset;
+ struct kdbus_conn *conn;
+ struct kdbus_info *info;
+ struct kdbus_item *item;
+ char *tmp, *busname;
+
+ /* extract the bus-name from @bus_path */
+ tmp = strdup(bus_path);
+ ASSERT_RETURN(tmp);
+ busname = strrchr(tmp, '/');
+ ASSERT_RETURN(busname);
+ *busname = 0;
+ busname = strrchr(tmp, '/');
+ ASSERT_RETURN(busname);
+ ++busname;
+
+ conn = kdbus_hello(bus_path, 0, NULL, 0);
+ ASSERT_RETURN(conn);
+
+ ret = kdbus_bus_creator_info(conn, _KDBUS_ATTACH_ALL, &offset);
+ ASSERT_RETURN(ret == 0);
+
+ info = (struct kdbus_info *)(conn->buf + offset);
+
+ item = kdbus_get_item(info, KDBUS_ITEM_MAKE_NAME);
+ ASSERT_RETURN(item);
+ ASSERT_RETURN(!strcmp(item->str, busname));
+
+ ret = kdbus_free(conn, offset);
+ ASSERT_RETURN_VAL(ret == 0, ret);
+
+ free(tmp);
+ kdbus_conn_free(conn);
+ return 0;
+}
+
+int kdbus_test_bus_make(struct kdbus_test_env *env)
+{
+ struct {
+ struct kdbus_cmd cmd;
+
+ /* bloom size item */
+ struct {
+ uint64_t size;
+ uint64_t type;
+ struct kdbus_bloom_parameter bloom;
+ } bs;
+
+ /* name item */
+ uint64_t n_size;
+ uint64_t n_type;
+ char name[64];
+ } bus_make;
+ char s[PATH_MAX], *name;
+ int ret, control_fd2;
+ uid_t uid;
+
+ name = unique_name("");
+ ASSERT_RETURN(name);
+
+ snprintf(s, sizeof(s), "%s/control", env->root);
+ env->control_fd = open(s, O_RDWR|O_CLOEXEC);
+ ASSERT_RETURN(env->control_fd >= 0);
+
+ control_fd2 = open(s, O_RDWR|O_CLOEXEC);
+ ASSERT_RETURN(control_fd2 >= 0);
+
+ memset(&bus_make, 0, sizeof(bus_make));
+
+ bus_make.bs.size = sizeof(bus_make.bs);
+ bus_make.bs.type = KDBUS_ITEM_BLOOM_PARAMETER;
+ bus_make.bs.bloom.size = 64;
+ bus_make.bs.bloom.n_hash = 1;
+
+ bus_make.n_type = KDBUS_ITEM_MAKE_NAME;
+
+ uid = getuid();
+
+ /* missing uid prefix */
+ snprintf(bus_make.name, sizeof(bus_make.name), "foo");
+ bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1;
+ bus_make.cmd.size = sizeof(struct kdbus_cmd) +
+ sizeof(bus_make.bs) + bus_make.n_size;
+ ret = kdbus_cmd_bus_make(env->control_fd, &bus_make.cmd);
+ ASSERT_RETURN(ret == -EINVAL);
+
+ /* non alphanumeric character */
+ snprintf(bus_make.name, sizeof(bus_make.name), "%u-blah@123", uid);
+ bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1;
+ bus_make.cmd.size = sizeof(struct kdbus_cmd) +
+ sizeof(bus_make.bs) + bus_make.n_size;
+ ret = kdbus_cmd_bus_make(env->control_fd, &bus_make.cmd);
+ ASSERT_RETURN(ret == -EINVAL);
+
+ /* '-' at the end */
+ snprintf(bus_make.name, sizeof(bus_make.name), "%u-blah-", uid);
+ bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1;
+ bus_make.cmd.size = sizeof(struct kdbus_cmd) +
+ sizeof(bus_make.bs) + bus_make.n_size;
+ ret = kdbus_cmd_bus_make(env->control_fd, &bus_make.cmd);
+ ASSERT_RETURN(ret == -EINVAL);
+
+ /* create a new bus */
+ snprintf(bus_make.name, sizeof(bus_make.name), "%u-%s-1", uid, name);
+ bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1;
+ bus_make.cmd.size = sizeof(struct kdbus_cmd) +
+ sizeof(bus_make.bs) + bus_make.n_size;
+ ret = kdbus_cmd_bus_make(env->control_fd, &bus_make.cmd);
+ ASSERT_RETURN(ret == 0);
+
+ ret = kdbus_cmd_bus_make(control_fd2, &bus_make.cmd);
+ ASSERT_RETURN(ret == -EEXIST);
+
+ snprintf(s, sizeof(s), "%s/%u-%s-1/bus", env->root, uid, name);
+ ASSERT_RETURN(access(s, F_OK) == 0);
+
+ ret = test_bus_creator_info(s);
+ ASSERT_RETURN(ret == 0);
+
+ /* can't use the same fd for bus make twice, even though a different
+ * bus name is used
+ */
+ snprintf(bus_make.name, sizeof(bus_make.name), "%u-%s-2", uid, name);
+ bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1;
+ bus_make.cmd.size = sizeof(struct kdbus_cmd) +
+ sizeof(bus_make.bs) + bus_make.n_size;
+ ret = kdbus_cmd_bus_make(env->control_fd, &bus_make.cmd);
+ ASSERT_RETURN(ret == -EBADFD);
+
+ /* create a new bus, with different fd and different bus name */
+ snprintf(bus_make.name, sizeof(bus_make.name), "%u-%s-2", uid, name);
+ bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1;
+ bus_make.cmd.size = sizeof(struct kdbus_cmd) +
+ sizeof(bus_make.bs) + bus_make.n_size;
+ ret = kdbus_cmd_bus_make(control_fd2, &bus_make.cmd);
+ ASSERT_RETURN(ret == 0);
+
+ close(control_fd2);
+ free(name);
+
+ return TEST_OK;
+}