Linux Audio

Check our new training course

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