xref: /linux/tools/testing/selftests/landlock/net_test.c (revision e7d759f31ca295d589f7420719c311870bb3166f)
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, ruleset_with_unknown_access)
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, rule_with_unknown_access)
1280 {
1281 	const struct landlock_ruleset_attr ruleset_attr = {
1282 		.handled_access_net = ACCESS_ALL,
1283 	};
1284 	struct landlock_net_port_attr net_port = {
1285 		.port = sock_port_start,
1286 	};
1287 	int ruleset_fd;
1288 	__u64 access;
1289 
1290 	ruleset_fd =
1291 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
1292 	ASSERT_LE(0, ruleset_fd);
1293 
1294 	for (access = 1ULL << 63; access != ACCESS_LAST; access >>= 1) {
1295 		net_port.allowed_access = access;
1296 		EXPECT_EQ(-1,
1297 			  landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1298 					    &net_port, 0));
1299 		EXPECT_EQ(EINVAL, errno);
1300 	}
1301 	EXPECT_EQ(0, close(ruleset_fd));
1302 }
1303 
1304 TEST_F(mini, rule_with_unhandled_access)
1305 {
1306 	struct landlock_ruleset_attr ruleset_attr = {
1307 		.handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP,
1308 	};
1309 	struct landlock_net_port_attr net_port = {
1310 		.port = sock_port_start,
1311 	};
1312 	int ruleset_fd;
1313 	__u64 access;
1314 
1315 	ruleset_fd =
1316 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
1317 	ASSERT_LE(0, ruleset_fd);
1318 
1319 	for (access = 1; access > 0; access <<= 1) {
1320 		int err;
1321 
1322 		net_port.allowed_access = access;
1323 		err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1324 					&net_port, 0);
1325 		if (access == ruleset_attr.handled_access_net) {
1326 			EXPECT_EQ(0, err);
1327 		} else {
1328 			EXPECT_EQ(-1, err);
1329 			EXPECT_EQ(EINVAL, errno);
1330 		}
1331 	}
1332 
1333 	EXPECT_EQ(0, close(ruleset_fd));
1334 }
1335 
1336 TEST_F(mini, inval)
1337 {
1338 	const struct landlock_ruleset_attr ruleset_attr = {
1339 		.handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP
1340 	};
1341 	const struct landlock_net_port_attr tcp_bind_connect = {
1342 		.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP |
1343 				  LANDLOCK_ACCESS_NET_CONNECT_TCP,
1344 		.port = sock_port_start,
1345 	};
1346 	const struct landlock_net_port_attr tcp_denied = {
1347 		.allowed_access = 0,
1348 		.port = sock_port_start,
1349 	};
1350 	const struct landlock_net_port_attr tcp_bind = {
1351 		.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP,
1352 		.port = sock_port_start,
1353 	};
1354 	int ruleset_fd;
1355 
1356 	ruleset_fd =
1357 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
1358 	ASSERT_LE(0, ruleset_fd);
1359 
1360 	/* Checks unhandled allowed_access. */
1361 	EXPECT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1362 					&tcp_bind_connect, 0));
1363 	EXPECT_EQ(EINVAL, errno);
1364 
1365 	/* Checks zero access value. */
1366 	EXPECT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1367 					&tcp_denied, 0));
1368 	EXPECT_EQ(ENOMSG, errno);
1369 
1370 	/* Adds with legitimate values. */
1371 	ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1372 				       &tcp_bind, 0));
1373 }
1374 
1375 TEST_F(mini, tcp_port_overflow)
1376 {
1377 	const struct landlock_ruleset_attr ruleset_attr = {
1378 		.handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP |
1379 				      LANDLOCK_ACCESS_NET_CONNECT_TCP,
1380 	};
1381 	const struct landlock_net_port_attr port_max_bind = {
1382 		.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP,
1383 		.port = UINT16_MAX,
1384 	};
1385 	const struct landlock_net_port_attr port_max_connect = {
1386 		.allowed_access = LANDLOCK_ACCESS_NET_CONNECT_TCP,
1387 		.port = UINT16_MAX,
1388 	};
1389 	const struct landlock_net_port_attr port_overflow1 = {
1390 		.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP,
1391 		.port = UINT16_MAX + 1,
1392 	};
1393 	const struct landlock_net_port_attr port_overflow2 = {
1394 		.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP,
1395 		.port = UINT16_MAX + 2,
1396 	};
1397 	const struct landlock_net_port_attr port_overflow3 = {
1398 		.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP,
1399 		.port = UINT32_MAX + 1UL,
1400 	};
1401 	const struct landlock_net_port_attr port_overflow4 = {
1402 		.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP,
1403 		.port = UINT32_MAX + 2UL,
1404 	};
1405 	const struct protocol_variant ipv4_tcp = {
1406 		.domain = AF_INET,
1407 		.type = SOCK_STREAM,
1408 	};
1409 	struct service_fixture srv_denied, srv_max_allowed;
1410 	int ruleset_fd;
1411 
1412 	ASSERT_EQ(0, set_service(&srv_denied, ipv4_tcp, 0));
1413 
1414 	/* Be careful to avoid port inconsistencies. */
1415 	srv_max_allowed = srv_denied;
1416 	srv_max_allowed.port = port_max_bind.port;
1417 	srv_max_allowed.ipv4_addr.sin_port = htons(port_max_bind.port);
1418 
1419 	ruleset_fd =
1420 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
1421 	ASSERT_LE(0, ruleset_fd);
1422 
1423 	ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1424 				       &port_max_bind, 0));
1425 
1426 	EXPECT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1427 					&port_overflow1, 0));
1428 	EXPECT_EQ(EINVAL, errno);
1429 
1430 	EXPECT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1431 					&port_overflow2, 0));
1432 	EXPECT_EQ(EINVAL, errno);
1433 
1434 	EXPECT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1435 					&port_overflow3, 0));
1436 	EXPECT_EQ(EINVAL, errno);
1437 
1438 	/* Interleaves with invalid rule additions. */
1439 	ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1440 				       &port_max_connect, 0));
1441 
1442 	EXPECT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1443 					&port_overflow4, 0));
1444 	EXPECT_EQ(EINVAL, errno);
1445 
1446 	enforce_ruleset(_metadata, ruleset_fd);
1447 
1448 	test_bind_and_connect(_metadata, &srv_denied, true, true);
1449 	test_bind_and_connect(_metadata, &srv_max_allowed, false, false);
1450 }
1451 
1452 FIXTURE(ipv4_tcp)
1453 {
1454 	struct service_fixture srv0, srv1;
1455 };
1456 
1457 FIXTURE_SETUP(ipv4_tcp)
1458 {
1459 	const struct protocol_variant ipv4_tcp = {
1460 		.domain = AF_INET,
1461 		.type = SOCK_STREAM,
1462 	};
1463 
1464 	disable_caps(_metadata);
1465 
1466 	ASSERT_EQ(0, set_service(&self->srv0, ipv4_tcp, 0));
1467 	ASSERT_EQ(0, set_service(&self->srv1, ipv4_tcp, 1));
1468 
1469 	setup_loopback(_metadata);
1470 };
1471 
1472 FIXTURE_TEARDOWN(ipv4_tcp)
1473 {
1474 }
1475 
1476 TEST_F(ipv4_tcp, port_endianness)
1477 {
1478 	const struct landlock_ruleset_attr ruleset_attr = {
1479 		.handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP |
1480 				      LANDLOCK_ACCESS_NET_CONNECT_TCP,
1481 	};
1482 	const struct landlock_net_port_attr bind_host_endian_p0 = {
1483 		.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP,
1484 		/* Host port format. */
1485 		.port = self->srv0.port,
1486 	};
1487 	const struct landlock_net_port_attr connect_big_endian_p0 = {
1488 		.allowed_access = LANDLOCK_ACCESS_NET_CONNECT_TCP,
1489 		/* Big endian port format. */
1490 		.port = htons(self->srv0.port),
1491 	};
1492 	const struct landlock_net_port_attr bind_connect_host_endian_p1 = {
1493 		.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP |
1494 				  LANDLOCK_ACCESS_NET_CONNECT_TCP,
1495 		/* Host port format. */
1496 		.port = self->srv1.port,
1497 	};
1498 	const unsigned int one = 1;
1499 	const char little_endian = *(const char *)&one;
1500 	int ruleset_fd;
1501 
1502 	ruleset_fd =
1503 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
1504 	ASSERT_LE(0, ruleset_fd);
1505 	ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1506 				       &bind_host_endian_p0, 0));
1507 	ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1508 				       &connect_big_endian_p0, 0));
1509 	ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1510 				       &bind_connect_host_endian_p1, 0));
1511 	enforce_ruleset(_metadata, ruleset_fd);
1512 
1513 	/* No restriction for big endinan CPU. */
1514 	test_bind_and_connect(_metadata, &self->srv0, false, little_endian);
1515 
1516 	/* No restriction for any CPU. */
1517 	test_bind_and_connect(_metadata, &self->srv1, false, false);
1518 }
1519 
1520 TEST_F(ipv4_tcp, with_fs)
1521 {
1522 	const struct landlock_ruleset_attr ruleset_attr_fs_net = {
1523 		.handled_access_fs = LANDLOCK_ACCESS_FS_READ_DIR,
1524 		.handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP,
1525 	};
1526 	struct landlock_path_beneath_attr path_beneath = {
1527 		.allowed_access = LANDLOCK_ACCESS_FS_READ_DIR,
1528 		.parent_fd = -1,
1529 	};
1530 	struct landlock_net_port_attr tcp_bind = {
1531 		.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP,
1532 		.port = self->srv0.port,
1533 	};
1534 	int ruleset_fd, bind_fd, dir_fd;
1535 
1536 	/* Creates ruleset both for filesystem and network access. */
1537 	ruleset_fd = landlock_create_ruleset(&ruleset_attr_fs_net,
1538 					     sizeof(ruleset_attr_fs_net), 0);
1539 	ASSERT_LE(0, ruleset_fd);
1540 
1541 	/* Adds a filesystem rule. */
1542 	path_beneath.parent_fd = open("/dev", O_PATH | O_DIRECTORY | O_CLOEXEC);
1543 	ASSERT_LE(0, path_beneath.parent_fd);
1544 	ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
1545 				       &path_beneath, 0));
1546 	EXPECT_EQ(0, close(path_beneath.parent_fd));
1547 
1548 	/* Adds a network rule. */
1549 	ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1550 				       &tcp_bind, 0));
1551 
1552 	enforce_ruleset(_metadata, ruleset_fd);
1553 	EXPECT_EQ(0, close(ruleset_fd));
1554 
1555 	/* Tests file access. */
1556 	dir_fd = open("/dev", O_RDONLY);
1557 	EXPECT_LE(0, dir_fd);
1558 	EXPECT_EQ(0, close(dir_fd));
1559 
1560 	dir_fd = open("/", O_RDONLY);
1561 	EXPECT_EQ(-1, dir_fd);
1562 	EXPECT_EQ(EACCES, errno);
1563 
1564 	/* Tests port binding. */
1565 	bind_fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1566 	ASSERT_LE(0, bind_fd);
1567 	EXPECT_EQ(0, bind_variant(bind_fd, &self->srv0));
1568 	EXPECT_EQ(0, close(bind_fd));
1569 
1570 	bind_fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1571 	ASSERT_LE(0, bind_fd);
1572 	EXPECT_EQ(-EACCES, bind_variant(bind_fd, &self->srv1));
1573 }
1574 
1575 FIXTURE(port_specific)
1576 {
1577 	struct service_fixture srv0;
1578 };
1579 
1580 FIXTURE_VARIANT(port_specific)
1581 {
1582 	const enum sandbox_type sandbox;
1583 	const struct protocol_variant prot;
1584 };
1585 
1586 /* clang-format off */
1587 FIXTURE_VARIANT_ADD(port_specific, no_sandbox_with_ipv4) {
1588 	/* clang-format on */
1589 	.sandbox = NO_SANDBOX,
1590 	.prot = {
1591 		.domain = AF_INET,
1592 		.type = SOCK_STREAM,
1593 	},
1594 };
1595 
1596 /* clang-format off */
1597 FIXTURE_VARIANT_ADD(port_specific, sandbox_with_ipv4) {
1598 	/* clang-format on */
1599 	.sandbox = TCP_SANDBOX,
1600 	.prot = {
1601 		.domain = AF_INET,
1602 		.type = SOCK_STREAM,
1603 	},
1604 };
1605 
1606 /* clang-format off */
1607 FIXTURE_VARIANT_ADD(port_specific, no_sandbox_with_ipv6) {
1608 	/* clang-format on */
1609 	.sandbox = NO_SANDBOX,
1610 	.prot = {
1611 		.domain = AF_INET6,
1612 		.type = SOCK_STREAM,
1613 	},
1614 };
1615 
1616 /* clang-format off */
1617 FIXTURE_VARIANT_ADD(port_specific, sandbox_with_ipv6) {
1618 	/* clang-format on */
1619 	.sandbox = TCP_SANDBOX,
1620 	.prot = {
1621 		.domain = AF_INET6,
1622 		.type = SOCK_STREAM,
1623 	},
1624 };
1625 
1626 FIXTURE_SETUP(port_specific)
1627 {
1628 	disable_caps(_metadata);
1629 
1630 	ASSERT_EQ(0, set_service(&self->srv0, variant->prot, 0));
1631 
1632 	setup_loopback(_metadata);
1633 };
1634 
1635 FIXTURE_TEARDOWN(port_specific)
1636 {
1637 }
1638 
1639 TEST_F(port_specific, bind_connect_zero)
1640 {
1641 	int bind_fd, connect_fd, ret;
1642 	uint16_t port;
1643 
1644 	/* Adds a rule layer with bind and connect actions. */
1645 	if (variant->sandbox == TCP_SANDBOX) {
1646 		const struct landlock_ruleset_attr ruleset_attr = {
1647 			.handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP |
1648 					      LANDLOCK_ACCESS_NET_CONNECT_TCP
1649 		};
1650 		const struct landlock_net_port_attr tcp_bind_connect_zero = {
1651 			.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP |
1652 					  LANDLOCK_ACCESS_NET_CONNECT_TCP,
1653 			.port = 0,
1654 		};
1655 		int ruleset_fd;
1656 
1657 		ruleset_fd = landlock_create_ruleset(&ruleset_attr,
1658 						     sizeof(ruleset_attr), 0);
1659 		ASSERT_LE(0, ruleset_fd);
1660 
1661 		/* Checks zero port value on bind and connect actions. */
1662 		EXPECT_EQ(0,
1663 			  landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1664 					    &tcp_bind_connect_zero, 0));
1665 
1666 		enforce_ruleset(_metadata, ruleset_fd);
1667 		EXPECT_EQ(0, close(ruleset_fd));
1668 	}
1669 
1670 	bind_fd = socket_variant(&self->srv0);
1671 	ASSERT_LE(0, bind_fd);
1672 
1673 	connect_fd = socket_variant(&self->srv0);
1674 	ASSERT_LE(0, connect_fd);
1675 
1676 	/* Sets address port to 0 for both protocol families. */
1677 	set_port(&self->srv0, 0);
1678 	/*
1679 	 * Binds on port 0, which selects a random port within
1680 	 * ip_local_port_range.
1681 	 */
1682 	ret = bind_variant(bind_fd, &self->srv0);
1683 	EXPECT_EQ(0, ret);
1684 
1685 	EXPECT_EQ(0, listen(bind_fd, backlog));
1686 
1687 	/* Connects on port 0. */
1688 	ret = connect_variant(connect_fd, &self->srv0);
1689 	EXPECT_EQ(-ECONNREFUSED, ret);
1690 
1691 	/* Sets binded port for both protocol families. */
1692 	port = get_binded_port(bind_fd, &variant->prot);
1693 	EXPECT_NE(0, port);
1694 	set_port(&self->srv0, port);
1695 	/* Connects on the binded port. */
1696 	ret = connect_variant(connect_fd, &self->srv0);
1697 	if (is_restricted(&variant->prot, variant->sandbox)) {
1698 		/* Denied by Landlock. */
1699 		EXPECT_EQ(-EACCES, ret);
1700 	} else {
1701 		EXPECT_EQ(0, ret);
1702 	}
1703 
1704 	EXPECT_EQ(0, close(connect_fd));
1705 	EXPECT_EQ(0, close(bind_fd));
1706 }
1707 
1708 TEST_F(port_specific, bind_connect_1023)
1709 {
1710 	int bind_fd, connect_fd, ret;
1711 
1712 	/* Adds a rule layer with bind and connect actions. */
1713 	if (variant->sandbox == TCP_SANDBOX) {
1714 		const struct landlock_ruleset_attr ruleset_attr = {
1715 			.handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP |
1716 					      LANDLOCK_ACCESS_NET_CONNECT_TCP
1717 		};
1718 		/* A rule with port value less than 1024. */
1719 		const struct landlock_net_port_attr tcp_bind_connect_low_range = {
1720 			.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP |
1721 					  LANDLOCK_ACCESS_NET_CONNECT_TCP,
1722 			.port = 1023,
1723 		};
1724 		/* A rule with 1024 port. */
1725 		const struct landlock_net_port_attr tcp_bind_connect = {
1726 			.allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP |
1727 					  LANDLOCK_ACCESS_NET_CONNECT_TCP,
1728 			.port = 1024,
1729 		};
1730 		int ruleset_fd;
1731 
1732 		ruleset_fd = landlock_create_ruleset(&ruleset_attr,
1733 						     sizeof(ruleset_attr), 0);
1734 		ASSERT_LE(0, ruleset_fd);
1735 
1736 		ASSERT_EQ(0,
1737 			  landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1738 					    &tcp_bind_connect_low_range, 0));
1739 		ASSERT_EQ(0,
1740 			  landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1741 					    &tcp_bind_connect, 0));
1742 
1743 		enforce_ruleset(_metadata, ruleset_fd);
1744 		EXPECT_EQ(0, close(ruleset_fd));
1745 	}
1746 
1747 	bind_fd = socket_variant(&self->srv0);
1748 	ASSERT_LE(0, bind_fd);
1749 
1750 	connect_fd = socket_variant(&self->srv0);
1751 	ASSERT_LE(0, connect_fd);
1752 
1753 	/* Sets address port to 1023 for both protocol families. */
1754 	set_port(&self->srv0, 1023);
1755 	/* Binds on port 1023. */
1756 	ret = bind_variant(bind_fd, &self->srv0);
1757 	/* Denied by the system. */
1758 	EXPECT_EQ(-EACCES, ret);
1759 
1760 	/* Binds on port 1023. */
1761 	set_cap(_metadata, CAP_NET_BIND_SERVICE);
1762 	ret = bind_variant(bind_fd, &self->srv0);
1763 	clear_cap(_metadata, CAP_NET_BIND_SERVICE);
1764 	EXPECT_EQ(0, ret);
1765 	EXPECT_EQ(0, listen(bind_fd, backlog));
1766 
1767 	/* Connects on the binded port 1023. */
1768 	ret = connect_variant(connect_fd, &self->srv0);
1769 	EXPECT_EQ(0, ret);
1770 
1771 	EXPECT_EQ(0, close(connect_fd));
1772 	EXPECT_EQ(0, close(bind_fd));
1773 
1774 	bind_fd = socket_variant(&self->srv0);
1775 	ASSERT_LE(0, bind_fd);
1776 
1777 	connect_fd = socket_variant(&self->srv0);
1778 	ASSERT_LE(0, connect_fd);
1779 
1780 	/* Sets address port to 1024 for both protocol families. */
1781 	set_port(&self->srv0, 1024);
1782 	/* Binds on port 1024. */
1783 	ret = bind_variant(bind_fd, &self->srv0);
1784 	EXPECT_EQ(0, ret);
1785 	EXPECT_EQ(0, listen(bind_fd, backlog));
1786 
1787 	/* Connects on the binded port 1024. */
1788 	ret = connect_variant(connect_fd, &self->srv0);
1789 	EXPECT_EQ(0, ret);
1790 
1791 	EXPECT_EQ(0, close(connect_fd));
1792 	EXPECT_EQ(0, close(bind_fd));
1793 }
1794 
1795 TEST_HARNESS_MAIN
1796