Linux Audio

Check our new training course

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