xref: /linux/tools/testing/selftests/landlock/net_test.c (revision c0d35086a21b8d5536da5029fd76b9aeecf3217d)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Landlock tests - Network
4  *
5  * Copyright © 2022-2023 Huawei Tech. Co., Ltd.
6  * Copyright © 2023 Microsoft Corporation
7  */
8 
9 #define _GNU_SOURCE
10 #include <arpa/inet.h>
11 #include <errno.h>
12 #include <fcntl.h>
13 #include <linux/landlock.h>
14 #include <linux/in.h>
15 #include <sched.h>
16 #include <stdint.h>
17 #include <string.h>
18 #include <sys/prctl.h>
19 #include <sys/socket.h>
20 #include <sys/syscall.h>
21 #include <sys/un.h>
22 
23 #include "common.h"
24 
25 const short sock_port_start = (1 << 10);
26 
27 static const char loopback_ipv4[] = "127.0.0.1";
28 static const char loopback_ipv6[] = "::1";
29 
30 /* Number pending connections queue to be hold. */
31 const short backlog = 10;
32 
33 enum sandbox_type {
34 	NO_SANDBOX,
35 	/* This may be used to test rules that allow *and* deny accesses. */
36 	TCP_SANDBOX,
37 };
38 
set_service(struct service_fixture * const srv,const struct protocol_variant prot,const unsigned short index)39 static int set_service(struct service_fixture *const srv,
40 		       const struct protocol_variant prot,
41 		       const unsigned short index)
42 {
43 	memset(srv, 0, sizeof(*srv));
44 
45 	/*
46 	 * Copies all protocol properties in case of the variant only contains
47 	 * a subset of them.
48 	 */
49 	srv->protocol = prot;
50 
51 	/* Checks for port overflow. */
52 	if (index > 2)
53 		return 1;
54 	srv->port = sock_port_start << (2 * index);
55 
56 	switch (prot.domain) {
57 	case AF_UNSPEC:
58 	case AF_INET:
59 		srv->ipv4_addr.sin_family = prot.domain;
60 		srv->ipv4_addr.sin_port = htons(srv->port);
61 		srv->ipv4_addr.sin_addr.s_addr = inet_addr(loopback_ipv4);
62 		return 0;
63 
64 	case AF_INET6:
65 		srv->ipv6_addr.sin6_family = prot.domain;
66 		srv->ipv6_addr.sin6_port = htons(srv->port);
67 		inet_pton(AF_INET6, loopback_ipv6, &srv->ipv6_addr.sin6_addr);
68 		return 0;
69 
70 	case AF_UNIX:
71 		set_unix_address(srv, index);
72 		return 0;
73 	}
74 	return 1;
75 }
76 
setup_loopback(struct __test_metadata * const _metadata)77 static void setup_loopback(struct __test_metadata *const _metadata)
78 {
79 	set_cap(_metadata, CAP_SYS_ADMIN);
80 	ASSERT_EQ(0, unshare(CLONE_NEWNET));
81 	clear_cap(_metadata, CAP_SYS_ADMIN);
82 
83 	set_ambient_cap(_metadata, CAP_NET_ADMIN);
84 	ASSERT_EQ(0, system("ip link set dev lo up"));
85 	clear_ambient_cap(_metadata, CAP_NET_ADMIN);
86 }
87 
prot_is_tcp(const struct protocol_variant * const prot)88 static bool prot_is_tcp(const struct protocol_variant *const prot)
89 {
90 	return (prot->domain == AF_INET || prot->domain == AF_INET6) &&
91 	       prot->type == SOCK_STREAM &&
92 	       (prot->protocol == IPPROTO_TCP || prot->protocol == IPPROTO_IP);
93 }
94 
is_restricted(const struct protocol_variant * const prot,const enum sandbox_type sandbox)95 static bool is_restricted(const struct protocol_variant *const prot,
96 			  const enum sandbox_type sandbox)
97 {
98 	if (sandbox == TCP_SANDBOX)
99 		return prot_is_tcp(prot);
100 	return false;
101 }
102 
socket_variant(const struct service_fixture * const srv)103 static int socket_variant(const struct service_fixture *const srv)
104 {
105 	int ret;
106 
107 	ret = socket(srv->protocol.domain, srv->protocol.type | SOCK_CLOEXEC,
108 		     srv->protocol.protocol);
109 	if (ret < 0)
110 		return -errno;
111 	return ret;
112 }
113 
114 #ifndef SIN6_LEN_RFC2133
115 #define SIN6_LEN_RFC2133 24
116 #endif
117 
get_addrlen(const struct service_fixture * const srv,const bool minimal)118 static socklen_t get_addrlen(const struct service_fixture *const srv,
119 			     const bool minimal)
120 {
121 	switch (srv->protocol.domain) {
122 	case AF_UNSPEC:
123 	case AF_INET:
124 		return sizeof(srv->ipv4_addr);
125 
126 	case AF_INET6:
127 		if (minimal)
128 			return SIN6_LEN_RFC2133;
129 		return sizeof(srv->ipv6_addr);
130 
131 	case AF_UNIX:
132 		if (minimal)
133 			return sizeof(srv->unix_addr) -
134 			       sizeof(srv->unix_addr.sun_path);
135 		return srv->unix_addr_len;
136 
137 	default:
138 		return 0;
139 	}
140 }
141 
set_port(struct service_fixture * const srv,uint16_t port)142 static void set_port(struct service_fixture *const srv, uint16_t port)
143 {
144 	switch (srv->protocol.domain) {
145 	case AF_UNSPEC:
146 	case AF_INET:
147 		srv->ipv4_addr.sin_port = htons(port);
148 		return;
149 
150 	case AF_INET6:
151 		srv->ipv6_addr.sin6_port = htons(port);
152 		return;
153 
154 	default:
155 		return;
156 	}
157 }
158 
get_binded_port(int socket_fd,const struct protocol_variant * const prot)159 static uint16_t get_binded_port(int socket_fd,
160 				const struct protocol_variant *const prot)
161 {
162 	struct sockaddr_in ipv4_addr;
163 	struct sockaddr_in6 ipv6_addr;
164 	socklen_t ipv4_addr_len, ipv6_addr_len;
165 
166 	/* Gets binded port. */
167 	switch (prot->domain) {
168 	case AF_UNSPEC:
169 	case AF_INET:
170 		ipv4_addr_len = sizeof(ipv4_addr);
171 		getsockname(socket_fd, &ipv4_addr, &ipv4_addr_len);
172 		return ntohs(ipv4_addr.sin_port);
173 
174 	case AF_INET6:
175 		ipv6_addr_len = sizeof(ipv6_addr);
176 		getsockname(socket_fd, &ipv6_addr, &ipv6_addr_len);
177 		return ntohs(ipv6_addr.sin6_port);
178 
179 	default:
180 		return 0;
181 	}
182 }
183 
bind_variant_addrlen(const int sock_fd,const struct service_fixture * const srv,const socklen_t addrlen)184 static int bind_variant_addrlen(const int sock_fd,
185 				const struct service_fixture *const srv,
186 				const socklen_t addrlen)
187 {
188 	int ret;
189 
190 	switch (srv->protocol.domain) {
191 	case AF_UNSPEC:
192 	case AF_INET:
193 		ret = bind(sock_fd, &srv->ipv4_addr, addrlen);
194 		break;
195 
196 	case AF_INET6:
197 		ret = bind(sock_fd, &srv->ipv6_addr, addrlen);
198 		break;
199 
200 	case AF_UNIX:
201 		ret = bind(sock_fd, &srv->unix_addr, addrlen);
202 		break;
203 
204 	default:
205 		errno = EAFNOSUPPORT;
206 		return -errno;
207 	}
208 
209 	if (ret < 0)
210 		return -errno;
211 	return ret;
212 }
213 
bind_variant(const int sock_fd,const struct service_fixture * const srv)214 static int bind_variant(const int sock_fd,
215 			const struct service_fixture *const srv)
216 {
217 	return bind_variant_addrlen(sock_fd, srv, get_addrlen(srv, false));
218 }
219 
connect_variant_addrlen(const int sock_fd,const struct service_fixture * const srv,const socklen_t addrlen)220 static int connect_variant_addrlen(const int sock_fd,
221 				   const struct service_fixture *const srv,
222 				   const socklen_t addrlen)
223 {
224 	int ret;
225 
226 	switch (srv->protocol.domain) {
227 	case AF_UNSPEC:
228 	case AF_INET:
229 		ret = connect(sock_fd, &srv->ipv4_addr, addrlen);
230 		break;
231 
232 	case AF_INET6:
233 		ret = connect(sock_fd, &srv->ipv6_addr, addrlen);
234 		break;
235 
236 	case AF_UNIX:
237 		ret = connect(sock_fd, &srv->unix_addr, addrlen);
238 		break;
239 
240 	default:
241 		errno = -EAFNOSUPPORT;
242 		return -errno;
243 	}
244 
245 	if (ret < 0)
246 		return -errno;
247 	return ret;
248 }
249 
connect_variant(const int sock_fd,const struct service_fixture * const srv)250 static int connect_variant(const int sock_fd,
251 			   const struct service_fixture *const srv)
252 {
253 	return connect_variant_addrlen(sock_fd, srv, get_addrlen(srv, false));
254 }
255 
FIXTURE(protocol)256 FIXTURE(protocol)
257 {
258 	struct service_fixture srv0, srv1, srv2, unspec_any0, unspec_srv0;
259 };
260 
FIXTURE_VARIANT(protocol)261 FIXTURE_VARIANT(protocol)
262 {
263 	const enum sandbox_type sandbox;
264 	const struct protocol_variant prot;
265 };
266 
FIXTURE_SETUP(protocol)267 FIXTURE_SETUP(protocol)
268 {
269 	const struct protocol_variant prot_unspec = {
270 		.domain = AF_UNSPEC,
271 		.type = SOCK_STREAM,
272 	};
273 
274 	disable_caps(_metadata);
275 
276 	ASSERT_EQ(0, set_service(&self->srv0, variant->prot, 0));
277 	ASSERT_EQ(0, set_service(&self->srv1, variant->prot, 1));
278 	ASSERT_EQ(0, set_service(&self->srv2, variant->prot, 2));
279 
280 	ASSERT_EQ(0, set_service(&self->unspec_srv0, prot_unspec, 0));
281 
282 	ASSERT_EQ(0, set_service(&self->unspec_any0, prot_unspec, 0));
283 	self->unspec_any0.ipv4_addr.sin_addr.s_addr = htonl(INADDR_ANY);
284 
285 	setup_loopback(_metadata);
286 };
287 
FIXTURE_TEARDOWN(protocol)288 FIXTURE_TEARDOWN(protocol)
289 {
290 }
291 
292 /* clang-format off */
FIXTURE_VARIANT_ADD(protocol,no_sandbox_with_ipv4_tcp1)293 FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv4_tcp1) {
294 	/* clang-format on */
295 	.sandbox = NO_SANDBOX,
296 	.prot = {
297 		.domain = AF_INET,
298 		.type = SOCK_STREAM,
299 		/* IPPROTO_IP == 0 */
300 		.protocol = IPPROTO_IP,
301 	},
302 };
303 
304 /* clang-format off */
FIXTURE_VARIANT_ADD(protocol,no_sandbox_with_ipv4_tcp2)305 FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv4_tcp2) {
306 	/* clang-format on */
307 	.sandbox = NO_SANDBOX,
308 	.prot = {
309 		.domain = AF_INET,
310 		.type = SOCK_STREAM,
311 		.protocol = IPPROTO_TCP,
312 	},
313 };
314 
315 /* clang-format off */
FIXTURE_VARIANT_ADD(protocol,no_sandbox_with_ipv4_mptcp)316 FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv4_mptcp) {
317 	/* clang-format on */
318 	.sandbox = NO_SANDBOX,
319 	.prot = {
320 		.domain = AF_INET,
321 		.type = SOCK_STREAM,
322 		.protocol = IPPROTO_MPTCP,
323 	},
324 };
325 
326 /* clang-format off */
FIXTURE_VARIANT_ADD(protocol,no_sandbox_with_ipv6_tcp1)327 FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv6_tcp1) {
328 	/* clang-format on */
329 	.sandbox = NO_SANDBOX,
330 	.prot = {
331 		.domain = AF_INET6,
332 		.type = SOCK_STREAM,
333 		/* IPPROTO_IP == 0 */
334 		.protocol = IPPROTO_IP,
335 	},
336 };
337 
338 /* clang-format off */
FIXTURE_VARIANT_ADD(protocol,no_sandbox_with_ipv6_tcp2)339 FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv6_tcp2) {
340 	/* clang-format on */
341 	.sandbox = NO_SANDBOX,
342 	.prot = {
343 		.domain = AF_INET6,
344 		.type = SOCK_STREAM,
345 		.protocol = IPPROTO_TCP,
346 	},
347 };
348 
349 /* clang-format off */
FIXTURE_VARIANT_ADD(protocol,no_sandbox_with_ipv6_mptcp)350 FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv6_mptcp) {
351 	/* clang-format on */
352 	.sandbox = NO_SANDBOX,
353 	.prot = {
354 		.domain = AF_INET6,
355 		.type = SOCK_STREAM,
356 		.protocol = IPPROTO_MPTCP,
357 	},
358 };
359 
360 /* clang-format off */
FIXTURE_VARIANT_ADD(protocol,no_sandbox_with_ipv4_udp)361 FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv4_udp) {
362 	/* clang-format on */
363 	.sandbox = NO_SANDBOX,
364 	.prot = {
365 		.domain = AF_INET,
366 		.type = SOCK_DGRAM,
367 	},
368 };
369 
370 /* clang-format off */
FIXTURE_VARIANT_ADD(protocol,no_sandbox_with_ipv6_udp)371 FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv6_udp) {
372 	/* clang-format on */
373 	.sandbox = NO_SANDBOX,
374 	.prot = {
375 		.domain = AF_INET6,
376 		.type = SOCK_DGRAM,
377 	},
378 };
379 
380 /* clang-format off */
FIXTURE_VARIANT_ADD(protocol,no_sandbox_with_unix_stream)381 FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_unix_stream) {
382 	/* clang-format on */
383 	.sandbox = NO_SANDBOX,
384 	.prot = {
385 		.domain = AF_UNIX,
386 		.type = SOCK_STREAM,
387 	},
388 };
389 
390 /* clang-format off */
FIXTURE_VARIANT_ADD(protocol,no_sandbox_with_unix_datagram)391 FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_unix_datagram) {
392 	/* clang-format on */
393 	.sandbox = NO_SANDBOX,
394 	.prot = {
395 		.domain = AF_UNIX,
396 		.type = SOCK_DGRAM,
397 	},
398 };
399 
400 /* clang-format off */
FIXTURE_VARIANT_ADD(protocol,tcp_sandbox_with_ipv4_tcp1)401 FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv4_tcp1) {
402 	/* clang-format on */
403 	.sandbox = TCP_SANDBOX,
404 	.prot = {
405 		.domain = AF_INET,
406 		.type = SOCK_STREAM,
407 		/* IPPROTO_IP == 0 */
408 		.protocol = IPPROTO_IP,
409 	},
410 };
411 
412 /* clang-format off */
FIXTURE_VARIANT_ADD(protocol,tcp_sandbox_with_ipv4_tcp2)413 FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv4_tcp2) {
414 	/* clang-format on */
415 	.sandbox = TCP_SANDBOX,
416 	.prot = {
417 		.domain = AF_INET,
418 		.type = SOCK_STREAM,
419 		.protocol = IPPROTO_TCP,
420 	},
421 };
422 
423 /* clang-format off */
FIXTURE_VARIANT_ADD(protocol,tcp_sandbox_with_ipv4_mptcp)424 FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv4_mptcp) {
425 	/* clang-format on */
426 	.sandbox = TCP_SANDBOX,
427 	.prot = {
428 		.domain = AF_INET,
429 		.type = SOCK_STREAM,
430 		.protocol = IPPROTO_MPTCP,
431 	},
432 };
433 
434 /* clang-format off */
FIXTURE_VARIANT_ADD(protocol,tcp_sandbox_with_ipv6_tcp1)435 FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv6_tcp1) {
436 	/* clang-format on */
437 	.sandbox = TCP_SANDBOX,
438 	.prot = {
439 		.domain = AF_INET6,
440 		.type = SOCK_STREAM,
441 		/* IPPROTO_IP == 0 */
442 		.protocol = IPPROTO_IP,
443 	},
444 };
445 
446 /* clang-format off */
FIXTURE_VARIANT_ADD(protocol,tcp_sandbox_with_ipv6_tcp2)447 FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv6_tcp2) {
448 	/* clang-format on */
449 	.sandbox = TCP_SANDBOX,
450 	.prot = {
451 		.domain = AF_INET6,
452 		.type = SOCK_STREAM,
453 		.protocol = IPPROTO_TCP,
454 	},
455 };
456 
457 /* clang-format off */
FIXTURE_VARIANT_ADD(protocol,tcp_sandbox_with_ipv6_mptcp)458 FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv6_mptcp) {
459 	/* clang-format on */
460 	.sandbox = TCP_SANDBOX,
461 	.prot = {
462 		.domain = AF_INET6,
463 		.type = SOCK_STREAM,
464 		.protocol = IPPROTO_MPTCP,
465 	},
466 };
467 
468 /* clang-format off */
FIXTURE_VARIANT_ADD(protocol,tcp_sandbox_with_ipv4_udp)469 FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv4_udp) {
470 	/* clang-format on */
471 	.sandbox = TCP_SANDBOX,
472 	.prot = {
473 		.domain = AF_INET,
474 		.type = SOCK_DGRAM,
475 	},
476 };
477 
478 /* clang-format off */
FIXTURE_VARIANT_ADD(protocol,tcp_sandbox_with_ipv6_udp)479 FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv6_udp) {
480 	/* clang-format on */
481 	.sandbox = TCP_SANDBOX,
482 	.prot = {
483 		.domain = AF_INET6,
484 		.type = SOCK_DGRAM,
485 	},
486 };
487 
488 /* clang-format off */
FIXTURE_VARIANT_ADD(protocol,tcp_sandbox_with_unix_stream)489 FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_unix_stream) {
490 	/* clang-format on */
491 	.sandbox = TCP_SANDBOX,
492 	.prot = {
493 		.domain = AF_UNIX,
494 		.type = SOCK_STREAM,
495 	},
496 };
497 
498 /* clang-format off */
FIXTURE_VARIANT_ADD(protocol,tcp_sandbox_with_unix_datagram)499 FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_unix_datagram) {
500 	/* clang-format on */
501 	.sandbox = TCP_SANDBOX,
502 	.prot = {
503 		.domain = AF_UNIX,
504 		.type = SOCK_DGRAM,
505 	},
506 };
507 
test_bind_and_connect(struct __test_metadata * const _metadata,const struct service_fixture * const srv,const bool deny_bind,const bool deny_connect)508 static void test_bind_and_connect(struct __test_metadata *const _metadata,
509 				  const struct service_fixture *const srv,
510 				  const bool deny_bind, const bool deny_connect)
511 {
512 	char buf = '\0';
513 	int inval_fd, bind_fd, client_fd, status, ret;
514 	pid_t child;
515 
516 	/* Starts invalid addrlen tests with bind. */
517 	inval_fd = socket_variant(srv);
518 	ASSERT_LE(0, inval_fd)
519 	{
520 		TH_LOG("Failed to create socket: %s", strerror(errno));
521 	}
522 
523 	/* Tries to bind with zero as addrlen. */
524 	EXPECT_EQ(-EINVAL, bind_variant_addrlen(inval_fd, srv, 0));
525 
526 	/* Tries to bind with too small addrlen. */
527 	EXPECT_EQ(-EINVAL, bind_variant_addrlen(inval_fd, srv,
528 						get_addrlen(srv, true) - 1));
529 
530 	/* Tries to bind with minimal addrlen. */
531 	ret = bind_variant_addrlen(inval_fd, srv, get_addrlen(srv, true));
532 	if (deny_bind) {
533 		EXPECT_EQ(-EACCES, ret);
534 	} else {
535 		EXPECT_EQ(0, ret)
536 		{
537 			TH_LOG("Failed to bind to socket: %s", strerror(errno));
538 		}
539 	}
540 	EXPECT_EQ(0, close(inval_fd));
541 
542 	/* Starts invalid addrlen tests with connect. */
543 	inval_fd = socket_variant(srv);
544 	ASSERT_LE(0, inval_fd);
545 
546 	/* Tries to connect with zero as addrlen. */
547 	EXPECT_EQ(-EINVAL, connect_variant_addrlen(inval_fd, srv, 0));
548 
549 	/* Tries to connect with too small addrlen. */
550 	EXPECT_EQ(-EINVAL, connect_variant_addrlen(inval_fd, srv,
551 						   get_addrlen(srv, true) - 1));
552 
553 	/* Tries to connect with minimal addrlen. */
554 	ret = connect_variant_addrlen(inval_fd, srv, get_addrlen(srv, true));
555 	if (srv->protocol.domain == AF_UNIX) {
556 		EXPECT_EQ(-EINVAL, ret);
557 	} else if (deny_connect) {
558 		EXPECT_EQ(-EACCES, ret);
559 	} else if (srv->protocol.type == SOCK_STREAM) {
560 		/* No listening server, whatever the value of deny_bind. */
561 		EXPECT_EQ(-ECONNREFUSED, ret);
562 	} else {
563 		EXPECT_EQ(0, ret)
564 		{
565 			TH_LOG("Failed to connect to socket: %s",
566 			       strerror(errno));
567 		}
568 	}
569 	EXPECT_EQ(0, close(inval_fd));
570 
571 	/* Starts connection tests. */
572 	bind_fd = socket_variant(srv);
573 	ASSERT_LE(0, bind_fd);
574 
575 	ret = bind_variant(bind_fd, srv);
576 	if (deny_bind) {
577 		EXPECT_EQ(-EACCES, ret);
578 	} else {
579 		EXPECT_EQ(0, ret);
580 
581 		/* Creates a listening socket. */
582 		if (srv->protocol.type == SOCK_STREAM)
583 			EXPECT_EQ(0, listen(bind_fd, backlog));
584 	}
585 
586 	child = fork();
587 	ASSERT_LE(0, child);
588 	if (child == 0) {
589 		int connect_fd, ret;
590 
591 		/* Closes listening socket for the child. */
592 		EXPECT_EQ(0, close(bind_fd));
593 
594 		/* Starts connection tests. */
595 		connect_fd = socket_variant(srv);
596 		ASSERT_LE(0, connect_fd);
597 		ret = connect_variant(connect_fd, srv);
598 		if (deny_connect) {
599 			EXPECT_EQ(-EACCES, ret);
600 		} else if (deny_bind) {
601 			/* No listening server. */
602 			EXPECT_EQ(-ECONNREFUSED, ret);
603 		} else {
604 			EXPECT_EQ(0, ret);
605 			EXPECT_EQ(1, write(connect_fd, ".", 1));
606 		}
607 
608 		EXPECT_EQ(0, close(connect_fd));
609 		_exit(_metadata->exit_code);
610 		return;
611 	}
612 
613 	/* Accepts connection from the child. */
614 	client_fd = bind_fd;
615 	if (!deny_bind && !deny_connect) {
616 		if (srv->protocol.type == SOCK_STREAM) {
617 			client_fd = accept(bind_fd, NULL, 0);
618 			ASSERT_LE(0, client_fd);
619 		}
620 
621 		EXPECT_EQ(1, read(client_fd, &buf, 1));
622 		EXPECT_EQ('.', buf);
623 	}
624 
625 	EXPECT_EQ(child, waitpid(child, &status, 0));
626 	EXPECT_EQ(1, WIFEXITED(status));
627 	EXPECT_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
628 
629 	/* Closes connection, if any. */
630 	if (client_fd != bind_fd)
631 		EXPECT_LE(0, close(client_fd));
632 
633 	/* Closes listening socket. */
634 	EXPECT_EQ(0, close(bind_fd));
635 }
636 
TEST_F(protocol,bind)637 TEST_F(protocol, bind)
638 {
639 	if (variant->sandbox == TCP_SANDBOX) {
640 		const struct landlock_ruleset_attr ruleset_attr = {
641 			.handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP |
642 					      LANDLOCK_ACCESS_NET_CONNECT_TCP,
643 		};
644 		const struct landlock_net_port_attr tcp_bind_connect_p0 = {
645 			.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP |
646 					  LANDLOCK_ACCESS_NET_CONNECT_TCP,
647 			.port = self->srv0.port,
648 		};
649 		const struct landlock_net_port_attr tcp_connect_p1 = {
650 			.allowed_access = LANDLOCK_ACCESS_NET_CONNECT_TCP,
651 			.port = self->srv1.port,
652 		};
653 		int ruleset_fd;
654 
655 		ruleset_fd = landlock_create_ruleset(&ruleset_attr,
656 						     sizeof(ruleset_attr), 0);
657 		ASSERT_LE(0, ruleset_fd);
658 
659 		/* Allows connect and bind for the first port.  */
660 		ASSERT_EQ(0,
661 			  landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
662 					    &tcp_bind_connect_p0, 0));
663 
664 		/* Allows connect and denies bind for the second port. */
665 		ASSERT_EQ(0,
666 			  landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
667 					    &tcp_connect_p1, 0));
668 
669 		enforce_ruleset(_metadata, ruleset_fd);
670 		EXPECT_EQ(0, close(ruleset_fd));
671 	}
672 
673 	/* Binds a socket to the first port. */
674 	test_bind_and_connect(_metadata, &self->srv0, false, false);
675 
676 	/* Binds a socket to the second port. */
677 	test_bind_and_connect(_metadata, &self->srv1,
678 			      is_restricted(&variant->prot, variant->sandbox),
679 			      false);
680 
681 	/* Binds a socket to the third port. */
682 	test_bind_and_connect(_metadata, &self->srv2,
683 			      is_restricted(&variant->prot, variant->sandbox),
684 			      is_restricted(&variant->prot, variant->sandbox));
685 }
686 
TEST_F(protocol,connect)687 TEST_F(protocol, connect)
688 {
689 	if (variant->sandbox == TCP_SANDBOX) {
690 		const struct landlock_ruleset_attr ruleset_attr = {
691 			.handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP |
692 					      LANDLOCK_ACCESS_NET_CONNECT_TCP,
693 		};
694 		const struct landlock_net_port_attr tcp_bind_connect_p0 = {
695 			.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP |
696 					  LANDLOCK_ACCESS_NET_CONNECT_TCP,
697 			.port = self->srv0.port,
698 		};
699 		const struct landlock_net_port_attr tcp_bind_p1 = {
700 			.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP,
701 			.port = self->srv1.port,
702 		};
703 		int ruleset_fd;
704 
705 		ruleset_fd = landlock_create_ruleset(&ruleset_attr,
706 						     sizeof(ruleset_attr), 0);
707 		ASSERT_LE(0, ruleset_fd);
708 
709 		/* Allows connect and bind for the first port. */
710 		ASSERT_EQ(0,
711 			  landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
712 					    &tcp_bind_connect_p0, 0));
713 
714 		/* Allows bind and denies connect for the second port. */
715 		ASSERT_EQ(0,
716 			  landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
717 					    &tcp_bind_p1, 0));
718 
719 		enforce_ruleset(_metadata, ruleset_fd);
720 		EXPECT_EQ(0, close(ruleset_fd));
721 	}
722 
723 	test_bind_and_connect(_metadata, &self->srv0, false, false);
724 
725 	test_bind_and_connect(_metadata, &self->srv1, false,
726 			      is_restricted(&variant->prot, variant->sandbox));
727 
728 	test_bind_and_connect(_metadata, &self->srv2,
729 			      is_restricted(&variant->prot, variant->sandbox),
730 			      is_restricted(&variant->prot, variant->sandbox));
731 }
732 
TEST_F(protocol,bind_unspec)733 TEST_F(protocol, bind_unspec)
734 {
735 	const struct landlock_ruleset_attr ruleset_attr = {
736 		.handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP,
737 	};
738 	const struct landlock_net_port_attr tcp_bind = {
739 		.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP,
740 		.port = self->srv0.port,
741 	};
742 	int bind_fd, ret;
743 
744 	if (variant->sandbox == TCP_SANDBOX) {
745 		const int ruleset_fd = landlock_create_ruleset(
746 			&ruleset_attr, sizeof(ruleset_attr), 0);
747 		ASSERT_LE(0, ruleset_fd);
748 
749 		/* Allows bind. */
750 		ASSERT_EQ(0,
751 			  landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
752 					    &tcp_bind, 0));
753 		enforce_ruleset(_metadata, ruleset_fd);
754 		EXPECT_EQ(0, close(ruleset_fd));
755 	}
756 
757 	bind_fd = socket_variant(&self->srv0);
758 	ASSERT_LE(0, bind_fd);
759 
760 	/* Allowed bind on AF_UNSPEC/INADDR_ANY. */
761 	ret = bind_variant(bind_fd, &self->unspec_any0);
762 	if (variant->prot.domain == AF_INET) {
763 		EXPECT_EQ(0, ret)
764 		{
765 			TH_LOG("Failed to bind to unspec/any socket: %s",
766 			       strerror(errno));
767 		}
768 	} else {
769 		EXPECT_EQ(-EINVAL, ret);
770 	}
771 	EXPECT_EQ(0, close(bind_fd));
772 
773 	if (variant->sandbox == TCP_SANDBOX) {
774 		const int ruleset_fd = landlock_create_ruleset(
775 			&ruleset_attr, sizeof(ruleset_attr), 0);
776 		ASSERT_LE(0, ruleset_fd);
777 
778 		/* Denies bind. */
779 		enforce_ruleset(_metadata, ruleset_fd);
780 		EXPECT_EQ(0, close(ruleset_fd));
781 	}
782 
783 	bind_fd = socket_variant(&self->srv0);
784 	ASSERT_LE(0, bind_fd);
785 
786 	/* Denied bind on AF_UNSPEC/INADDR_ANY. */
787 	ret = bind_variant(bind_fd, &self->unspec_any0);
788 	if (variant->prot.domain == AF_INET) {
789 		if (is_restricted(&variant->prot, variant->sandbox)) {
790 			EXPECT_EQ(-EACCES, ret);
791 		} else {
792 			EXPECT_EQ(0, ret);
793 		}
794 	} else {
795 		EXPECT_EQ(-EINVAL, ret);
796 	}
797 	EXPECT_EQ(0, close(bind_fd));
798 
799 	/* Checks bind with AF_UNSPEC and the loopback address. */
800 	bind_fd = socket_variant(&self->srv0);
801 	ASSERT_LE(0, bind_fd);
802 	ret = bind_variant(bind_fd, &self->unspec_srv0);
803 	if (variant->prot.domain == AF_INET) {
804 		EXPECT_EQ(-EAFNOSUPPORT, ret);
805 	} else {
806 		EXPECT_EQ(-EINVAL, ret)
807 		{
808 			TH_LOG("Wrong bind error: %s", strerror(errno));
809 		}
810 	}
811 	EXPECT_EQ(0, close(bind_fd));
812 }
813 
TEST_F(protocol,connect_unspec)814 TEST_F(protocol, connect_unspec)
815 {
816 	const struct landlock_ruleset_attr ruleset_attr = {
817 		.handled_access_net = LANDLOCK_ACCESS_NET_CONNECT_TCP,
818 	};
819 	const struct landlock_net_port_attr tcp_connect = {
820 		.allowed_access = LANDLOCK_ACCESS_NET_CONNECT_TCP,
821 		.port = self->srv0.port,
822 	};
823 	int bind_fd, client_fd, status;
824 	pid_t child;
825 
826 	/* Specific connection tests. */
827 	bind_fd = socket_variant(&self->srv0);
828 	ASSERT_LE(0, bind_fd);
829 	EXPECT_EQ(0, bind_variant(bind_fd, &self->srv0));
830 	if (self->srv0.protocol.type == SOCK_STREAM)
831 		EXPECT_EQ(0, listen(bind_fd, backlog));
832 
833 	child = fork();
834 	ASSERT_LE(0, child);
835 	if (child == 0) {
836 		int connect_fd, ret;
837 
838 		/* Closes listening socket for the child. */
839 		EXPECT_EQ(0, close(bind_fd));
840 
841 		connect_fd = socket_variant(&self->srv0);
842 		ASSERT_LE(0, connect_fd);
843 		EXPECT_EQ(0, connect_variant(connect_fd, &self->srv0));
844 
845 		/* Tries to connect again, or set peer. */
846 		ret = connect_variant(connect_fd, &self->srv0);
847 		if (self->srv0.protocol.type == SOCK_STREAM) {
848 			EXPECT_EQ(-EISCONN, ret);
849 		} else {
850 			EXPECT_EQ(0, ret);
851 		}
852 
853 		if (variant->sandbox == TCP_SANDBOX) {
854 			const int ruleset_fd = landlock_create_ruleset(
855 				&ruleset_attr, sizeof(ruleset_attr), 0);
856 			ASSERT_LE(0, ruleset_fd);
857 
858 			/* Allows connect. */
859 			ASSERT_EQ(0, landlock_add_rule(ruleset_fd,
860 						       LANDLOCK_RULE_NET_PORT,
861 						       &tcp_connect, 0));
862 			enforce_ruleset(_metadata, ruleset_fd);
863 			EXPECT_EQ(0, close(ruleset_fd));
864 		}
865 
866 		/* Disconnects already connected socket, or set peer. */
867 		ret = connect_variant(connect_fd, &self->unspec_any0);
868 		if (self->srv0.protocol.domain == AF_UNIX &&
869 		    self->srv0.protocol.type == SOCK_STREAM) {
870 			EXPECT_EQ(-EINVAL, ret);
871 		} else {
872 			EXPECT_EQ(0, ret);
873 		}
874 
875 		/* Tries to reconnect, or set peer. */
876 		ret = connect_variant(connect_fd, &self->srv0);
877 		if (self->srv0.protocol.domain == AF_UNIX &&
878 		    self->srv0.protocol.type == SOCK_STREAM) {
879 			EXPECT_EQ(-EISCONN, ret);
880 		} else {
881 			EXPECT_EQ(0, ret);
882 		}
883 
884 		if (variant->sandbox == TCP_SANDBOX) {
885 			const int ruleset_fd = landlock_create_ruleset(
886 				&ruleset_attr, sizeof(ruleset_attr), 0);
887 			ASSERT_LE(0, ruleset_fd);
888 
889 			/* Denies connect. */
890 			enforce_ruleset(_metadata, ruleset_fd);
891 			EXPECT_EQ(0, close(ruleset_fd));
892 		}
893 
894 		ret = connect_variant(connect_fd, &self->unspec_any0);
895 		if (self->srv0.protocol.domain == AF_UNIX &&
896 		    self->srv0.protocol.type == SOCK_STREAM) {
897 			EXPECT_EQ(-EINVAL, ret);
898 		} else {
899 			/* Always allowed to disconnect. */
900 			EXPECT_EQ(0, ret);
901 		}
902 
903 		EXPECT_EQ(0, close(connect_fd));
904 		_exit(_metadata->exit_code);
905 		return;
906 	}
907 
908 	client_fd = bind_fd;
909 	if (self->srv0.protocol.type == SOCK_STREAM) {
910 		client_fd = accept(bind_fd, NULL, 0);
911 		ASSERT_LE(0, client_fd);
912 	}
913 
914 	EXPECT_EQ(child, waitpid(child, &status, 0));
915 	EXPECT_EQ(1, WIFEXITED(status));
916 	EXPECT_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
917 
918 	/* Closes connection, if any. */
919 	if (client_fd != bind_fd)
920 		EXPECT_LE(0, close(client_fd));
921 
922 	/* Closes listening socket. */
923 	EXPECT_EQ(0, close(bind_fd));
924 }
925 
FIXTURE(ipv4)926 FIXTURE(ipv4)
927 {
928 	struct service_fixture srv0, srv1;
929 };
930 
FIXTURE_VARIANT(ipv4)931 FIXTURE_VARIANT(ipv4)
932 {
933 	const enum sandbox_type sandbox;
934 	const int type;
935 };
936 
937 /* clang-format off */
FIXTURE_VARIANT_ADD(ipv4,no_sandbox_with_tcp)938 FIXTURE_VARIANT_ADD(ipv4, no_sandbox_with_tcp) {
939 	/* clang-format on */
940 	.sandbox = NO_SANDBOX,
941 	.type = SOCK_STREAM,
942 };
943 
944 /* clang-format off */
FIXTURE_VARIANT_ADD(ipv4,tcp_sandbox_with_tcp)945 FIXTURE_VARIANT_ADD(ipv4, tcp_sandbox_with_tcp) {
946 	/* clang-format on */
947 	.sandbox = TCP_SANDBOX,
948 	.type = SOCK_STREAM,
949 };
950 
951 /* clang-format off */
FIXTURE_VARIANT_ADD(ipv4,no_sandbox_with_udp)952 FIXTURE_VARIANT_ADD(ipv4, no_sandbox_with_udp) {
953 	/* clang-format on */
954 	.sandbox = NO_SANDBOX,
955 	.type = SOCK_DGRAM,
956 };
957 
958 /* clang-format off */
FIXTURE_VARIANT_ADD(ipv4,tcp_sandbox_with_udp)959 FIXTURE_VARIANT_ADD(ipv4, tcp_sandbox_with_udp) {
960 	/* clang-format on */
961 	.sandbox = TCP_SANDBOX,
962 	.type = SOCK_DGRAM,
963 };
964 
FIXTURE_SETUP(ipv4)965 FIXTURE_SETUP(ipv4)
966 {
967 	const struct protocol_variant prot = {
968 		.domain = AF_INET,
969 		.type = variant->type,
970 	};
971 
972 	disable_caps(_metadata);
973 
974 	set_service(&self->srv0, prot, 0);
975 	set_service(&self->srv1, prot, 1);
976 
977 	setup_loopback(_metadata);
978 };
979 
FIXTURE_TEARDOWN(ipv4)980 FIXTURE_TEARDOWN(ipv4)
981 {
982 }
983 
TEST_F(ipv4,from_unix_to_inet)984 TEST_F(ipv4, from_unix_to_inet)
985 {
986 	int unix_stream_fd, unix_dgram_fd;
987 
988 	if (variant->sandbox == TCP_SANDBOX) {
989 		const struct landlock_ruleset_attr ruleset_attr = {
990 			.handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP |
991 					      LANDLOCK_ACCESS_NET_CONNECT_TCP,
992 		};
993 		const struct landlock_net_port_attr tcp_bind_connect_p0 = {
994 			.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP |
995 					  LANDLOCK_ACCESS_NET_CONNECT_TCP,
996 			.port = self->srv0.port,
997 		};
998 		int ruleset_fd;
999 
1000 		/* Denies connect and bind to check errno value. */
1001 		ruleset_fd = landlock_create_ruleset(&ruleset_attr,
1002 						     sizeof(ruleset_attr), 0);
1003 		ASSERT_LE(0, ruleset_fd);
1004 
1005 		/* Allows connect and bind for srv0.  */
1006 		ASSERT_EQ(0,
1007 			  landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1008 					    &tcp_bind_connect_p0, 0));
1009 
1010 		enforce_ruleset(_metadata, ruleset_fd);
1011 		EXPECT_EQ(0, close(ruleset_fd));
1012 	}
1013 
1014 	unix_stream_fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
1015 	ASSERT_LE(0, unix_stream_fd);
1016 
1017 	unix_dgram_fd = socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1018 	ASSERT_LE(0, unix_dgram_fd);
1019 
1020 	/* Checks unix stream bind and connect for srv0. */
1021 	EXPECT_EQ(-EINVAL, bind_variant(unix_stream_fd, &self->srv0));
1022 	EXPECT_EQ(-EINVAL, connect_variant(unix_stream_fd, &self->srv0));
1023 
1024 	/* Checks unix stream bind and connect for srv1. */
1025 	EXPECT_EQ(-EINVAL, bind_variant(unix_stream_fd, &self->srv1))
1026 	{
1027 		TH_LOG("Wrong bind error: %s", strerror(errno));
1028 	}
1029 	EXPECT_EQ(-EINVAL, connect_variant(unix_stream_fd, &self->srv1));
1030 
1031 	/* Checks unix datagram bind and connect for srv0. */
1032 	EXPECT_EQ(-EINVAL, bind_variant(unix_dgram_fd, &self->srv0));
1033 	EXPECT_EQ(-EINVAL, connect_variant(unix_dgram_fd, &self->srv0));
1034 
1035 	/* Checks unix datagram bind and connect for srv1. */
1036 	EXPECT_EQ(-EINVAL, bind_variant(unix_dgram_fd, &self->srv1));
1037 	EXPECT_EQ(-EINVAL, connect_variant(unix_dgram_fd, &self->srv1));
1038 }
1039 
FIXTURE(tcp_layers)1040 FIXTURE(tcp_layers)
1041 {
1042 	struct service_fixture srv0, srv1;
1043 };
1044 
FIXTURE_VARIANT(tcp_layers)1045 FIXTURE_VARIANT(tcp_layers)
1046 {
1047 	const size_t num_layers;
1048 	const int domain;
1049 };
1050 
FIXTURE_SETUP(tcp_layers)1051 FIXTURE_SETUP(tcp_layers)
1052 {
1053 	const struct protocol_variant prot = {
1054 		.domain = variant->domain,
1055 		.type = SOCK_STREAM,
1056 	};
1057 
1058 	disable_caps(_metadata);
1059 
1060 	ASSERT_EQ(0, set_service(&self->srv0, prot, 0));
1061 	ASSERT_EQ(0, set_service(&self->srv1, prot, 1));
1062 
1063 	setup_loopback(_metadata);
1064 };
1065 
FIXTURE_TEARDOWN(tcp_layers)1066 FIXTURE_TEARDOWN(tcp_layers)
1067 {
1068 }
1069 
1070 /* clang-format off */
FIXTURE_VARIANT_ADD(tcp_layers,no_sandbox_with_ipv4)1071 FIXTURE_VARIANT_ADD(tcp_layers, no_sandbox_with_ipv4) {
1072 	/* clang-format on */
1073 	.domain = AF_INET,
1074 	.num_layers = 0,
1075 };
1076 
1077 /* clang-format off */
FIXTURE_VARIANT_ADD(tcp_layers,one_sandbox_with_ipv4)1078 FIXTURE_VARIANT_ADD(tcp_layers, one_sandbox_with_ipv4) {
1079 	/* clang-format on */
1080 	.domain = AF_INET,
1081 	.num_layers = 1,
1082 };
1083 
1084 /* clang-format off */
FIXTURE_VARIANT_ADD(tcp_layers,two_sandboxes_with_ipv4)1085 FIXTURE_VARIANT_ADD(tcp_layers, two_sandboxes_with_ipv4) {
1086 	/* clang-format on */
1087 	.domain = AF_INET,
1088 	.num_layers = 2,
1089 };
1090 
1091 /* clang-format off */
FIXTURE_VARIANT_ADD(tcp_layers,three_sandboxes_with_ipv4)1092 FIXTURE_VARIANT_ADD(tcp_layers, three_sandboxes_with_ipv4) {
1093 	/* clang-format on */
1094 	.domain = AF_INET,
1095 	.num_layers = 3,
1096 };
1097 
1098 /* clang-format off */
FIXTURE_VARIANT_ADD(tcp_layers,no_sandbox_with_ipv6)1099 FIXTURE_VARIANT_ADD(tcp_layers, no_sandbox_with_ipv6) {
1100 	/* clang-format on */
1101 	.domain = AF_INET6,
1102 	.num_layers = 0,
1103 };
1104 
1105 /* clang-format off */
FIXTURE_VARIANT_ADD(tcp_layers,one_sandbox_with_ipv6)1106 FIXTURE_VARIANT_ADD(tcp_layers, one_sandbox_with_ipv6) {
1107 	/* clang-format on */
1108 	.domain = AF_INET6,
1109 	.num_layers = 1,
1110 };
1111 
1112 /* clang-format off */
FIXTURE_VARIANT_ADD(tcp_layers,two_sandboxes_with_ipv6)1113 FIXTURE_VARIANT_ADD(tcp_layers, two_sandboxes_with_ipv6) {
1114 	/* clang-format on */
1115 	.domain = AF_INET6,
1116 	.num_layers = 2,
1117 };
1118 
1119 /* clang-format off */
FIXTURE_VARIANT_ADD(tcp_layers,three_sandboxes_with_ipv6)1120 FIXTURE_VARIANT_ADD(tcp_layers, three_sandboxes_with_ipv6) {
1121 	/* clang-format on */
1122 	.domain = AF_INET6,
1123 	.num_layers = 3,
1124 };
1125 
TEST_F(tcp_layers,ruleset_overlap)1126 TEST_F(tcp_layers, ruleset_overlap)
1127 {
1128 	const struct landlock_ruleset_attr ruleset_attr = {
1129 		.handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP |
1130 				      LANDLOCK_ACCESS_NET_CONNECT_TCP,
1131 	};
1132 	const struct landlock_net_port_attr tcp_bind = {
1133 		.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP,
1134 		.port = self->srv0.port,
1135 	};
1136 	const struct landlock_net_port_attr tcp_bind_connect = {
1137 		.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP |
1138 				  LANDLOCK_ACCESS_NET_CONNECT_TCP,
1139 		.port = self->srv0.port,
1140 	};
1141 
1142 	if (variant->num_layers >= 1) {
1143 		int ruleset_fd;
1144 
1145 		ruleset_fd = landlock_create_ruleset(&ruleset_attr,
1146 						     sizeof(ruleset_attr), 0);
1147 		ASSERT_LE(0, ruleset_fd);
1148 
1149 		/* Allows bind. */
1150 		ASSERT_EQ(0,
1151 			  landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1152 					    &tcp_bind, 0));
1153 		/* Also allows bind, but allows connect too. */
1154 		ASSERT_EQ(0,
1155 			  landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1156 					    &tcp_bind_connect, 0));
1157 		enforce_ruleset(_metadata, ruleset_fd);
1158 		EXPECT_EQ(0, close(ruleset_fd));
1159 	}
1160 
1161 	if (variant->num_layers >= 2) {
1162 		int ruleset_fd;
1163 
1164 		/* Creates another ruleset layer. */
1165 		ruleset_fd = landlock_create_ruleset(&ruleset_attr,
1166 						     sizeof(ruleset_attr), 0);
1167 		ASSERT_LE(0, ruleset_fd);
1168 
1169 		/* Only allows bind. */
1170 		ASSERT_EQ(0,
1171 			  landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1172 					    &tcp_bind, 0));
1173 		enforce_ruleset(_metadata, ruleset_fd);
1174 		EXPECT_EQ(0, close(ruleset_fd));
1175 	}
1176 
1177 	if (variant->num_layers >= 3) {
1178 		int ruleset_fd;
1179 
1180 		/* Creates another ruleset layer. */
1181 		ruleset_fd = landlock_create_ruleset(&ruleset_attr,
1182 						     sizeof(ruleset_attr), 0);
1183 		ASSERT_LE(0, ruleset_fd);
1184 
1185 		/* Try to allow bind and connect. */
1186 		ASSERT_EQ(0,
1187 			  landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1188 					    &tcp_bind_connect, 0));
1189 		enforce_ruleset(_metadata, ruleset_fd);
1190 		EXPECT_EQ(0, close(ruleset_fd));
1191 	}
1192 
1193 	/*
1194 	 * Forbids to connect to the socket because only one ruleset layer
1195 	 * allows connect.
1196 	 */
1197 	test_bind_and_connect(_metadata, &self->srv0, false,
1198 			      variant->num_layers >= 2);
1199 }
1200 
TEST_F(tcp_layers,ruleset_expand)1201 TEST_F(tcp_layers, ruleset_expand)
1202 {
1203 	if (variant->num_layers >= 1) {
1204 		const struct landlock_ruleset_attr ruleset_attr = {
1205 			.handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP,
1206 		};
1207 		/* Allows bind for srv0. */
1208 		const struct landlock_net_port_attr bind_srv0 = {
1209 			.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP,
1210 			.port = self->srv0.port,
1211 		};
1212 		int ruleset_fd;
1213 
1214 		ruleset_fd = landlock_create_ruleset(&ruleset_attr,
1215 						     sizeof(ruleset_attr), 0);
1216 		ASSERT_LE(0, ruleset_fd);
1217 		ASSERT_EQ(0,
1218 			  landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1219 					    &bind_srv0, 0));
1220 		enforce_ruleset(_metadata, ruleset_fd);
1221 		EXPECT_EQ(0, close(ruleset_fd));
1222 	}
1223 
1224 	if (variant->num_layers >= 2) {
1225 		/* Expands network mask with connect action. */
1226 		const struct landlock_ruleset_attr ruleset_attr = {
1227 			.handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP |
1228 					      LANDLOCK_ACCESS_NET_CONNECT_TCP,
1229 		};
1230 		/* Allows bind for srv0 and connect to srv0. */
1231 		const struct landlock_net_port_attr tcp_bind_connect_p0 = {
1232 			.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP |
1233 					  LANDLOCK_ACCESS_NET_CONNECT_TCP,
1234 			.port = self->srv0.port,
1235 		};
1236 		/* Try to allow bind for srv1. */
1237 		const struct landlock_net_port_attr tcp_bind_p1 = {
1238 			.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP,
1239 			.port = self->srv1.port,
1240 		};
1241 		int ruleset_fd;
1242 
1243 		ruleset_fd = landlock_create_ruleset(&ruleset_attr,
1244 						     sizeof(ruleset_attr), 0);
1245 		ASSERT_LE(0, ruleset_fd);
1246 		ASSERT_EQ(0,
1247 			  landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1248 					    &tcp_bind_connect_p0, 0));
1249 		ASSERT_EQ(0,
1250 			  landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1251 					    &tcp_bind_p1, 0));
1252 		enforce_ruleset(_metadata, ruleset_fd);
1253 		EXPECT_EQ(0, close(ruleset_fd));
1254 	}
1255 
1256 	if (variant->num_layers >= 3) {
1257 		const struct landlock_ruleset_attr ruleset_attr = {
1258 			.handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP |
1259 					      LANDLOCK_ACCESS_NET_CONNECT_TCP,
1260 		};
1261 		/* Allows connect to srv0, without bind rule. */
1262 		const struct landlock_net_port_attr tcp_bind_p0 = {
1263 			.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP,
1264 			.port = self->srv0.port,
1265 		};
1266 		int ruleset_fd;
1267 
1268 		ruleset_fd = landlock_create_ruleset(&ruleset_attr,
1269 						     sizeof(ruleset_attr), 0);
1270 		ASSERT_LE(0, ruleset_fd);
1271 		ASSERT_EQ(0,
1272 			  landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1273 					    &tcp_bind_p0, 0));
1274 		enforce_ruleset(_metadata, ruleset_fd);
1275 		EXPECT_EQ(0, close(ruleset_fd));
1276 	}
1277 
1278 	test_bind_and_connect(_metadata, &self->srv0, false,
1279 			      variant->num_layers >= 3);
1280 
1281 	test_bind_and_connect(_metadata, &self->srv1, variant->num_layers >= 1,
1282 			      variant->num_layers >= 2);
1283 }
1284 
1285 /* clang-format off */
FIXTURE(mini)1286 FIXTURE(mini) {};
1287 /* clang-format on */
1288 
FIXTURE_SETUP(mini)1289 FIXTURE_SETUP(mini)
1290 {
1291 	disable_caps(_metadata);
1292 
1293 	setup_loopback(_metadata);
1294 };
1295 
FIXTURE_TEARDOWN(mini)1296 FIXTURE_TEARDOWN(mini)
1297 {
1298 }
1299 
1300 /* clang-format off */
1301 
1302 #define ACCESS_LAST LANDLOCK_ACCESS_NET_CONNECT_TCP
1303 
1304 #define ACCESS_ALL ( \
1305 	LANDLOCK_ACCESS_NET_BIND_TCP | \
1306 	LANDLOCK_ACCESS_NET_CONNECT_TCP)
1307 
1308 /* clang-format on */
1309 
TEST_F(mini,network_access_rights)1310 TEST_F(mini, network_access_rights)
1311 {
1312 	const struct landlock_ruleset_attr ruleset_attr = {
1313 		.handled_access_net = ACCESS_ALL,
1314 	};
1315 	struct landlock_net_port_attr net_port = {
1316 		.port = sock_port_start,
1317 	};
1318 	int ruleset_fd;
1319 	__u64 access;
1320 
1321 	ruleset_fd =
1322 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
1323 	ASSERT_LE(0, ruleset_fd);
1324 
1325 	for (access = 1; access <= ACCESS_LAST; access <<= 1) {
1326 		net_port.allowed_access = access;
1327 		EXPECT_EQ(0,
1328 			  landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1329 					    &net_port, 0))
1330 		{
1331 			TH_LOG("Failed to add rule with access 0x%llx: %s",
1332 			       access, strerror(errno));
1333 		}
1334 	}
1335 	EXPECT_EQ(0, close(ruleset_fd));
1336 }
1337 
1338 /* Checks invalid attribute, out of landlock network access range. */
TEST_F(mini,ruleset_with_unknown_access)1339 TEST_F(mini, ruleset_with_unknown_access)
1340 {
1341 	__u64 access_mask;
1342 
1343 	for (access_mask = 1ULL << 63; access_mask != ACCESS_LAST;
1344 	     access_mask >>= 1) {
1345 		const struct landlock_ruleset_attr ruleset_attr = {
1346 			.handled_access_net = access_mask,
1347 		};
1348 
1349 		EXPECT_EQ(-1, landlock_create_ruleset(&ruleset_attr,
1350 						      sizeof(ruleset_attr), 0));
1351 		EXPECT_EQ(EINVAL, errno);
1352 	}
1353 }
1354 
TEST_F(mini,rule_with_unknown_access)1355 TEST_F(mini, rule_with_unknown_access)
1356 {
1357 	const struct landlock_ruleset_attr ruleset_attr = {
1358 		.handled_access_net = ACCESS_ALL,
1359 	};
1360 	struct landlock_net_port_attr net_port = {
1361 		.port = sock_port_start,
1362 	};
1363 	int ruleset_fd;
1364 	__u64 access;
1365 
1366 	ruleset_fd =
1367 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
1368 	ASSERT_LE(0, ruleset_fd);
1369 
1370 	for (access = 1ULL << 63; access != ACCESS_LAST; access >>= 1) {
1371 		net_port.allowed_access = access;
1372 		EXPECT_EQ(-1,
1373 			  landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1374 					    &net_port, 0));
1375 		EXPECT_EQ(EINVAL, errno);
1376 	}
1377 	EXPECT_EQ(0, close(ruleset_fd));
1378 }
1379 
TEST_F(mini,rule_with_unhandled_access)1380 TEST_F(mini, rule_with_unhandled_access)
1381 {
1382 	struct landlock_ruleset_attr ruleset_attr = {
1383 		.handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP,
1384 	};
1385 	struct landlock_net_port_attr net_port = {
1386 		.port = sock_port_start,
1387 	};
1388 	int ruleset_fd;
1389 	__u64 access;
1390 
1391 	ruleset_fd =
1392 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
1393 	ASSERT_LE(0, ruleset_fd);
1394 
1395 	for (access = 1; access > 0; access <<= 1) {
1396 		int err;
1397 
1398 		net_port.allowed_access = access;
1399 		err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1400 					&net_port, 0);
1401 		if (access == ruleset_attr.handled_access_net) {
1402 			EXPECT_EQ(0, err);
1403 		} else {
1404 			EXPECT_EQ(-1, err);
1405 			EXPECT_EQ(EINVAL, errno);
1406 		}
1407 	}
1408 
1409 	EXPECT_EQ(0, close(ruleset_fd));
1410 }
1411 
TEST_F(mini,inval)1412 TEST_F(mini, inval)
1413 {
1414 	const struct landlock_ruleset_attr ruleset_attr = {
1415 		.handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP
1416 	};
1417 	const struct landlock_net_port_attr tcp_bind_connect = {
1418 		.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP |
1419 				  LANDLOCK_ACCESS_NET_CONNECT_TCP,
1420 		.port = sock_port_start,
1421 	};
1422 	const struct landlock_net_port_attr tcp_denied = {
1423 		.allowed_access = 0,
1424 		.port = sock_port_start,
1425 	};
1426 	const struct landlock_net_port_attr tcp_bind = {
1427 		.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP,
1428 		.port = sock_port_start,
1429 	};
1430 	int ruleset_fd;
1431 
1432 	ruleset_fd =
1433 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
1434 	ASSERT_LE(0, ruleset_fd);
1435 
1436 	/* Checks unhandled allowed_access. */
1437 	EXPECT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1438 					&tcp_bind_connect, 0));
1439 	EXPECT_EQ(EINVAL, errno);
1440 
1441 	/* Checks zero access value. */
1442 	EXPECT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1443 					&tcp_denied, 0));
1444 	EXPECT_EQ(ENOMSG, errno);
1445 
1446 	/* Adds with legitimate values. */
1447 	ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1448 				       &tcp_bind, 0));
1449 }
1450 
TEST_F(mini,tcp_port_overflow)1451 TEST_F(mini, tcp_port_overflow)
1452 {
1453 	const struct landlock_ruleset_attr ruleset_attr = {
1454 		.handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP |
1455 				      LANDLOCK_ACCESS_NET_CONNECT_TCP,
1456 	};
1457 	const struct landlock_net_port_attr port_max_bind = {
1458 		.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP,
1459 		.port = UINT16_MAX,
1460 	};
1461 	const struct landlock_net_port_attr port_max_connect = {
1462 		.allowed_access = LANDLOCK_ACCESS_NET_CONNECT_TCP,
1463 		.port = UINT16_MAX,
1464 	};
1465 	const struct landlock_net_port_attr port_overflow1 = {
1466 		.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP,
1467 		.port = UINT16_MAX + 1,
1468 	};
1469 	const struct landlock_net_port_attr port_overflow2 = {
1470 		.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP,
1471 		.port = UINT16_MAX + 2,
1472 	};
1473 	const struct landlock_net_port_attr port_overflow3 = {
1474 		.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP,
1475 		.port = UINT32_MAX + 1UL,
1476 	};
1477 	const struct landlock_net_port_attr port_overflow4 = {
1478 		.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP,
1479 		.port = UINT32_MAX + 2UL,
1480 	};
1481 	const struct protocol_variant ipv4_tcp = {
1482 		.domain = AF_INET,
1483 		.type = SOCK_STREAM,
1484 	};
1485 	struct service_fixture srv_denied, srv_max_allowed;
1486 	int ruleset_fd;
1487 
1488 	ASSERT_EQ(0, set_service(&srv_denied, ipv4_tcp, 0));
1489 
1490 	/* Be careful to avoid port inconsistencies. */
1491 	srv_max_allowed = srv_denied;
1492 	srv_max_allowed.port = port_max_bind.port;
1493 	srv_max_allowed.ipv4_addr.sin_port = htons(port_max_bind.port);
1494 
1495 	ruleset_fd =
1496 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
1497 	ASSERT_LE(0, ruleset_fd);
1498 
1499 	ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1500 				       &port_max_bind, 0));
1501 
1502 	EXPECT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1503 					&port_overflow1, 0));
1504 	EXPECT_EQ(EINVAL, errno);
1505 
1506 	EXPECT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1507 					&port_overflow2, 0));
1508 	EXPECT_EQ(EINVAL, errno);
1509 
1510 	EXPECT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1511 					&port_overflow3, 0));
1512 	EXPECT_EQ(EINVAL, errno);
1513 
1514 	/* Interleaves with invalid rule additions. */
1515 	ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1516 				       &port_max_connect, 0));
1517 
1518 	EXPECT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1519 					&port_overflow4, 0));
1520 	EXPECT_EQ(EINVAL, errno);
1521 
1522 	enforce_ruleset(_metadata, ruleset_fd);
1523 
1524 	test_bind_and_connect(_metadata, &srv_denied, true, true);
1525 	test_bind_and_connect(_metadata, &srv_max_allowed, false, false);
1526 }
1527 
FIXTURE(ipv4_tcp)1528 FIXTURE(ipv4_tcp)
1529 {
1530 	struct service_fixture srv0, srv1;
1531 };
1532 
FIXTURE_SETUP(ipv4_tcp)1533 FIXTURE_SETUP(ipv4_tcp)
1534 {
1535 	const struct protocol_variant ipv4_tcp = {
1536 		.domain = AF_INET,
1537 		.type = SOCK_STREAM,
1538 	};
1539 
1540 	disable_caps(_metadata);
1541 
1542 	ASSERT_EQ(0, set_service(&self->srv0, ipv4_tcp, 0));
1543 	ASSERT_EQ(0, set_service(&self->srv1, ipv4_tcp, 1));
1544 
1545 	setup_loopback(_metadata);
1546 };
1547 
FIXTURE_TEARDOWN(ipv4_tcp)1548 FIXTURE_TEARDOWN(ipv4_tcp)
1549 {
1550 }
1551 
TEST_F(ipv4_tcp,port_endianness)1552 TEST_F(ipv4_tcp, port_endianness)
1553 {
1554 	const struct landlock_ruleset_attr ruleset_attr = {
1555 		.handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP |
1556 				      LANDLOCK_ACCESS_NET_CONNECT_TCP,
1557 	};
1558 	const struct landlock_net_port_attr bind_host_endian_p0 = {
1559 		.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP,
1560 		/* Host port format. */
1561 		.port = self->srv0.port,
1562 	};
1563 	const struct landlock_net_port_attr connect_big_endian_p0 = {
1564 		.allowed_access = LANDLOCK_ACCESS_NET_CONNECT_TCP,
1565 		/* Big endian port format. */
1566 		.port = htons(self->srv0.port),
1567 	};
1568 	const struct landlock_net_port_attr bind_connect_host_endian_p1 = {
1569 		.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP |
1570 				  LANDLOCK_ACCESS_NET_CONNECT_TCP,
1571 		/* Host port format. */
1572 		.port = self->srv1.port,
1573 	};
1574 	const unsigned int one = 1;
1575 	const char little_endian = *(const char *)&one;
1576 	int ruleset_fd;
1577 
1578 	ruleset_fd =
1579 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
1580 	ASSERT_LE(0, ruleset_fd);
1581 	ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1582 				       &bind_host_endian_p0, 0));
1583 	ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1584 				       &connect_big_endian_p0, 0));
1585 	ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1586 				       &bind_connect_host_endian_p1, 0));
1587 	enforce_ruleset(_metadata, ruleset_fd);
1588 
1589 	/* No restriction for big endinan CPU. */
1590 	test_bind_and_connect(_metadata, &self->srv0, false, little_endian);
1591 
1592 	/* No restriction for any CPU. */
1593 	test_bind_and_connect(_metadata, &self->srv1, false, false);
1594 }
1595 
TEST_F(ipv4_tcp,with_fs)1596 TEST_F(ipv4_tcp, with_fs)
1597 {
1598 	const struct landlock_ruleset_attr ruleset_attr_fs_net = {
1599 		.handled_access_fs = LANDLOCK_ACCESS_FS_READ_DIR,
1600 		.handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP,
1601 	};
1602 	struct landlock_path_beneath_attr path_beneath = {
1603 		.allowed_access = LANDLOCK_ACCESS_FS_READ_DIR,
1604 		.parent_fd = -1,
1605 	};
1606 	struct landlock_net_port_attr tcp_bind = {
1607 		.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP,
1608 		.port = self->srv0.port,
1609 	};
1610 	int ruleset_fd, bind_fd, dir_fd;
1611 
1612 	/* Creates ruleset both for filesystem and network access. */
1613 	ruleset_fd = landlock_create_ruleset(&ruleset_attr_fs_net,
1614 					     sizeof(ruleset_attr_fs_net), 0);
1615 	ASSERT_LE(0, ruleset_fd);
1616 
1617 	/* Adds a filesystem rule. */
1618 	path_beneath.parent_fd = open("/dev", O_PATH | O_DIRECTORY | O_CLOEXEC);
1619 	ASSERT_LE(0, path_beneath.parent_fd);
1620 	ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
1621 				       &path_beneath, 0));
1622 	EXPECT_EQ(0, close(path_beneath.parent_fd));
1623 
1624 	/* Adds a network rule. */
1625 	ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1626 				       &tcp_bind, 0));
1627 
1628 	enforce_ruleset(_metadata, ruleset_fd);
1629 	EXPECT_EQ(0, close(ruleset_fd));
1630 
1631 	/* Tests file access. */
1632 	dir_fd = open("/dev", O_RDONLY);
1633 	EXPECT_LE(0, dir_fd);
1634 	EXPECT_EQ(0, close(dir_fd));
1635 
1636 	dir_fd = open("/", O_RDONLY);
1637 	EXPECT_EQ(-1, dir_fd);
1638 	EXPECT_EQ(EACCES, errno);
1639 
1640 	/* Tests port binding. */
1641 	bind_fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1642 	ASSERT_LE(0, bind_fd);
1643 	EXPECT_EQ(0, bind_variant(bind_fd, &self->srv0));
1644 	EXPECT_EQ(0, close(bind_fd));
1645 
1646 	bind_fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1647 	ASSERT_LE(0, bind_fd);
1648 	EXPECT_EQ(-EACCES, bind_variant(bind_fd, &self->srv1));
1649 }
1650 
FIXTURE(port_specific)1651 FIXTURE(port_specific)
1652 {
1653 	struct service_fixture srv0;
1654 };
1655 
FIXTURE_VARIANT(port_specific)1656 FIXTURE_VARIANT(port_specific)
1657 {
1658 	const enum sandbox_type sandbox;
1659 	const struct protocol_variant prot;
1660 };
1661 
1662 /* clang-format off */
FIXTURE_VARIANT_ADD(port_specific,no_sandbox_with_ipv4)1663 FIXTURE_VARIANT_ADD(port_specific, no_sandbox_with_ipv4) {
1664 	/* clang-format on */
1665 	.sandbox = NO_SANDBOX,
1666 	.prot = {
1667 		.domain = AF_INET,
1668 		.type = SOCK_STREAM,
1669 	},
1670 };
1671 
1672 /* clang-format off */
FIXTURE_VARIANT_ADD(port_specific,sandbox_with_ipv4)1673 FIXTURE_VARIANT_ADD(port_specific, sandbox_with_ipv4) {
1674 	/* clang-format on */
1675 	.sandbox = TCP_SANDBOX,
1676 	.prot = {
1677 		.domain = AF_INET,
1678 		.type = SOCK_STREAM,
1679 	},
1680 };
1681 
1682 /* clang-format off */
FIXTURE_VARIANT_ADD(port_specific,no_sandbox_with_ipv6)1683 FIXTURE_VARIANT_ADD(port_specific, no_sandbox_with_ipv6) {
1684 	/* clang-format on */
1685 	.sandbox = NO_SANDBOX,
1686 	.prot = {
1687 		.domain = AF_INET6,
1688 		.type = SOCK_STREAM,
1689 	},
1690 };
1691 
1692 /* clang-format off */
FIXTURE_VARIANT_ADD(port_specific,sandbox_with_ipv6)1693 FIXTURE_VARIANT_ADD(port_specific, sandbox_with_ipv6) {
1694 	/* clang-format on */
1695 	.sandbox = TCP_SANDBOX,
1696 	.prot = {
1697 		.domain = AF_INET6,
1698 		.type = SOCK_STREAM,
1699 	},
1700 };
1701 
FIXTURE_SETUP(port_specific)1702 FIXTURE_SETUP(port_specific)
1703 {
1704 	disable_caps(_metadata);
1705 
1706 	ASSERT_EQ(0, set_service(&self->srv0, variant->prot, 0));
1707 
1708 	setup_loopback(_metadata);
1709 };
1710 
FIXTURE_TEARDOWN(port_specific)1711 FIXTURE_TEARDOWN(port_specific)
1712 {
1713 }
1714 
TEST_F(port_specific,bind_connect_zero)1715 TEST_F(port_specific, bind_connect_zero)
1716 {
1717 	int bind_fd, connect_fd, ret;
1718 	uint16_t port;
1719 
1720 	/* Adds a rule layer with bind and connect actions. */
1721 	if (variant->sandbox == TCP_SANDBOX) {
1722 		const struct landlock_ruleset_attr ruleset_attr = {
1723 			.handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP |
1724 					      LANDLOCK_ACCESS_NET_CONNECT_TCP
1725 		};
1726 		const struct landlock_net_port_attr tcp_bind_connect_zero = {
1727 			.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP |
1728 					  LANDLOCK_ACCESS_NET_CONNECT_TCP,
1729 			.port = 0,
1730 		};
1731 		int ruleset_fd;
1732 
1733 		ruleset_fd = landlock_create_ruleset(&ruleset_attr,
1734 						     sizeof(ruleset_attr), 0);
1735 		ASSERT_LE(0, ruleset_fd);
1736 
1737 		/* Checks zero port value on bind and connect actions. */
1738 		EXPECT_EQ(0,
1739 			  landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1740 					    &tcp_bind_connect_zero, 0));
1741 
1742 		enforce_ruleset(_metadata, ruleset_fd);
1743 		EXPECT_EQ(0, close(ruleset_fd));
1744 	}
1745 
1746 	bind_fd = socket_variant(&self->srv0);
1747 	ASSERT_LE(0, bind_fd);
1748 
1749 	connect_fd = socket_variant(&self->srv0);
1750 	ASSERT_LE(0, connect_fd);
1751 
1752 	/* Sets address port to 0 for both protocol families. */
1753 	set_port(&self->srv0, 0);
1754 	/*
1755 	 * Binds on port 0, which selects a random port within
1756 	 * ip_local_port_range.
1757 	 */
1758 	ret = bind_variant(bind_fd, &self->srv0);
1759 	EXPECT_EQ(0, ret);
1760 
1761 	EXPECT_EQ(0, listen(bind_fd, backlog));
1762 
1763 	/* Connects on port 0. */
1764 	ret = connect_variant(connect_fd, &self->srv0);
1765 	EXPECT_EQ(-ECONNREFUSED, ret);
1766 
1767 	/* Sets binded port for both protocol families. */
1768 	port = get_binded_port(bind_fd, &variant->prot);
1769 	EXPECT_NE(0, port);
1770 	set_port(&self->srv0, port);
1771 	/* Connects on the binded port. */
1772 	ret = connect_variant(connect_fd, &self->srv0);
1773 	if (is_restricted(&variant->prot, variant->sandbox)) {
1774 		/* Denied by Landlock. */
1775 		EXPECT_EQ(-EACCES, ret);
1776 	} else {
1777 		EXPECT_EQ(0, ret);
1778 	}
1779 
1780 	EXPECT_EQ(0, close(connect_fd));
1781 	EXPECT_EQ(0, close(bind_fd));
1782 }
1783 
TEST_F(port_specific,bind_connect_1023)1784 TEST_F(port_specific, bind_connect_1023)
1785 {
1786 	int bind_fd, connect_fd, ret;
1787 
1788 	/* Adds a rule layer with bind and connect actions. */
1789 	if (variant->sandbox == TCP_SANDBOX) {
1790 		const struct landlock_ruleset_attr ruleset_attr = {
1791 			.handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP |
1792 					      LANDLOCK_ACCESS_NET_CONNECT_TCP
1793 		};
1794 		/* A rule with port value less than 1024. */
1795 		const struct landlock_net_port_attr tcp_bind_connect_low_range = {
1796 			.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP |
1797 					  LANDLOCK_ACCESS_NET_CONNECT_TCP,
1798 			.port = 1023,
1799 		};
1800 		/* A rule with 1024 port. */
1801 		const struct landlock_net_port_attr tcp_bind_connect = {
1802 			.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP |
1803 					  LANDLOCK_ACCESS_NET_CONNECT_TCP,
1804 			.port = 1024,
1805 		};
1806 		int ruleset_fd;
1807 
1808 		ruleset_fd = landlock_create_ruleset(&ruleset_attr,
1809 						     sizeof(ruleset_attr), 0);
1810 		ASSERT_LE(0, ruleset_fd);
1811 
1812 		ASSERT_EQ(0,
1813 			  landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1814 					    &tcp_bind_connect_low_range, 0));
1815 		ASSERT_EQ(0,
1816 			  landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1817 					    &tcp_bind_connect, 0));
1818 
1819 		enforce_ruleset(_metadata, ruleset_fd);
1820 		EXPECT_EQ(0, close(ruleset_fd));
1821 	}
1822 
1823 	bind_fd = socket_variant(&self->srv0);
1824 	ASSERT_LE(0, bind_fd);
1825 
1826 	connect_fd = socket_variant(&self->srv0);
1827 	ASSERT_LE(0, connect_fd);
1828 
1829 	/* Sets address port to 1023 for both protocol families. */
1830 	set_port(&self->srv0, 1023);
1831 	/* Binds on port 1023. */
1832 	ret = bind_variant(bind_fd, &self->srv0);
1833 	/* Denied by the system. */
1834 	EXPECT_EQ(-EACCES, ret);
1835 
1836 	/* Binds on port 1023. */
1837 	set_cap(_metadata, CAP_NET_BIND_SERVICE);
1838 	ret = bind_variant(bind_fd, &self->srv0);
1839 	clear_cap(_metadata, CAP_NET_BIND_SERVICE);
1840 	EXPECT_EQ(0, ret);
1841 	EXPECT_EQ(0, listen(bind_fd, backlog));
1842 
1843 	/* Connects on the binded port 1023. */
1844 	ret = connect_variant(connect_fd, &self->srv0);
1845 	EXPECT_EQ(0, ret);
1846 
1847 	EXPECT_EQ(0, close(connect_fd));
1848 	EXPECT_EQ(0, close(bind_fd));
1849 
1850 	bind_fd = socket_variant(&self->srv0);
1851 	ASSERT_LE(0, bind_fd);
1852 
1853 	connect_fd = socket_variant(&self->srv0);
1854 	ASSERT_LE(0, connect_fd);
1855 
1856 	/* Sets address port to 1024 for both protocol families. */
1857 	set_port(&self->srv0, 1024);
1858 	/* Binds on port 1024. */
1859 	ret = bind_variant(bind_fd, &self->srv0);
1860 	EXPECT_EQ(0, ret);
1861 	EXPECT_EQ(0, listen(bind_fd, backlog));
1862 
1863 	/* Connects on the binded port 1024. */
1864 	ret = connect_variant(connect_fd, &self->srv0);
1865 	EXPECT_EQ(0, ret);
1866 
1867 	EXPECT_EQ(0, close(connect_fd));
1868 	EXPECT_EQ(0, close(bind_fd));
1869 }
1870 
1871 TEST_HARNESS_MAIN
1872