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