File Index
Files and directories
Sign in
FILE

net_test.c

File preview with syntax highlighting.

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