brintos

brintos / linux-shallow public Read only

0
0
Text · 43.6 KiB · 4e0aeb5 Raw
1776 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Landlock tests - Network4 *5 * Copyright © 2022-2023 Huawei Tech. Co., Ltd.6 * Copyright © 2023 Microsoft Corporation7 */8 9#define _GNU_SOURCE10#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 25const short sock_port_start = (1 << 10);26 27static const char loopback_ipv4[] = "127.0.0.1";28static const char loopback_ipv6[] = "::1";29 30/* Number pending connections queue to be hold. */31const short backlog = 10;32 33enum sandbox_type {34	NO_SANDBOX,35	/* This may be used to test rules that allow *and* deny accesses. */36	TCP_SANDBOX,37};38 39static 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 contains47	 * 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 77static 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 88static 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 103static 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_RFC2133115#define SIN6_LEN_RFC2133 24116#endif117 118static 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 142static 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 159static 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 184static 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 214static 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 220static 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 250static 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 256FIXTURE(protocol)257{258	struct service_fixture srv0, srv1, srv2, unspec_any0, unspec_srv0;259};260 261FIXTURE_VARIANT(protocol)262{263	const enum sandbox_type sandbox;264	const struct protocol_variant prot;265};266 267FIXTURE_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 288FIXTURE_TEARDOWN(protocol)289{290}291 292/* clang-format off */293FIXTURE_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 */303FIXTURE_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 */313FIXTURE_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 */323FIXTURE_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 */333FIXTURE_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 */343FIXTURE_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 */353FIXTURE_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 */363FIXTURE_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 */373FIXTURE_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 */383FIXTURE_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 */393FIXTURE_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 */403FIXTURE_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 412static 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 541TEST_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 591TEST_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 637TEST_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 718TEST_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 830FIXTURE(ipv4)831{832	struct service_fixture srv0, srv1;833};834 835FIXTURE_VARIANT(ipv4)836{837	const enum sandbox_type sandbox;838	const int type;839};840 841/* clang-format off */842FIXTURE_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 */849FIXTURE_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 */856FIXTURE_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 */863FIXTURE_VARIANT_ADD(ipv4, tcp_sandbox_with_udp) {864	/* clang-format on */865	.sandbox = TCP_SANDBOX,866	.type = SOCK_DGRAM,867};868 869FIXTURE_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 884FIXTURE_TEARDOWN(ipv4)885{886}887 888TEST_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 944FIXTURE(tcp_layers)945{946	struct service_fixture srv0, srv1;947};948 949FIXTURE_VARIANT(tcp_layers)950{951	const size_t num_layers;952	const int domain;953};954 955FIXTURE_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 970FIXTURE_TEARDOWN(tcp_layers)971{972}973 974/* clang-format off */975FIXTURE_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 */982FIXTURE_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 */989FIXTURE_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 */996FIXTURE_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 */1003FIXTURE_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 */1010FIXTURE_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 */1017FIXTURE_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 */1024FIXTURE_VARIANT_ADD(tcp_layers, three_sandboxes_with_ipv6) {1025	/* clang-format on */1026	.domain = AF_INET6,1027	.num_layers = 3,1028};1029 1030TEST_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 layer1099	 * allows connect.1100	 */1101	test_bind_and_connect(_metadata, &self->srv0, false,1102			      variant->num_layers >= 2);1103}1104 1105TEST_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 */1190FIXTURE(mini) {};1191/* clang-format on */1192 1193FIXTURE_SETUP(mini)1194{1195	disable_caps(_metadata);1196 1197	setup_loopback(_metadata);1198};1199 1200FIXTURE_TEARDOWN(mini)1201{1202}1203 1204/* clang-format off */1205 1206#define ACCESS_LAST LANDLOCK_ACCESS_NET_CONNECT_TCP1207 1208#define ACCESS_ALL ( \1209	LANDLOCK_ACCESS_NET_BIND_TCP | \1210	LANDLOCK_ACCESS_NET_CONNECT_TCP)1211 1212/* clang-format on */1213 1214TEST_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. */1243TEST_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 1259TEST_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 1284TEST_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 1316TEST_F(mini, inval)1317{1318	const struct landlock_ruleset_attr ruleset_attr = {1319		.handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP1320	};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 1355TEST_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 1432FIXTURE(ipv4_tcp)1433{1434	struct service_fixture srv0, srv1;1435};1436 1437FIXTURE_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 1452FIXTURE_TEARDOWN(ipv4_tcp)1453{1454}1455 1456TEST_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 1500TEST_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 1555FIXTURE(port_specific)1556{1557	struct service_fixture srv0;1558};1559 1560FIXTURE_VARIANT(port_specific)1561{1562	const enum sandbox_type sandbox;1563	const struct protocol_variant prot;1564};1565 1566/* clang-format off */1567FIXTURE_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 */1577FIXTURE_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 */1587FIXTURE_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 */1597FIXTURE_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 1606FIXTURE_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 1615FIXTURE_TEARDOWN(port_specific)1616{1617}1618 1619TEST_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_TCP1629		};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 within1660	 * 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 1688TEST_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_TCP1697		};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 1775TEST_HARNESS_MAIN1776