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