Merge tag 'trace-printf-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/trace...
[drm/drm-misc.git] / tools / testing / selftests / landlock / scoped_abstract_unix_test.c
bloba6b59d2ab1b42b125919daca2d7c7d2788f8d37c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Landlock tests - Abstract UNIX socket
5 * Copyright © 2024 Tahera Fahimi <fahimitahera@gmail.com>
6 */
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>
23 #include "common.h"
24 #include "scoped_common.h"
26 /* Number of pending connections queue to be hold. */
27 const short backlog = 10;
29 static void create_fs_domain(struct __test_metadata *const _metadata)
31 int ruleset_fd;
32 struct landlock_ruleset_attr ruleset_attr = {
33 .handled_access_fs = LANDLOCK_ACCESS_FS_READ_DIR,
36 ruleset_fd =
37 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
38 EXPECT_LE(0, ruleset_fd)
40 TH_LOG("Failed to create a ruleset: %s", strerror(errno));
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));
47 FIXTURE(scoped_domains)
49 struct service_fixture stream_address, dgram_address;
52 #include "scoped_base_variants.h"
54 FIXTURE_SETUP(scoped_domains)
56 drop_caps(_metadata);
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);
64 FIXTURE_TEARDOWN(scoped_domains)
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.
72 TEST_F(scoped_domains, connect_to_parent)
74 pid_t child;
75 bool can_connect_to_parent;
76 int status;
77 int pipe_parent[2];
78 int stream_server, dgram_server;
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.
85 can_connect_to_parent = !variant->domain_child;
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;
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;
102 EXPECT_EQ(0, close(pipe_parent[1]));
103 if (variant->domain_child)
104 create_scoped_domain(
105 _metadata, LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
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);
112 /* Waits for the server. */
113 ASSERT_EQ(1, read(pipe_parent[0], &buf_child, 1));
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);
123 EXPECT_EQ(0, close(stream_client));
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);
133 EXPECT_EQ(0, close(dgram_client));
134 _exit(_metadata->exit_code);
135 return;
137 EXPECT_EQ(0, close(pipe_parent[0]));
138 if (variant->domain_parent)
139 create_scoped_domain(_metadata,
140 LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
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));
152 /* Signals to child that the parent is listening. */
153 ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
155 ASSERT_EQ(child, waitpid(child, &status, 0));
156 EXPECT_EQ(0, close(stream_server));
157 EXPECT_EQ(0, close(dgram_server));
159 if (WIFSIGNALED(status) || !WIFEXITED(status) ||
160 WEXITSTATUS(status) != EXIT_SUCCESS)
161 _metadata->exit_code = KSFT_FAIL;
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.
168 TEST_F(scoped_domains, connect_to_child)
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;
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.
182 can_connect_to_child = !variant->domain_parent;
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;
193 child = fork();
194 ASSERT_LE(0, child);
195 if (child == 0) {
196 int stream_server, dgram_server;
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);
204 /* Waits for the parent to be in a domain, if any. */
205 ASSERT_EQ(1, read(pipe_parent[0], &buf, 1));
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));
218 /* Signals to the parent that child is listening. */
219 ASSERT_EQ(1, write(pipe_child[1], ".", 1));
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;
228 EXPECT_EQ(0, close(pipe_child[1]));
229 EXPECT_EQ(0, close(pipe_parent[0]));
231 if (variant->domain_parent)
232 create_scoped_domain(_metadata,
233 LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
235 /* Signals that the parent is in a domain, if any. */
236 ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
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);
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);
260 ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
261 EXPECT_EQ(0, close(stream_client));
262 EXPECT_EQ(0, close(dgram_client));
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;
270 FIXTURE(scoped_vs_unscoped)
272 struct service_fixture parent_stream_address, parent_dgram_address,
273 child_stream_address, child_dgram_address;
276 #include "scoped_multiple_domain_variants.h"
278 FIXTURE_SETUP(scoped_vs_unscoped)
280 drop_caps(_metadata);
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);
296 FIXTURE_TEARDOWN(scoped_vs_unscoped)
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.
304 TEST_F(scoped_vs_unscoped, unix_scoping)
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;
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));
316 ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC));
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);
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;
331 ASSERT_EQ(0, pipe2(pipe_child, O_CLOEXEC));
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);
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;
346 EXPECT_EQ(0, close(pipe_parent[1]));
347 EXPECT_EQ(0, close(pipe_child[1]));
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);
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);
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);
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". */
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);
407 EXPECT_EQ(0, close(stream_client));
408 EXPECT_EQ(0, close(dgram_client));
410 _exit(_metadata->exit_code);
411 return;
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);
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);
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));
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;
439 EXPECT_EQ(0, close(pipe_parent[0]));
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);
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));
458 ASSERT_EQ(0, listen(stream_server_parent, backlog));
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));
465 if (WIFSIGNALED(status) || !WIFEXITED(status) ||
466 WEXITSTATUS(status) != EXIT_SUCCESS)
467 _metadata->exit_code = KSFT_FAIL;
470 FIXTURE(outside_socket)
472 struct service_fixture address, transit_address;
475 FIXTURE_VARIANT(outside_socket)
477 const bool child_socket;
478 const int type;
481 /* clang-format off */
482 FIXTURE_VARIANT_ADD(outside_socket, allow_dgram_child) {
483 /* clang-format on */
484 .child_socket = true,
485 .type = SOCK_DGRAM,
488 /* clang-format off */
489 FIXTURE_VARIANT_ADD(outside_socket, deny_dgram_server) {
490 /* clang-format on */
491 .child_socket = false,
492 .type = SOCK_DGRAM,
495 /* clang-format off */
496 FIXTURE_VARIANT_ADD(outside_socket, allow_stream_child) {
497 /* clang-format on */
498 .child_socket = true,
499 .type = SOCK_STREAM,
502 /* clang-format off */
503 FIXTURE_VARIANT_ADD(outside_socket, deny_stream_server) {
504 /* clang-format on */
505 .child_socket = false,
506 .type = SOCK_STREAM,
509 FIXTURE_SETUP(outside_socket)
511 drop_caps(_metadata);
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);
519 FIXTURE_TEARDOWN(outside_socket)
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.
527 TEST_F(outside_socket, socket_with_different_domain)
529 pid_t child;
530 int err, status;
531 int pipe_child[2], pipe_parent[2];
532 char buf_parent;
533 int server_socket;
535 ASSERT_EQ(0, pipe2(pipe_child, O_CLOEXEC));
536 ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC));
538 child = fork();
539 ASSERT_LE(0, child);
540 if (child == 0) {
541 int client_socket;
542 char buf_child;
544 EXPECT_EQ(0, close(pipe_parent[1]));
545 EXPECT_EQ(0, close(pipe_child[0]));
547 /* Client always has a domain. */
548 create_scoped_domain(_metadata,
549 LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
551 if (variant->child_socket) {
552 int data_socket, passed_socket, stream_server;
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));
570 client_socket = socket(AF_UNIX, variant->type, 0);
571 ASSERT_LE(0, client_socket);
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);
583 EXPECT_EQ(0, close(client_socket));
584 _exit(_metadata->exit_code);
585 return;
587 EXPECT_EQ(0, close(pipe_child[1]));
588 EXPECT_EQ(0, close(pipe_parent[0]));
590 if (variant->child_socket) {
591 int client_child = socket(AF_UNIX, SOCK_STREAM, 0);
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);
603 ASSERT_LE(0, server_socket);
605 /* Server always has a domain. */
606 create_scoped_domain(_metadata, LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
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));
613 /* Signals to child that the parent is listening. */
614 ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
616 ASSERT_EQ(child, waitpid(child, &status, 0));
617 EXPECT_EQ(0, close(server_socket));
619 if (WIFSIGNALED(status) || !WIFEXITED(status) ||
620 WEXITSTATUS(status) != EXIT_SUCCESS)
621 _metadata->exit_code = KSFT_FAIL;
624 static const char stream_path[] = TMP_DIR "/stream.sock";
625 static const char dgram_path[] = TMP_DIR "/dgram.sock";
627 /* clang-format off */
628 FIXTURE(various_address_sockets) {};
629 /* clang-format on */
631 FIXTURE_VARIANT(various_address_sockets)
633 const int domain;
636 /* clang-format off */
637 FIXTURE_VARIANT_ADD(various_address_sockets, pathname_socket_scoped_domain) {
638 /* clang-format on */
639 .domain = SCOPE_SANDBOX,
642 /* clang-format off */
643 FIXTURE_VARIANT_ADD(various_address_sockets, pathname_socket_other_domain) {
644 /* clang-format on */
645 .domain = OTHER_SANDBOX,
648 /* clang-format off */
649 FIXTURE_VARIANT_ADD(various_address_sockets, pathname_socket_no_domain) {
650 /* clang-format on */
651 .domain = NO_SANDBOX,
654 FIXTURE_SETUP(various_address_sockets)
656 drop_caps(_metadata);
658 umask(0077);
659 ASSERT_EQ(0, mkdir(TMP_DIR, 0700));
662 FIXTURE_TEARDOWN(various_address_sockets)
664 EXPECT_EQ(0, unlink(stream_path));
665 EXPECT_EQ(0, unlink(dgram_path));
666 EXPECT_EQ(0, rmdir(TMP_DIR));
669 TEST_F(various_address_sockets, scoped_pathname_sockets)
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,
683 struct sockaddr_un dgram_pathname_addr = {
684 .sun_family = AF_UNIX,
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);
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);
703 /* Unnamed address for datagram socket. */
704 ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_DGRAM, 0, unnamed_sockets));
706 ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC));
708 child = fork();
709 ASSERT_LE(0, child);
710 if (child == 0) {
711 int err;
713 EXPECT_EQ(0, close(pipe_parent[1]));
714 EXPECT_EQ(0, close(unnamed_sockets[1]));
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);
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]));
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]));
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));
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);
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));
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));
764 EXPECT_EQ(0, close(stream_abstract_socket));
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);
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));
790 EXPECT_EQ(0, close(dgram_abstract_socket));
792 _exit(_metadata->exit_code);
793 return;
795 EXPECT_EQ(0, close(pipe_parent[0]));
796 EXPECT_EQ(0, close(unnamed_sockets[0]));
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));
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));
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));
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));
823 ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
824 EXPECT_EQ(0, close(pipe_parent[1]));
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]));
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));
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));
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));
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);
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));
869 if (WIFSIGNALED(status) || !WIFEXITED(status) ||
870 WEXITSTATUS(status) != EXIT_SUCCESS)
871 _metadata->exit_code = KSFT_FAIL;
874 TEST(datagram_sockets)
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;
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);
889 ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC));
890 ASSERT_EQ(0, pipe2(pipe_child, O_CLOEXEC));
892 child = fork();
893 ASSERT_LE(0, child);
894 if (child == 0) {
895 int client_conn_socket, client_unconn_socket;
897 EXPECT_EQ(0, close(pipe_parent[1]));
898 EXPECT_EQ(0, close(pipe_child[0]));
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);
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));
912 * Both connected and non-connected sockets can send data when
913 * the domain is not scoped.
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));
921 /* Scopes the domain. */
922 create_scoped_domain(_metadata,
923 LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
926 * Connected socket sends data to the receiver, but the
927 * non-connected socket must fail to send data.
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));
936 EXPECT_EQ(0, close(client_conn_socket));
937 EXPECT_EQ(0, close(client_unconn_socket));
938 _exit(_metadata->exit_code);
939 return;
941 EXPECT_EQ(0, close(pipe_parent[0]));
942 EXPECT_EQ(0, close(pipe_child[1]));
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);
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));
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));
961 * Connected datagram socket will receive data, but
962 * non-connected datagram socket does not receive data.
964 ASSERT_EQ(1, read(pipe_child[0], &buf, 1));
965 ASSERT_EQ(1, recv(server_conn_socket, &buf, 1, 0));
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));
972 if (WIFSIGNALED(status) || !WIFEXITED(status) ||
973 WEXITSTATUS(status) != EXIT_SUCCESS)
974 _metadata->exit_code = KSFT_FAIL;
977 TEST(self_connect)
979 struct service_fixture connected_addr, non_connected_addr;
980 int connected_socket, non_connected_socket, status;
981 pid_t child;
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);
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);
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));
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);
1007 * The child inherits the sockets, and cannot connect or
1008 * send data to them.
1010 ASSERT_EQ(-1,
1011 connect(connected_socket, &connected_addr.unix_addr,
1012 connected_addr.unix_addr_len));
1013 ASSERT_EQ(EPERM, errno);
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);
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);
1025 EXPECT_EQ(0, close(connected_socket));
1026 EXPECT_EQ(0, close(non_connected_socket));
1027 _exit(_metadata->exit_code);
1028 return;
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));
1036 if (WIFSIGNALED(status) || !WIFEXITED(status) ||
1037 WEXITSTATUS(status) != EXIT_SUCCESS)
1038 _metadata->exit_code = KSFT_FAIL;
1041 TEST_HARNESS_MAIN