Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.10.11.
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Landlock tests - Abstract UNIX socket
   4 *
   5 * Copyright © 2024 Tahera Fahimi <fahimitahera@gmail.com>
   6 */
   7
   8#define _GNU_SOURCE
   9#include <errno.h>
  10#include <fcntl.h>
  11#include <linux/landlock.h>
  12#include <sched.h>
  13#include <signal.h>
  14#include <stddef.h>
  15#include <sys/prctl.h>
  16#include <sys/socket.h>
  17#include <sys/stat.h>
  18#include <sys/types.h>
  19#include <sys/un.h>
  20#include <sys/wait.h>
  21#include <unistd.h>
  22
  23#include "common.h"
  24#include "scoped_common.h"
  25
  26/* Number of pending connections queue to be hold. */
  27const short backlog = 10;
  28
  29static void create_fs_domain(struct __test_metadata *const _metadata)
  30{
  31	int ruleset_fd;
  32	struct landlock_ruleset_attr ruleset_attr = {
  33		.handled_access_fs = LANDLOCK_ACCESS_FS_READ_DIR,
  34	};
  35
  36	ruleset_fd =
  37		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
  38	EXPECT_LE(0, ruleset_fd)
  39	{
  40		TH_LOG("Failed to create a ruleset: %s", strerror(errno));
  41	}
  42	EXPECT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0));
  43	EXPECT_EQ(0, landlock_restrict_self(ruleset_fd, 0));
  44	EXPECT_EQ(0, close(ruleset_fd));
  45}
  46
  47FIXTURE(scoped_domains)
  48{
  49	struct service_fixture stream_address, dgram_address;
  50};
  51
  52#include "scoped_base_variants.h"
  53
  54FIXTURE_SETUP(scoped_domains)
  55{
  56	drop_caps(_metadata);
  57
  58	memset(&self->stream_address, 0, sizeof(self->stream_address));
  59	memset(&self->dgram_address, 0, sizeof(self->dgram_address));
  60	set_unix_address(&self->stream_address, 0);
  61	set_unix_address(&self->dgram_address, 1);
  62}
  63
  64FIXTURE_TEARDOWN(scoped_domains)
  65{
  66}
  67
  68/*
  69 * Test unix_stream_connect() and unix_may_send() for a child connecting to its
  70 * parent, when they have scoped domain or no domain.
  71 */
  72TEST_F(scoped_domains, connect_to_parent)
  73{
  74	pid_t child;
  75	bool can_connect_to_parent;
  76	int status;
  77	int pipe_parent[2];
  78	int stream_server, dgram_server;
  79
  80	/*
  81	 * can_connect_to_parent is true if a child process can connect to its
  82	 * parent process. This depends on the child process not being isolated
  83	 * from the parent with a dedicated Landlock domain.
  84	 */
  85	can_connect_to_parent = !variant->domain_child;
  86
  87	ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC));
  88	if (variant->domain_both) {
  89		create_scoped_domain(_metadata,
  90				     LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
  91		if (!__test_passed(_metadata))
  92			return;
  93	}
  94
  95	child = fork();
  96	ASSERT_LE(0, child);
  97	if (child == 0) {
  98		int err;
  99		int stream_client, dgram_client;
 100		char buf_child;
 101
 102		EXPECT_EQ(0, close(pipe_parent[1]));
 103		if (variant->domain_child)
 104			create_scoped_domain(
 105				_metadata, LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
 106
 107		stream_client = socket(AF_UNIX, SOCK_STREAM, 0);
 108		ASSERT_LE(0, stream_client);
 109		dgram_client = socket(AF_UNIX, SOCK_DGRAM, 0);
 110		ASSERT_LE(0, dgram_client);
 111
 112		/* Waits for the server. */
 113		ASSERT_EQ(1, read(pipe_parent[0], &buf_child, 1));
 114
 115		err = connect(stream_client, &self->stream_address.unix_addr,
 116			      self->stream_address.unix_addr_len);
 117		if (can_connect_to_parent) {
 118			EXPECT_EQ(0, err);
 119		} else {
 120			EXPECT_EQ(-1, err);
 121			EXPECT_EQ(EPERM, errno);
 122		}
 123		EXPECT_EQ(0, close(stream_client));
 124
 125		err = connect(dgram_client, &self->dgram_address.unix_addr,
 126			      self->dgram_address.unix_addr_len);
 127		if (can_connect_to_parent) {
 128			EXPECT_EQ(0, err);
 129		} else {
 130			EXPECT_EQ(-1, err);
 131			EXPECT_EQ(EPERM, errno);
 132		}
 133		EXPECT_EQ(0, close(dgram_client));
 134		_exit(_metadata->exit_code);
 135		return;
 136	}
 137	EXPECT_EQ(0, close(pipe_parent[0]));
 138	if (variant->domain_parent)
 139		create_scoped_domain(_metadata,
 140				     LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
 141
 142	stream_server = socket(AF_UNIX, SOCK_STREAM, 0);
 143	ASSERT_LE(0, stream_server);
 144	dgram_server = socket(AF_UNIX, SOCK_DGRAM, 0);
 145	ASSERT_LE(0, dgram_server);
 146	ASSERT_EQ(0, bind(stream_server, &self->stream_address.unix_addr,
 147			  self->stream_address.unix_addr_len));
 148	ASSERT_EQ(0, bind(dgram_server, &self->dgram_address.unix_addr,
 149			  self->dgram_address.unix_addr_len));
 150	ASSERT_EQ(0, listen(stream_server, backlog));
 151
 152	/* Signals to child that the parent is listening. */
 153	ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
 154
 155	ASSERT_EQ(child, waitpid(child, &status, 0));
 156	EXPECT_EQ(0, close(stream_server));
 157	EXPECT_EQ(0, close(dgram_server));
 158
 159	if (WIFSIGNALED(status) || !WIFEXITED(status) ||
 160	    WEXITSTATUS(status) != EXIT_SUCCESS)
 161		_metadata->exit_code = KSFT_FAIL;
 162}
 163
 164/*
 165 * Test unix_stream_connect() and unix_may_send() for a parent connecting to
 166 * its child, when they have scoped domain or no domain.
 167 */
 168TEST_F(scoped_domains, connect_to_child)
 169{
 170	pid_t child;
 171	bool can_connect_to_child;
 172	int err_stream, err_dgram, errno_stream, errno_dgram, status;
 173	int pipe_child[2], pipe_parent[2];
 174	char buf;
 175	int stream_client, dgram_client;
 176
 177	/*
 178	 * can_connect_to_child is true if a parent process can connect to its
 179	 * child process. The parent process is not isolated from the child
 180	 * with a dedicated Landlock domain.
 181	 */
 182	can_connect_to_child = !variant->domain_parent;
 183
 184	ASSERT_EQ(0, pipe2(pipe_child, O_CLOEXEC));
 185	ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC));
 186	if (variant->domain_both) {
 187		create_scoped_domain(_metadata,
 188				     LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
 189		if (!__test_passed(_metadata))
 190			return;
 191	}
 192
 193	child = fork();
 194	ASSERT_LE(0, child);
 195	if (child == 0) {
 196		int stream_server, dgram_server;
 197
 198		EXPECT_EQ(0, close(pipe_parent[1]));
 199		EXPECT_EQ(0, close(pipe_child[0]));
 200		if (variant->domain_child)
 201			create_scoped_domain(
 202				_metadata, LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
 203
 204		/* Waits for the parent to be in a domain, if any. */
 205		ASSERT_EQ(1, read(pipe_parent[0], &buf, 1));
 206
 207		stream_server = socket(AF_UNIX, SOCK_STREAM, 0);
 208		ASSERT_LE(0, stream_server);
 209		dgram_server = socket(AF_UNIX, SOCK_DGRAM, 0);
 210		ASSERT_LE(0, dgram_server);
 211		ASSERT_EQ(0,
 212			  bind(stream_server, &self->stream_address.unix_addr,
 213			       self->stream_address.unix_addr_len));
 214		ASSERT_EQ(0, bind(dgram_server, &self->dgram_address.unix_addr,
 215				  self->dgram_address.unix_addr_len));
 216		ASSERT_EQ(0, listen(stream_server, backlog));
 217
 218		/* Signals to the parent that child is listening. */
 219		ASSERT_EQ(1, write(pipe_child[1], ".", 1));
 220
 221		/* Waits to connect. */
 222		ASSERT_EQ(1, read(pipe_parent[0], &buf, 1));
 223		EXPECT_EQ(0, close(stream_server));
 224		EXPECT_EQ(0, close(dgram_server));
 225		_exit(_metadata->exit_code);
 226		return;
 227	}
 228	EXPECT_EQ(0, close(pipe_child[1]));
 229	EXPECT_EQ(0, close(pipe_parent[0]));
 230
 231	if (variant->domain_parent)
 232		create_scoped_domain(_metadata,
 233				     LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
 234
 235	/* Signals that the parent is in a domain, if any. */
 236	ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
 237
 238	stream_client = socket(AF_UNIX, SOCK_STREAM, 0);
 239	ASSERT_LE(0, stream_client);
 240	dgram_client = socket(AF_UNIX, SOCK_DGRAM, 0);
 241	ASSERT_LE(0, dgram_client);
 242
 243	/* Waits for the child to listen */
 244	ASSERT_EQ(1, read(pipe_child[0], &buf, 1));
 245	err_stream = connect(stream_client, &self->stream_address.unix_addr,
 246			     self->stream_address.unix_addr_len);
 247	errno_stream = errno;
 248	err_dgram = connect(dgram_client, &self->dgram_address.unix_addr,
 249			    self->dgram_address.unix_addr_len);
 250	errno_dgram = errno;
 251	if (can_connect_to_child) {
 252		EXPECT_EQ(0, err_stream);
 253		EXPECT_EQ(0, err_dgram);
 254	} else {
 255		EXPECT_EQ(-1, err_stream);
 256		EXPECT_EQ(-1, err_dgram);
 257		EXPECT_EQ(EPERM, errno_stream);
 258		EXPECT_EQ(EPERM, errno_dgram);
 259	}
 260	ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
 261	EXPECT_EQ(0, close(stream_client));
 262	EXPECT_EQ(0, close(dgram_client));
 263
 264	ASSERT_EQ(child, waitpid(child, &status, 0));
 265	if (WIFSIGNALED(status) || !WIFEXITED(status) ||
 266	    WEXITSTATUS(status) != EXIT_SUCCESS)
 267		_metadata->exit_code = KSFT_FAIL;
 268}
 269
 270FIXTURE(scoped_vs_unscoped)
 271{
 272	struct service_fixture parent_stream_address, parent_dgram_address,
 273		child_stream_address, child_dgram_address;
 274};
 275
 276#include "scoped_multiple_domain_variants.h"
 277
 278FIXTURE_SETUP(scoped_vs_unscoped)
 279{
 280	drop_caps(_metadata);
 281
 282	memset(&self->parent_stream_address, 0,
 283	       sizeof(self->parent_stream_address));
 284	set_unix_address(&self->parent_stream_address, 0);
 285	memset(&self->parent_dgram_address, 0,
 286	       sizeof(self->parent_dgram_address));
 287	set_unix_address(&self->parent_dgram_address, 1);
 288	memset(&self->child_stream_address, 0,
 289	       sizeof(self->child_stream_address));
 290	set_unix_address(&self->child_stream_address, 2);
 291	memset(&self->child_dgram_address, 0,
 292	       sizeof(self->child_dgram_address));
 293	set_unix_address(&self->child_dgram_address, 3);
 294}
 295
 296FIXTURE_TEARDOWN(scoped_vs_unscoped)
 297{
 298}
 299
 300/*
 301 * Test unix_stream_connect and unix_may_send for parent, child and
 302 * grand child processes when they can have scoped or non-scoped domains.
 303 */
 304TEST_F(scoped_vs_unscoped, unix_scoping)
 305{
 306	pid_t child;
 307	int status;
 308	bool can_connect_to_parent, can_connect_to_child;
 309	int pipe_parent[2];
 310	int stream_server_parent, dgram_server_parent;
 311
 312	can_connect_to_child = (variant->domain_grand_child != SCOPE_SANDBOX);
 313	can_connect_to_parent = (can_connect_to_child &&
 314				 (variant->domain_children != SCOPE_SANDBOX));
 315
 316	ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC));
 317
 318	if (variant->domain_all == OTHER_SANDBOX)
 319		create_fs_domain(_metadata);
 320	else if (variant->domain_all == SCOPE_SANDBOX)
 321		create_scoped_domain(_metadata,
 322				     LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
 323
 324	child = fork();
 325	ASSERT_LE(0, child);
 326	if (child == 0) {
 327		int stream_server_child, dgram_server_child;
 328		int pipe_child[2];
 329		pid_t grand_child;
 330
 331		ASSERT_EQ(0, pipe2(pipe_child, O_CLOEXEC));
 332
 333		if (variant->domain_children == OTHER_SANDBOX)
 334			create_fs_domain(_metadata);
 335		else if (variant->domain_children == SCOPE_SANDBOX)
 336			create_scoped_domain(
 337				_metadata, LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
 338
 339		grand_child = fork();
 340		ASSERT_LE(0, grand_child);
 341		if (grand_child == 0) {
 342			char buf;
 343			int stream_err, dgram_err, stream_errno, dgram_errno;
 344			int stream_client, dgram_client;
 345
 346			EXPECT_EQ(0, close(pipe_parent[1]));
 347			EXPECT_EQ(0, close(pipe_child[1]));
 348
 349			if (variant->domain_grand_child == OTHER_SANDBOX)
 350				create_fs_domain(_metadata);
 351			else if (variant->domain_grand_child == SCOPE_SANDBOX)
 352				create_scoped_domain(
 353					_metadata,
 354					LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
 355
 356			stream_client = socket(AF_UNIX, SOCK_STREAM, 0);
 357			ASSERT_LE(0, stream_client);
 358			dgram_client = socket(AF_UNIX, SOCK_DGRAM, 0);
 359			ASSERT_LE(0, dgram_client);
 360
 361			ASSERT_EQ(1, read(pipe_child[0], &buf, 1));
 362			stream_err = connect(
 363				stream_client,
 364				&self->child_stream_address.unix_addr,
 365				self->child_stream_address.unix_addr_len);
 366			stream_errno = errno;
 367			dgram_err = connect(
 368				dgram_client,
 369				&self->child_dgram_address.unix_addr,
 370				self->child_dgram_address.unix_addr_len);
 371			dgram_errno = errno;
 372			if (can_connect_to_child) {
 373				EXPECT_EQ(0, stream_err);
 374				EXPECT_EQ(0, dgram_err);
 375			} else {
 376				EXPECT_EQ(-1, stream_err);
 377				EXPECT_EQ(-1, dgram_err);
 378				EXPECT_EQ(EPERM, stream_errno);
 379				EXPECT_EQ(EPERM, dgram_errno);
 380			}
 381
 382			EXPECT_EQ(0, close(stream_client));
 383			stream_client = socket(AF_UNIX, SOCK_STREAM, 0);
 384			ASSERT_LE(0, stream_client);
 385			/* Datagram sockets can "reconnect". */
 386
 387			ASSERT_EQ(1, read(pipe_parent[0], &buf, 1));
 388			stream_err = connect(
 389				stream_client,
 390				&self->parent_stream_address.unix_addr,
 391				self->parent_stream_address.unix_addr_len);
 392			stream_errno = errno;
 393			dgram_err = connect(
 394				dgram_client,
 395				&self->parent_dgram_address.unix_addr,
 396				self->parent_dgram_address.unix_addr_len);
 397			dgram_errno = errno;
 398			if (can_connect_to_parent) {
 399				EXPECT_EQ(0, stream_err);
 400				EXPECT_EQ(0, dgram_err);
 401			} else {
 402				EXPECT_EQ(-1, stream_err);
 403				EXPECT_EQ(-1, dgram_err);
 404				EXPECT_EQ(EPERM, stream_errno);
 405				EXPECT_EQ(EPERM, dgram_errno);
 406			}
 407			EXPECT_EQ(0, close(stream_client));
 408			EXPECT_EQ(0, close(dgram_client));
 409
 410			_exit(_metadata->exit_code);
 411			return;
 412		}
 413		EXPECT_EQ(0, close(pipe_child[0]));
 414		if (variant->domain_child == OTHER_SANDBOX)
 415			create_fs_domain(_metadata);
 416		else if (variant->domain_child == SCOPE_SANDBOX)
 417			create_scoped_domain(
 418				_metadata, LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
 419
 420		stream_server_child = socket(AF_UNIX, SOCK_STREAM, 0);
 421		ASSERT_LE(0, stream_server_child);
 422		dgram_server_child = socket(AF_UNIX, SOCK_DGRAM, 0);
 423		ASSERT_LE(0, dgram_server_child);
 424
 425		ASSERT_EQ(0, bind(stream_server_child,
 426				  &self->child_stream_address.unix_addr,
 427				  self->child_stream_address.unix_addr_len));
 428		ASSERT_EQ(0, bind(dgram_server_child,
 429				  &self->child_dgram_address.unix_addr,
 430				  self->child_dgram_address.unix_addr_len));
 431		ASSERT_EQ(0, listen(stream_server_child, backlog));
 432
 433		ASSERT_EQ(1, write(pipe_child[1], ".", 1));
 434		ASSERT_EQ(grand_child, waitpid(grand_child, &status, 0));
 435		EXPECT_EQ(0, close(stream_server_child))
 436		EXPECT_EQ(0, close(dgram_server_child));
 437		return;
 438	}
 439	EXPECT_EQ(0, close(pipe_parent[0]));
 440
 441	if (variant->domain_parent == OTHER_SANDBOX)
 442		create_fs_domain(_metadata);
 443	else if (variant->domain_parent == SCOPE_SANDBOX)
 444		create_scoped_domain(_metadata,
 445				     LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
 446
 447	stream_server_parent = socket(AF_UNIX, SOCK_STREAM, 0);
 448	ASSERT_LE(0, stream_server_parent);
 449	dgram_server_parent = socket(AF_UNIX, SOCK_DGRAM, 0);
 450	ASSERT_LE(0, dgram_server_parent);
 451	ASSERT_EQ(0, bind(stream_server_parent,
 452			  &self->parent_stream_address.unix_addr,
 453			  self->parent_stream_address.unix_addr_len));
 454	ASSERT_EQ(0, bind(dgram_server_parent,
 455			  &self->parent_dgram_address.unix_addr,
 456			  self->parent_dgram_address.unix_addr_len));
 457
 458	ASSERT_EQ(0, listen(stream_server_parent, backlog));
 459
 460	ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
 461	ASSERT_EQ(child, waitpid(child, &status, 0));
 462	EXPECT_EQ(0, close(stream_server_parent));
 463	EXPECT_EQ(0, close(dgram_server_parent));
 464
 465	if (WIFSIGNALED(status) || !WIFEXITED(status) ||
 466	    WEXITSTATUS(status) != EXIT_SUCCESS)
 467		_metadata->exit_code = KSFT_FAIL;
 468}
 469
 470FIXTURE(outside_socket)
 471{
 472	struct service_fixture address, transit_address;
 473};
 474
 475FIXTURE_VARIANT(outside_socket)
 476{
 477	const bool child_socket;
 478	const int type;
 479};
 480
 481/* clang-format off */
 482FIXTURE_VARIANT_ADD(outside_socket, allow_dgram_child) {
 483	/* clang-format on */
 484	.child_socket = true,
 485	.type = SOCK_DGRAM,
 486};
 487
 488/* clang-format off */
 489FIXTURE_VARIANT_ADD(outside_socket, deny_dgram_server) {
 490	/* clang-format on */
 491	.child_socket = false,
 492	.type = SOCK_DGRAM,
 493};
 494
 495/* clang-format off */
 496FIXTURE_VARIANT_ADD(outside_socket, allow_stream_child) {
 497	/* clang-format on */
 498	.child_socket = true,
 499	.type = SOCK_STREAM,
 500};
 501
 502/* clang-format off */
 503FIXTURE_VARIANT_ADD(outside_socket, deny_stream_server) {
 504	/* clang-format on */
 505	.child_socket = false,
 506	.type = SOCK_STREAM,
 507};
 508
 509FIXTURE_SETUP(outside_socket)
 510{
 511	drop_caps(_metadata);
 512
 513	memset(&self->transit_address, 0, sizeof(self->transit_address));
 514	set_unix_address(&self->transit_address, 0);
 515	memset(&self->address, 0, sizeof(self->address));
 516	set_unix_address(&self->address, 1);
 517}
 518
 519FIXTURE_TEARDOWN(outside_socket)
 520{
 521}
 522
 523/*
 524 * Test unix_stream_connect and unix_may_send for parent and child processes
 525 * when connecting socket has different domain than the process using it.
 526 */
 527TEST_F(outside_socket, socket_with_different_domain)
 528{
 529	pid_t child;
 530	int err, status;
 531	int pipe_child[2], pipe_parent[2];
 532	char buf_parent;
 533	int server_socket;
 534
 535	ASSERT_EQ(0, pipe2(pipe_child, O_CLOEXEC));
 536	ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC));
 537
 538	child = fork();
 539	ASSERT_LE(0, child);
 540	if (child == 0) {
 541		int client_socket;
 542		char buf_child;
 543
 544		EXPECT_EQ(0, close(pipe_parent[1]));
 545		EXPECT_EQ(0, close(pipe_child[0]));
 546
 547		/* Client always has a domain. */
 548		create_scoped_domain(_metadata,
 549				     LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
 550
 551		if (variant->child_socket) {
 552			int data_socket, passed_socket, stream_server;
 553
 554			passed_socket = socket(AF_UNIX, variant->type, 0);
 555			ASSERT_LE(0, passed_socket);
 556			stream_server = socket(AF_UNIX, SOCK_STREAM, 0);
 557			ASSERT_LE(0, stream_server);
 558			ASSERT_EQ(0, bind(stream_server,
 559					  &self->transit_address.unix_addr,
 560					  self->transit_address.unix_addr_len));
 561			ASSERT_EQ(0, listen(stream_server, backlog));
 562			ASSERT_EQ(1, write(pipe_child[1], ".", 1));
 563			data_socket = accept(stream_server, NULL, NULL);
 564			ASSERT_LE(0, data_socket);
 565			ASSERT_EQ(0, send_fd(data_socket, passed_socket));
 566			EXPECT_EQ(0, close(passed_socket));
 567			EXPECT_EQ(0, close(stream_server));
 568		}
 569
 570		client_socket = socket(AF_UNIX, variant->type, 0);
 571		ASSERT_LE(0, client_socket);
 572
 573		/* Waits for parent signal for connection. */
 574		ASSERT_EQ(1, read(pipe_parent[0], &buf_child, 1));
 575		err = connect(client_socket, &self->address.unix_addr,
 576			      self->address.unix_addr_len);
 577		if (variant->child_socket) {
 578			EXPECT_EQ(0, err);
 579		} else {
 580			EXPECT_EQ(-1, err);
 581			EXPECT_EQ(EPERM, errno);
 582		}
 583		EXPECT_EQ(0, close(client_socket));
 584		_exit(_metadata->exit_code);
 585		return;
 586	}
 587	EXPECT_EQ(0, close(pipe_child[1]));
 588	EXPECT_EQ(0, close(pipe_parent[0]));
 589
 590	if (variant->child_socket) {
 591		int client_child = socket(AF_UNIX, SOCK_STREAM, 0);
 592
 593		ASSERT_LE(0, client_child);
 594		ASSERT_EQ(1, read(pipe_child[0], &buf_parent, 1));
 595		ASSERT_EQ(0, connect(client_child,
 596				     &self->transit_address.unix_addr,
 597				     self->transit_address.unix_addr_len));
 598		server_socket = recv_fd(client_child);
 599		EXPECT_EQ(0, close(client_child));
 600	} else {
 601		server_socket = socket(AF_UNIX, variant->type, 0);
 602	}
 603	ASSERT_LE(0, server_socket);
 604
 605	/* Server always has a domain. */
 606	create_scoped_domain(_metadata, LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
 607
 608	ASSERT_EQ(0, bind(server_socket, &self->address.unix_addr,
 609			  self->address.unix_addr_len));
 610	if (variant->type == SOCK_STREAM)
 611		ASSERT_EQ(0, listen(server_socket, backlog));
 612
 613	/* Signals to child that the parent is listening. */
 614	ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
 615
 616	ASSERT_EQ(child, waitpid(child, &status, 0));
 617	EXPECT_EQ(0, close(server_socket));
 618
 619	if (WIFSIGNALED(status) || !WIFEXITED(status) ||
 620	    WEXITSTATUS(status) != EXIT_SUCCESS)
 621		_metadata->exit_code = KSFT_FAIL;
 622}
 623
 624static const char stream_path[] = TMP_DIR "/stream.sock";
 625static const char dgram_path[] = TMP_DIR "/dgram.sock";
 626
 627/* clang-format off */
 628FIXTURE(various_address_sockets) {};
 629/* clang-format on */
 630
 631FIXTURE_VARIANT(various_address_sockets)
 632{
 633	const int domain;
 634};
 635
 636/* clang-format off */
 637FIXTURE_VARIANT_ADD(various_address_sockets, pathname_socket_scoped_domain) {
 638	/* clang-format on */
 639	.domain = SCOPE_SANDBOX,
 640};
 641
 642/* clang-format off */
 643FIXTURE_VARIANT_ADD(various_address_sockets, pathname_socket_other_domain) {
 644	/* clang-format on */
 645	.domain = OTHER_SANDBOX,
 646};
 647
 648/* clang-format off */
 649FIXTURE_VARIANT_ADD(various_address_sockets, pathname_socket_no_domain) {
 650	/* clang-format on */
 651	.domain = NO_SANDBOX,
 652};
 653
 654FIXTURE_SETUP(various_address_sockets)
 655{
 656	drop_caps(_metadata);
 657
 658	umask(0077);
 659	ASSERT_EQ(0, mkdir(TMP_DIR, 0700));
 660}
 661
 662FIXTURE_TEARDOWN(various_address_sockets)
 663{
 664	EXPECT_EQ(0, unlink(stream_path));
 665	EXPECT_EQ(0, unlink(dgram_path));
 666	EXPECT_EQ(0, rmdir(TMP_DIR));
 667}
 668
 669TEST_F(various_address_sockets, scoped_pathname_sockets)
 670{
 671	socklen_t size_stream, size_dgram;
 672	pid_t child;
 673	int status;
 674	char buf_child, buf_parent;
 675	int pipe_parent[2];
 676	int unnamed_sockets[2];
 677	int stream_pathname_socket, dgram_pathname_socket,
 678		stream_abstract_socket, dgram_abstract_socket, data_socket;
 679	struct service_fixture stream_abstract_addr, dgram_abstract_addr;
 680	struct sockaddr_un stream_pathname_addr = {
 681		.sun_family = AF_UNIX,
 682	};
 683	struct sockaddr_un dgram_pathname_addr = {
 684		.sun_family = AF_UNIX,
 685	};
 686
 687	/* Pathname address. */
 688	snprintf(stream_pathname_addr.sun_path,
 689		 sizeof(stream_pathname_addr.sun_path), "%s", stream_path);
 690	size_stream = offsetof(struct sockaddr_un, sun_path) +
 691		      strlen(stream_pathname_addr.sun_path);
 692	snprintf(dgram_pathname_addr.sun_path,
 693		 sizeof(dgram_pathname_addr.sun_path), "%s", dgram_path);
 694	size_dgram = offsetof(struct sockaddr_un, sun_path) +
 695		     strlen(dgram_pathname_addr.sun_path);
 696
 697	/* Abstract address. */
 698	memset(&stream_abstract_addr, 0, sizeof(stream_abstract_addr));
 699	set_unix_address(&stream_abstract_addr, 0);
 700	memset(&dgram_abstract_addr, 0, sizeof(dgram_abstract_addr));
 701	set_unix_address(&dgram_abstract_addr, 1);
 702
 703	/* Unnamed address for datagram socket. */
 704	ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_DGRAM, 0, unnamed_sockets));
 705
 706	ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC));
 707
 708	child = fork();
 709	ASSERT_LE(0, child);
 710	if (child == 0) {
 711		int err;
 712
 713		EXPECT_EQ(0, close(pipe_parent[1]));
 714		EXPECT_EQ(0, close(unnamed_sockets[1]));
 715
 716		if (variant->domain == SCOPE_SANDBOX)
 717			create_scoped_domain(
 718				_metadata, LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
 719		else if (variant->domain == OTHER_SANDBOX)
 720			create_fs_domain(_metadata);
 721
 722		/* Waits for parent to listen. */
 723		ASSERT_EQ(1, read(pipe_parent[0], &buf_child, 1));
 724		EXPECT_EQ(0, close(pipe_parent[0]));
 725
 726		/* Checks that we can send data through a datagram socket. */
 727		ASSERT_EQ(1, write(unnamed_sockets[0], "a", 1));
 728		EXPECT_EQ(0, close(unnamed_sockets[0]));
 729
 730		/* Connects with pathname sockets. */
 731		stream_pathname_socket = socket(AF_UNIX, SOCK_STREAM, 0);
 732		ASSERT_LE(0, stream_pathname_socket);
 733		ASSERT_EQ(0, connect(stream_pathname_socket,
 734				     &stream_pathname_addr, size_stream));
 735		ASSERT_EQ(1, write(stream_pathname_socket, "b", 1));
 736		EXPECT_EQ(0, close(stream_pathname_socket));
 737
 738		/* Sends without connection. */
 739		dgram_pathname_socket = socket(AF_UNIX, SOCK_DGRAM, 0);
 740		ASSERT_LE(0, dgram_pathname_socket);
 741		err = sendto(dgram_pathname_socket, "c", 1, 0,
 742			     &dgram_pathname_addr, size_dgram);
 743		EXPECT_EQ(1, err);
 744
 745		/* Sends with connection. */
 746		ASSERT_EQ(0, connect(dgram_pathname_socket,
 747				     &dgram_pathname_addr, size_dgram));
 748		ASSERT_EQ(1, write(dgram_pathname_socket, "d", 1));
 749		EXPECT_EQ(0, close(dgram_pathname_socket));
 750
 751		/* Connects with abstract sockets. */
 752		stream_abstract_socket = socket(AF_UNIX, SOCK_STREAM, 0);
 753		ASSERT_LE(0, stream_abstract_socket);
 754		err = connect(stream_abstract_socket,
 755			      &stream_abstract_addr.unix_addr,
 756			      stream_abstract_addr.unix_addr_len);
 757		if (variant->domain == SCOPE_SANDBOX) {
 758			EXPECT_EQ(-1, err);
 759			EXPECT_EQ(EPERM, errno);
 760		} else {
 761			EXPECT_EQ(0, err);
 762			ASSERT_EQ(1, write(stream_abstract_socket, "e", 1));
 763		}
 764		EXPECT_EQ(0, close(stream_abstract_socket));
 765
 766		/* Sends without connection. */
 767		dgram_abstract_socket = socket(AF_UNIX, SOCK_DGRAM, 0);
 768		ASSERT_LE(0, dgram_abstract_socket);
 769		err = sendto(dgram_abstract_socket, "f", 1, 0,
 770			     &dgram_abstract_addr.unix_addr,
 771			     dgram_abstract_addr.unix_addr_len);
 772		if (variant->domain == SCOPE_SANDBOX) {
 773			EXPECT_EQ(-1, err);
 774			EXPECT_EQ(EPERM, errno);
 775		} else {
 776			EXPECT_EQ(1, err);
 777		}
 778
 779		/* Sends with connection. */
 780		err = connect(dgram_abstract_socket,
 781			      &dgram_abstract_addr.unix_addr,
 782			      dgram_abstract_addr.unix_addr_len);
 783		if (variant->domain == SCOPE_SANDBOX) {
 784			EXPECT_EQ(-1, err);
 785			EXPECT_EQ(EPERM, errno);
 786		} else {
 787			EXPECT_EQ(0, err);
 788			ASSERT_EQ(1, write(dgram_abstract_socket, "g", 1));
 789		}
 790		EXPECT_EQ(0, close(dgram_abstract_socket));
 791
 792		_exit(_metadata->exit_code);
 793		return;
 794	}
 795	EXPECT_EQ(0, close(pipe_parent[0]));
 796	EXPECT_EQ(0, close(unnamed_sockets[0]));
 797
 798	/* Sets up pathname servers. */
 799	stream_pathname_socket = socket(AF_UNIX, SOCK_STREAM, 0);
 800	ASSERT_LE(0, stream_pathname_socket);
 801	ASSERT_EQ(0, bind(stream_pathname_socket, &stream_pathname_addr,
 802			  size_stream));
 803	ASSERT_EQ(0, listen(stream_pathname_socket, backlog));
 804
 805	dgram_pathname_socket = socket(AF_UNIX, SOCK_DGRAM, 0);
 806	ASSERT_LE(0, dgram_pathname_socket);
 807	ASSERT_EQ(0, bind(dgram_pathname_socket, &dgram_pathname_addr,
 808			  size_dgram));
 809
 810	/* Sets up abstract servers. */
 811	stream_abstract_socket = socket(AF_UNIX, SOCK_STREAM, 0);
 812	ASSERT_LE(0, stream_abstract_socket);
 813	ASSERT_EQ(0,
 814		  bind(stream_abstract_socket, &stream_abstract_addr.unix_addr,
 815		       stream_abstract_addr.unix_addr_len));
 816
 817	dgram_abstract_socket = socket(AF_UNIX, SOCK_DGRAM, 0);
 818	ASSERT_LE(0, dgram_abstract_socket);
 819	ASSERT_EQ(0, bind(dgram_abstract_socket, &dgram_abstract_addr.unix_addr,
 820			  dgram_abstract_addr.unix_addr_len));
 821	ASSERT_EQ(0, listen(stream_abstract_socket, backlog));
 822
 823	ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
 824	EXPECT_EQ(0, close(pipe_parent[1]));
 825
 826	/* Reads from unnamed socket. */
 827	ASSERT_EQ(1, read(unnamed_sockets[1], &buf_parent, sizeof(buf_parent)));
 828	ASSERT_EQ('a', buf_parent);
 829	EXPECT_LE(0, close(unnamed_sockets[1]));
 830
 831	/* Reads from pathname sockets. */
 832	data_socket = accept(stream_pathname_socket, NULL, NULL);
 833	ASSERT_LE(0, data_socket);
 834	ASSERT_EQ(1, read(data_socket, &buf_parent, sizeof(buf_parent)));
 835	ASSERT_EQ('b', buf_parent);
 836	EXPECT_EQ(0, close(data_socket));
 837	EXPECT_EQ(0, close(stream_pathname_socket));
 838
 839	ASSERT_EQ(1,
 840		  read(dgram_pathname_socket, &buf_parent, sizeof(buf_parent)));
 841	ASSERT_EQ('c', buf_parent);
 842	ASSERT_EQ(1,
 843		  read(dgram_pathname_socket, &buf_parent, sizeof(buf_parent)));
 844	ASSERT_EQ('d', buf_parent);
 845	EXPECT_EQ(0, close(dgram_pathname_socket));
 846
 847	if (variant->domain != SCOPE_SANDBOX) {
 848		/* Reads from abstract sockets if allowed to send. */
 849		data_socket = accept(stream_abstract_socket, NULL, NULL);
 850		ASSERT_LE(0, data_socket);
 851		ASSERT_EQ(1,
 852			  read(data_socket, &buf_parent, sizeof(buf_parent)));
 853		ASSERT_EQ('e', buf_parent);
 854		EXPECT_EQ(0, close(data_socket));
 855
 856		ASSERT_EQ(1, read(dgram_abstract_socket, &buf_parent,
 857				  sizeof(buf_parent)));
 858		ASSERT_EQ('f', buf_parent);
 859		ASSERT_EQ(1, read(dgram_abstract_socket, &buf_parent,
 860				  sizeof(buf_parent)));
 861		ASSERT_EQ('g', buf_parent);
 862	}
 863
 864	/* Waits for all abstract socket tests. */
 865	ASSERT_EQ(child, waitpid(child, &status, 0));
 866	EXPECT_EQ(0, close(stream_abstract_socket));
 867	EXPECT_EQ(0, close(dgram_abstract_socket));
 868
 869	if (WIFSIGNALED(status) || !WIFEXITED(status) ||
 870	    WEXITSTATUS(status) != EXIT_SUCCESS)
 871		_metadata->exit_code = KSFT_FAIL;
 872}
 873
 874TEST(datagram_sockets)
 875{
 876	struct service_fixture connected_addr, non_connected_addr;
 877	int server_conn_socket, server_unconn_socket;
 878	int pipe_parent[2], pipe_child[2];
 879	int status;
 880	char buf;
 881	pid_t child;
 882
 883	drop_caps(_metadata);
 884	memset(&connected_addr, 0, sizeof(connected_addr));
 885	set_unix_address(&connected_addr, 0);
 886	memset(&non_connected_addr, 0, sizeof(non_connected_addr));
 887	set_unix_address(&non_connected_addr, 1);
 888
 889	ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC));
 890	ASSERT_EQ(0, pipe2(pipe_child, O_CLOEXEC));
 891
 892	child = fork();
 893	ASSERT_LE(0, child);
 894	if (child == 0) {
 895		int client_conn_socket, client_unconn_socket;
 896
 897		EXPECT_EQ(0, close(pipe_parent[1]));
 898		EXPECT_EQ(0, close(pipe_child[0]));
 899
 900		client_conn_socket = socket(AF_UNIX, SOCK_DGRAM, 0);
 901		client_unconn_socket = socket(AF_UNIX, SOCK_DGRAM, 0);
 902		ASSERT_LE(0, client_conn_socket);
 903		ASSERT_LE(0, client_unconn_socket);
 904
 905		/* Waits for parent to listen. */
 906		ASSERT_EQ(1, read(pipe_parent[0], &buf, 1));
 907		ASSERT_EQ(0,
 908			  connect(client_conn_socket, &connected_addr.unix_addr,
 909				  connected_addr.unix_addr_len));
 910
 911		/*
 912		 * Both connected and non-connected sockets can send data when
 913		 * the domain is not scoped.
 914		 */
 915		ASSERT_EQ(1, send(client_conn_socket, ".", 1, 0));
 916		ASSERT_EQ(1, sendto(client_unconn_socket, ".", 1, 0,
 917				    &non_connected_addr.unix_addr,
 918				    non_connected_addr.unix_addr_len));
 919		ASSERT_EQ(1, write(pipe_child[1], ".", 1));
 920
 921		/* Scopes the domain. */
 922		create_scoped_domain(_metadata,
 923				     LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
 924
 925		/*
 926		 * Connected socket sends data to the receiver, but the
 927		 * non-connected socket must fail to send data.
 928		 */
 929		ASSERT_EQ(1, send(client_conn_socket, ".", 1, 0));
 930		ASSERT_EQ(-1, sendto(client_unconn_socket, ".", 1, 0,
 931				     &non_connected_addr.unix_addr,
 932				     non_connected_addr.unix_addr_len));
 933		ASSERT_EQ(EPERM, errno);
 934		ASSERT_EQ(1, write(pipe_child[1], ".", 1));
 935
 936		EXPECT_EQ(0, close(client_conn_socket));
 937		EXPECT_EQ(0, close(client_unconn_socket));
 938		_exit(_metadata->exit_code);
 939		return;
 940	}
 941	EXPECT_EQ(0, close(pipe_parent[0]));
 942	EXPECT_EQ(0, close(pipe_child[1]));
 943
 944	server_conn_socket = socket(AF_UNIX, SOCK_DGRAM, 0);
 945	server_unconn_socket = socket(AF_UNIX, SOCK_DGRAM, 0);
 946	ASSERT_LE(0, server_conn_socket);
 947	ASSERT_LE(0, server_unconn_socket);
 948
 949	ASSERT_EQ(0, bind(server_conn_socket, &connected_addr.unix_addr,
 950			  connected_addr.unix_addr_len));
 951	ASSERT_EQ(0, bind(server_unconn_socket, &non_connected_addr.unix_addr,
 952			  non_connected_addr.unix_addr_len));
 953	ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
 954
 955	/* Waits for child to test. */
 956	ASSERT_EQ(1, read(pipe_child[0], &buf, 1));
 957	ASSERT_EQ(1, recv(server_conn_socket, &buf, 1, 0));
 958	ASSERT_EQ(1, recv(server_unconn_socket, &buf, 1, 0));
 959
 960	/*
 961	 * Connected datagram socket will receive data, but
 962	 * non-connected datagram socket does not receive data.
 963	 */
 964	ASSERT_EQ(1, read(pipe_child[0], &buf, 1));
 965	ASSERT_EQ(1, recv(server_conn_socket, &buf, 1, 0));
 966
 967	/* Waits for all tests to finish. */
 968	ASSERT_EQ(child, waitpid(child, &status, 0));
 969	EXPECT_EQ(0, close(server_conn_socket));
 970	EXPECT_EQ(0, close(server_unconn_socket));
 971
 972	if (WIFSIGNALED(status) || !WIFEXITED(status) ||
 973	    WEXITSTATUS(status) != EXIT_SUCCESS)
 974		_metadata->exit_code = KSFT_FAIL;
 975}
 976
 977TEST(self_connect)
 978{
 979	struct service_fixture connected_addr, non_connected_addr;
 980	int connected_socket, non_connected_socket, status;
 981	pid_t child;
 982
 983	drop_caps(_metadata);
 984	memset(&connected_addr, 0, sizeof(connected_addr));
 985	set_unix_address(&connected_addr, 0);
 986	memset(&non_connected_addr, 0, sizeof(non_connected_addr));
 987	set_unix_address(&non_connected_addr, 1);
 988
 989	connected_socket = socket(AF_UNIX, SOCK_DGRAM, 0);
 990	non_connected_socket = socket(AF_UNIX, SOCK_DGRAM, 0);
 991	ASSERT_LE(0, connected_socket);
 992	ASSERT_LE(0, non_connected_socket);
 993
 994	ASSERT_EQ(0, bind(connected_socket, &connected_addr.unix_addr,
 995			  connected_addr.unix_addr_len));
 996	ASSERT_EQ(0, bind(non_connected_socket, &non_connected_addr.unix_addr,
 997			  non_connected_addr.unix_addr_len));
 998
 999	child = fork();
1000	ASSERT_LE(0, child);
1001	if (child == 0) {
1002		/* Child's domain is scoped. */
1003		create_scoped_domain(_metadata,
1004				     LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
1005
1006		/*
1007		 * The child inherits the sockets, and cannot connect or
1008		 * send data to them.
1009		 */
1010		ASSERT_EQ(-1,
1011			  connect(connected_socket, &connected_addr.unix_addr,
1012				  connected_addr.unix_addr_len));
1013		ASSERT_EQ(EPERM, errno);
1014
1015		ASSERT_EQ(-1, sendto(connected_socket, ".", 1, 0,
1016				     &connected_addr.unix_addr,
1017				     connected_addr.unix_addr_len));
1018		ASSERT_EQ(EPERM, errno);
1019
1020		ASSERT_EQ(-1, sendto(non_connected_socket, ".", 1, 0,
1021				     &non_connected_addr.unix_addr,
1022				     non_connected_addr.unix_addr_len));
1023		ASSERT_EQ(EPERM, errno);
1024
1025		EXPECT_EQ(0, close(connected_socket));
1026		EXPECT_EQ(0, close(non_connected_socket));
1027		_exit(_metadata->exit_code);
1028		return;
1029	}
1030
1031	/* Waits for all tests to finish. */
1032	ASSERT_EQ(child, waitpid(child, &status, 0));
1033	EXPECT_EQ(0, close(connected_socket));
1034	EXPECT_EQ(0, close(non_connected_socket));
1035
1036	if (WIFSIGNALED(status) || !WIFEXITED(status) ||
1037	    WEXITSTATUS(status) != EXIT_SUCCESS)
1038		_metadata->exit_code = KSFT_FAIL;
1039}
1040
1041TEST_HARNESS_MAIN