kdbus: the driver, original and non-working
[platform/kernel/linux-exynos.git] / tools / testing / selftests / kdbus / test-bus.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <fcntl.h>
4 #include <stdlib.h>
5 #include <stddef.h>
6 #include <unistd.h>
7 #include <stdint.h>
8 #include <errno.h>
9 #include <assert.h>
10 #include <limits.h>
11 #include <sys/mman.h>
12 #include <stdbool.h>
13
14 #include "kdbus-api.h"
15 #include "kdbus-util.h"
16 #include "kdbus-enum.h"
17 #include "kdbus-test.h"
18
19 static struct kdbus_item *kdbus_get_item(struct kdbus_info *info,
20                                          uint64_t type)
21 {
22         struct kdbus_item *item;
23
24         KDBUS_ITEM_FOREACH(item, info, items)
25                 if (item->type == type)
26                         return item;
27
28         return NULL;
29 }
30
31 static int test_bus_creator_info(const char *bus_path)
32 {
33         int ret;
34         uint64_t offset;
35         struct kdbus_conn *conn;
36         struct kdbus_info *info;
37         struct kdbus_item *item;
38         char *tmp, *busname;
39
40         /* extract the bus-name from @bus_path */
41         tmp = strdup(bus_path);
42         ASSERT_RETURN(tmp);
43         busname = strrchr(tmp, '/');
44         ASSERT_RETURN(busname);
45         *busname = 0;
46         busname = strrchr(tmp, '/');
47         ASSERT_RETURN(busname);
48         ++busname;
49
50         conn = kdbus_hello(bus_path, 0, NULL, 0);
51         ASSERT_RETURN(conn);
52
53         ret = kdbus_bus_creator_info(conn, _KDBUS_ATTACH_ALL, &offset);
54         ASSERT_RETURN(ret == 0);
55
56         info = (struct kdbus_info *)(conn->buf + offset);
57
58         item = kdbus_get_item(info, KDBUS_ITEM_MAKE_NAME);
59         ASSERT_RETURN(item);
60         ASSERT_RETURN(!strcmp(item->str, busname));
61
62         ret = kdbus_free(conn, offset);
63         ASSERT_RETURN_VAL(ret == 0, ret);
64
65         free(tmp);
66         kdbus_conn_free(conn);
67         return 0;
68 }
69
70 int kdbus_test_bus_make(struct kdbus_test_env *env)
71 {
72         struct {
73                 struct kdbus_cmd cmd;
74
75                 /* bloom size item */
76                 struct {
77                         uint64_t size;
78                         uint64_t type;
79                         struct kdbus_bloom_parameter bloom;
80                 } bs;
81
82                 /* name item */
83                 uint64_t n_size;
84                 uint64_t n_type;
85                 char name[64];
86         } bus_make;
87         char s[PATH_MAX], *name;
88         int ret, control_fd2;
89         uid_t uid;
90
91         name = unique_name("");
92         ASSERT_RETURN(name);
93
94         snprintf(s, sizeof(s), "%s/control", env->root);
95         env->control_fd = open(s, O_RDWR|O_CLOEXEC);
96         ASSERT_RETURN(env->control_fd >= 0);
97
98         control_fd2 = open(s, O_RDWR|O_CLOEXEC);
99         ASSERT_RETURN(control_fd2 >= 0);
100
101         memset(&bus_make, 0, sizeof(bus_make));
102
103         bus_make.bs.size = sizeof(bus_make.bs);
104         bus_make.bs.type = KDBUS_ITEM_BLOOM_PARAMETER;
105         bus_make.bs.bloom.size = 64;
106         bus_make.bs.bloom.n_hash = 1;
107
108         bus_make.n_type = KDBUS_ITEM_MAKE_NAME;
109
110         uid = getuid();
111
112         /* missing uid prefix */
113         snprintf(bus_make.name, sizeof(bus_make.name), "foo");
114         bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1;
115         bus_make.cmd.size = sizeof(struct kdbus_cmd) +
116                             sizeof(bus_make.bs) + bus_make.n_size;
117         ret = kdbus_cmd_bus_make(env->control_fd, &bus_make.cmd);
118         ASSERT_RETURN(ret == -EINVAL);
119
120         /* non alphanumeric character */
121         snprintf(bus_make.name, sizeof(bus_make.name), "%u-blah@123", uid);
122         bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1;
123         bus_make.cmd.size = sizeof(struct kdbus_cmd) +
124                             sizeof(bus_make.bs) + bus_make.n_size;
125         ret = kdbus_cmd_bus_make(env->control_fd, &bus_make.cmd);
126         ASSERT_RETURN(ret == -EINVAL);
127
128         /* '-' at the end */
129         snprintf(bus_make.name, sizeof(bus_make.name), "%u-blah-", uid);
130         bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1;
131         bus_make.cmd.size = sizeof(struct kdbus_cmd) +
132                             sizeof(bus_make.bs) + bus_make.n_size;
133         ret = kdbus_cmd_bus_make(env->control_fd, &bus_make.cmd);
134         ASSERT_RETURN(ret == -EINVAL);
135
136         /* create a new bus */
137         snprintf(bus_make.name, sizeof(bus_make.name), "%u-%s-1", uid, name);
138         bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1;
139         bus_make.cmd.size = sizeof(struct kdbus_cmd) +
140                             sizeof(bus_make.bs) + bus_make.n_size;
141         ret = kdbus_cmd_bus_make(env->control_fd, &bus_make.cmd);
142         ASSERT_RETURN(ret == 0);
143
144         ret = kdbus_cmd_bus_make(control_fd2, &bus_make.cmd);
145         ASSERT_RETURN(ret == -EEXIST);
146
147         snprintf(s, sizeof(s), "%s/%u-%s-1/bus", env->root, uid, name);
148         ASSERT_RETURN(access(s, F_OK) == 0);
149
150         ret = test_bus_creator_info(s);
151         ASSERT_RETURN(ret == 0);
152
153         /* can't use the same fd for bus make twice, even though a different
154          * bus name is used
155          */
156         snprintf(bus_make.name, sizeof(bus_make.name), "%u-%s-2", uid, name);
157         bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1;
158         bus_make.cmd.size = sizeof(struct kdbus_cmd) +
159                             sizeof(bus_make.bs) + bus_make.n_size;
160         ret = kdbus_cmd_bus_make(env->control_fd, &bus_make.cmd);
161         ASSERT_RETURN(ret == -EBADFD);
162
163         /* create a new bus, with different fd and different bus name */
164         snprintf(bus_make.name, sizeof(bus_make.name), "%u-%s-2", uid, name);
165         bus_make.n_size = KDBUS_ITEM_HEADER_SIZE + strlen(bus_make.name) + 1;
166         bus_make.cmd.size = sizeof(struct kdbus_cmd) +
167                             sizeof(bus_make.bs) + bus_make.n_size;
168         ret = kdbus_cmd_bus_make(control_fd2, &bus_make.cmd);
169         ASSERT_RETURN(ret == 0);
170
171         close(control_fd2);
172         free(name);
173
174         return TEST_OK;
175 }