]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-socket-netlink.c
Merge pull request #16682 from poettering/userdb-gecos-fix
[thirdparty/systemd.git] / src / test / test-socket-netlink.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #include "alloc-util.h"
4 #include "tests.h"
5 #include "socket-netlink.h"
6 #include "string-util.h"
7
8 static void test_socket_address_parse_one(const char *in, int ret, int family, const char *expected) {
9 SocketAddress a;
10 _cleanup_free_ char *out = NULL;
11 int r;
12
13 r = socket_address_parse(&a, in);
14 if (r >= 0)
15 assert_se(socket_address_print(&a, &out) >= 0);
16
17 log_info("\"%s\" → %s → \"%s\" (expect \"%s\")", in,
18 r >= 0 ? "✓" : "✗", empty_to_dash(out), r >= 0 ? expected ?: in : "-");
19 assert_se(r == ret);
20 if (r >= 0) {
21 assert_se(a.sockaddr.sa.sa_family == family);
22 assert_se(streq(out, expected ?: in));
23 }
24 }
25
26 static void test_socket_address_parse(void) {
27 log_info("/* %s */", __func__);
28
29 test_socket_address_parse_one("junk", -EINVAL, 0, NULL);
30 test_socket_address_parse_one("192.168.1.1", -EINVAL, 0, NULL);
31 test_socket_address_parse_one(".168.1.1", -EINVAL, 0, NULL);
32 test_socket_address_parse_one("989.168.1.1", -EINVAL, 0, NULL);
33 test_socket_address_parse_one("192.168.1.1:65536", -ERANGE, 0, NULL);
34 test_socket_address_parse_one("192.168.1.1:0", -EINVAL, 0, NULL);
35 test_socket_address_parse_one("0", -EINVAL, 0, NULL);
36 test_socket_address_parse_one("65536", -ERANGE, 0, NULL);
37
38 const int default_family = socket_ipv6_is_supported() ? AF_INET6 : AF_INET;
39
40 test_socket_address_parse_one("65535", 0, default_family, "[::]:65535");
41
42 /* The checks below will pass even if ipv6 is disabled in
43 * kernel. The underlying glibc's inet_pton() is just a string
44 * parser and doesn't make any syscalls. */
45
46 test_socket_address_parse_one("[::1]", -EINVAL, 0, NULL);
47 test_socket_address_parse_one("[::1]8888", -EINVAL, 0, NULL);
48 test_socket_address_parse_one("::1", -EINVAL, 0, NULL);
49 test_socket_address_parse_one("[::1]:0", -EINVAL, 0, NULL);
50 test_socket_address_parse_one("[::1]:65536", -ERANGE, 0, NULL);
51 test_socket_address_parse_one("[a:b:1]:8888", -EINVAL, 0, NULL);
52
53 test_socket_address_parse_one("8888", 0, default_family, "[::]:8888");
54 test_socket_address_parse_one("[2001:0db8:0000:85a3:0000:0000:ac1f:8001]:8888", 0, AF_INET6,
55 "[2001:db8:0:85a3::ac1f:8001]:8888");
56 test_socket_address_parse_one("[::1]:8888", 0, AF_INET6, NULL);
57 test_socket_address_parse_one("192.168.1.254:8888", 0, AF_INET, NULL);
58 test_socket_address_parse_one("/foo/bar", 0, AF_UNIX, NULL);
59 test_socket_address_parse_one("/", 0, AF_UNIX, NULL);
60 test_socket_address_parse_one("@abstract", 0, AF_UNIX, NULL);
61
62 {
63 char aaa[SUN_PATH_LEN + 1] = "@";
64
65 memset(aaa + 1, 'a', SUN_PATH_LEN - 1);
66 char_array_0(aaa);
67
68 test_socket_address_parse_one(aaa, -EINVAL, 0, NULL);
69
70 aaa[SUN_PATH_LEN - 1] = '\0';
71 test_socket_address_parse_one(aaa, 0, AF_UNIX, NULL);
72 }
73
74 test_socket_address_parse_one("vsock:2:1234", 0, AF_VSOCK, NULL);
75 test_socket_address_parse_one("vsock::1234", 0, AF_VSOCK, NULL);
76 test_socket_address_parse_one("vsock:2:1234x", -EINVAL, 0, NULL);
77 test_socket_address_parse_one("vsock:2x:1234", -EINVAL, 0, NULL);
78 test_socket_address_parse_one("vsock:2", -EINVAL, 0, NULL);
79 }
80
81 static void test_socket_address_parse_netlink(void) {
82 SocketAddress a;
83
84 log_info("/* %s */", __func__);
85
86 assert_se(socket_address_parse_netlink(&a, "junk") < 0);
87 assert_se(socket_address_parse_netlink(&a, "") < 0);
88
89 assert_se(socket_address_parse_netlink(&a, "route") >= 0);
90 assert_se(a.sockaddr.nl.nl_family == AF_NETLINK);
91 assert_se(a.sockaddr.nl.nl_groups == 0);
92 assert_se(a.protocol == NETLINK_ROUTE);
93 assert_se(socket_address_parse_netlink(&a, "route") >= 0);
94 assert_se(socket_address_parse_netlink(&a, "route 10") >= 0);
95 assert_se(a.sockaddr.nl.nl_family == AF_NETLINK);
96 assert_se(a.sockaddr.nl.nl_groups == 10);
97 assert_se(a.protocol == NETLINK_ROUTE);
98
99 /* With spaces and tabs */
100 assert_se(socket_address_parse_netlink(&a, " kobject-uevent ") >= 0);
101 assert_se(a.sockaddr.nl.nl_family == AF_NETLINK);
102 assert_se(a.sockaddr.nl.nl_groups == 0);
103 assert_se(a.protocol == NETLINK_KOBJECT_UEVENT);
104 assert_se(socket_address_parse_netlink(&a, " \t kobject-uevent \t 10") >= 0);
105 assert_se(a.sockaddr.nl.nl_family == AF_NETLINK);
106 assert_se(a.sockaddr.nl.nl_groups == 10);
107 assert_se(a.protocol == NETLINK_KOBJECT_UEVENT);
108 assert_se(socket_address_parse_netlink(&a, "kobject-uevent\t10") >= 0);
109 assert_se(a.sockaddr.nl.nl_family == AF_NETLINK);
110 assert_se(a.sockaddr.nl.nl_groups == 10);
111 assert_se(a.protocol == NETLINK_KOBJECT_UEVENT);
112
113 /* trailing space is not supported */
114 assert_se(socket_address_parse_netlink(&a, "kobject-uevent\t10 ") < 0);
115
116 /* Group must be unsigned */
117 assert_se(socket_address_parse_netlink(&a, "kobject-uevent -1") < 0);
118
119 /* oss-fuzz #6884 */
120 assert_se(socket_address_parse_netlink(&a, "\xff") < 0);
121 }
122
123 static void test_socket_address_equal(void) {
124 SocketAddress a, b;
125
126 log_info("/* %s */", __func__);
127
128 assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
129 assert_se(socket_address_parse(&b, "192.168.1.1:888") >= 0);
130 assert_se(!socket_address_equal(&a, &b));
131
132 assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
133 assert_se(socket_address_parse(&b, "192.16.1.1:8888") >= 0);
134 assert_se(!socket_address_equal(&a, &b));
135
136 assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
137 assert_se(socket_address_parse(&b, "8888") >= 0);
138 assert_se(!socket_address_equal(&a, &b));
139
140 assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
141 assert_se(socket_address_parse(&b, "/foo/bar/") >= 0);
142 assert_se(!socket_address_equal(&a, &b));
143
144 assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
145 assert_se(socket_address_parse(&b, "192.168.1.1:8888") >= 0);
146 assert_se(socket_address_equal(&a, &b));
147
148 assert_se(socket_address_parse(&a, "/foo/bar") >= 0);
149 assert_se(socket_address_parse(&b, "/foo/bar") >= 0);
150 assert_se(socket_address_equal(&a, &b));
151
152 assert_se(socket_address_parse(&a, "[::1]:8888") >= 0);
153 assert_se(socket_address_parse(&b, "[::1]:8888") >= 0);
154 assert_se(socket_address_equal(&a, &b));
155
156 assert_se(socket_address_parse(&a, "@abstract") >= 0);
157 assert_se(socket_address_parse(&b, "@abstract") >= 0);
158 assert_se(socket_address_equal(&a, &b));
159
160 assert_se(socket_address_parse_netlink(&a, "firewall") >= 0);
161 assert_se(socket_address_parse_netlink(&b, "firewall") >= 0);
162 assert_se(socket_address_equal(&a, &b));
163
164 assert_se(socket_address_parse(&a, "vsock:2:1234") >= 0);
165 assert_se(socket_address_parse(&b, "vsock:2:1234") >= 0);
166 assert_se(socket_address_equal(&a, &b));
167 assert_se(socket_address_parse(&b, "vsock:2:1235") >= 0);
168 assert_se(!socket_address_equal(&a, &b));
169 assert_se(socket_address_parse(&b, "vsock:3:1234") >= 0);
170 assert_se(!socket_address_equal(&a, &b));
171 }
172
173 static void test_socket_address_get_path(void) {
174 SocketAddress a;
175
176 log_info("/* %s */", __func__);
177
178 assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
179 assert_se(!socket_address_get_path(&a));
180
181 assert_se(socket_address_parse(&a, "@abstract") >= 0);
182 assert_se(!socket_address_get_path(&a));
183
184 assert_se(socket_address_parse(&a, "[::1]:8888") >= 0);
185 assert_se(!socket_address_get_path(&a));
186
187 assert_se(socket_address_parse(&a, "/foo/bar") >= 0);
188 assert_se(streq(socket_address_get_path(&a), "/foo/bar"));
189
190 assert_se(socket_address_parse(&a, "vsock:2:1234") >= 0);
191 assert_se(!socket_address_get_path(&a));
192 }
193
194 static void test_socket_address_is(void) {
195 SocketAddress a;
196
197 log_info("/* %s */", __func__);
198
199 assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
200 assert_se(socket_address_is(&a, "192.168.1.1:8888", SOCK_STREAM));
201 assert_se(!socket_address_is(&a, "route", SOCK_STREAM));
202 assert_se(!socket_address_is(&a, "192.168.1.1:8888", SOCK_RAW));
203 }
204
205 static void test_socket_address_is_netlink(void) {
206 SocketAddress a;
207
208 log_info("/* %s */", __func__);
209
210 assert_se(socket_address_parse_netlink(&a, "route 10") >= 0);
211 assert_se(socket_address_is_netlink(&a, "route 10"));
212 assert_se(!socket_address_is_netlink(&a, "192.168.1.1:8888"));
213 assert_se(!socket_address_is_netlink(&a, "route 1"));
214 }
215
216 int main(int argc, char *argv[]) {
217 test_setup_logging(LOG_DEBUG);
218
219 test_socket_address_parse();
220 test_socket_address_parse_netlink();
221 test_socket_address_equal();
222 test_socket_address_get_path();
223 test_socket_address_is();
224 test_socket_address_is_netlink();
225
226 return 0;
227 }