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