File Index
Files and directories
Sign in
FILE

scoped_abstract_unix_test.c

File preview with syntax highlighting.

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