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. */ 28 const short backlog = 10; 29 30 static 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 48 FIXTURE(scoped_domains) 49 { 50 struct service_fixture stream_address, dgram_address; 51 }; 52 53 #include "scoped_base_variants.h" 54 55 FIXTURE_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 65 FIXTURE_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 */ 73 TEST_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 */ 169 TEST_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 271 FIXTURE(scoped_audit) 272 { 273 struct service_fixture dgram_address; 274 struct audit_filter audit_filter; 275 int audit_fd; 276 }; 277 278 FIXTURE_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 291 FIXTURE_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 */ 303 TEST_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 316 ASSERT_EQ(0, pipe2(pipe_child, O_CLOEXEC)); 317 ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC)); 318 319 child = fork(); 320 ASSERT_LE(0, child); 321 if (child == 0) { 322 int dgram_server; 323 324 EXPECT_EQ(0, close(pipe_parent[1])); 325 EXPECT_EQ(0, close(pipe_child[0])); 326 327 /* Waits for the parent to be in a domain. */ 328 ASSERT_EQ(1, read(pipe_parent[0], &buf, 1)); 329 330 dgram_server = socket(AF_UNIX, SOCK_DGRAM, 0); 331 ASSERT_LE(0, dgram_server); 332 ASSERT_EQ(0, bind(dgram_server, &self->dgram_address.unix_addr, 333 self->dgram_address.unix_addr_len)); 334 335 /* Signals to the parent that child is listening. */ 336 ASSERT_EQ(1, write(pipe_child[1], ".", 1)); 337 338 /* Waits to connect. */ 339 ASSERT_EQ(1, read(pipe_parent[0], &buf, 1)); 340 EXPECT_EQ(0, close(dgram_server)); 341 _exit(_metadata->exit_code); 342 return; 343 } 344 EXPECT_EQ(0, close(pipe_child[1])); 345 EXPECT_EQ(0, close(pipe_parent[0])); 346 347 create_scoped_domain(_metadata, LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); 348 349 /* Signals that the parent is in a domain, if any. */ 350 ASSERT_EQ(1, write(pipe_parent[1], ".", 1)); 351 352 dgram_client = socket(AF_UNIX, SOCK_DGRAM, 0); 353 ASSERT_LE(0, dgram_client); 354 355 /* Waits for the child to listen */ 356 ASSERT_EQ(1, read(pipe_child[0], &buf, 1)); 357 err_dgram = connect(dgram_client, &self->dgram_address.unix_addr, 358 self->dgram_address.unix_addr_len); 359 EXPECT_EQ(-1, err_dgram); 360 EXPECT_EQ(EPERM, errno); 361 362 EXPECT_EQ( 363 0, 364 audit_match_record( 365 self->audit_fd, AUDIT_LANDLOCK_ACCESS, 366 REGEX_LANDLOCK_PREFIX 367 " blockers=scope\\.abstract_unix_socket path=" ABSTRACT_SOCKET_PATH_PREFIX 368 "[0-9A-F]\\+$", 369 NULL)); 370 371 ASSERT_EQ(1, write(pipe_parent[1], ".", 1)); 372 EXPECT_EQ(0, close(dgram_client)); 373 374 ASSERT_EQ(child, waitpid(child, &status, 0)); 375 if (WIFSIGNALED(status) || !WIFEXITED(status) || 376 WEXITSTATUS(status) != EXIT_SUCCESS) 377 _metadata->exit_code = KSFT_FAIL; 378 } 379 380 FIXTURE(scoped_vs_unscoped) 381 { 382 struct service_fixture parent_stream_address, parent_dgram_address, 383 child_stream_address, child_dgram_address; 384 }; 385 386 #include "scoped_multiple_domain_variants.h" 387 388 FIXTURE_SETUP(scoped_vs_unscoped) 389 { 390 drop_caps(_metadata); 391 392 memset(&self->parent_stream_address, 0, 393 sizeof(self->parent_stream_address)); 394 set_unix_address(&self->parent_stream_address, 0); 395 memset(&self->parent_dgram_address, 0, 396 sizeof(self->parent_dgram_address)); 397 set_unix_address(&self->parent_dgram_address, 1); 398 memset(&self->child_stream_address, 0, 399 sizeof(self->child_stream_address)); 400 set_unix_address(&self->child_stream_address, 2); 401 memset(&self->child_dgram_address, 0, 402 sizeof(self->child_dgram_address)); 403 set_unix_address(&self->child_dgram_address, 3); 404 } 405 406 FIXTURE_TEARDOWN(scoped_vs_unscoped) 407 { 408 } 409 410 /* 411 * Test unix_stream_connect and unix_may_send for parent, child and 412 * grand child processes when they can have scoped or non-scoped domains. 413 */ 414 TEST_F(scoped_vs_unscoped, unix_scoping) 415 { 416 pid_t child; 417 int status; 418 bool can_connect_to_parent, can_connect_to_child; 419 int pipe_parent[2]; 420 int stream_server_parent, dgram_server_parent; 421 422 can_connect_to_child = (variant->domain_grand_child != SCOPE_SANDBOX); 423 can_connect_to_parent = (can_connect_to_child && 424 (variant->domain_children != SCOPE_SANDBOX)); 425 426 ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC)); 427 428 if (variant->domain_all == OTHER_SANDBOX) 429 create_fs_domain(_metadata); 430 else if (variant->domain_all == SCOPE_SANDBOX) 431 create_scoped_domain(_metadata, 432 LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); 433 434 child = fork(); 435 ASSERT_LE(0, child); 436 if (child == 0) { 437 int stream_server_child, dgram_server_child; 438 int pipe_child[2]; 439 pid_t grand_child; 440 441 ASSERT_EQ(0, pipe2(pipe_child, O_CLOEXEC)); 442 443 if (variant->domain_children == OTHER_SANDBOX) 444 create_fs_domain(_metadata); 445 else if (variant->domain_children == SCOPE_SANDBOX) 446 create_scoped_domain( 447 _metadata, LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); 448 449 grand_child = fork(); 450 ASSERT_LE(0, grand_child); 451 if (grand_child == 0) { 452 char buf; 453 int stream_err, dgram_err, stream_errno, dgram_errno; 454 int stream_client, dgram_client; 455 456 EXPECT_EQ(0, close(pipe_parent[1])); 457 EXPECT_EQ(0, close(pipe_child[1])); 458 459 if (variant->domain_grand_child == OTHER_SANDBOX) 460 create_fs_domain(_metadata); 461 else if (variant->domain_grand_child == SCOPE_SANDBOX) 462 create_scoped_domain( 463 _metadata, 464 LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); 465 466 stream_client = socket(AF_UNIX, SOCK_STREAM, 0); 467 ASSERT_LE(0, stream_client); 468 dgram_client = socket(AF_UNIX, SOCK_DGRAM, 0); 469 ASSERT_LE(0, dgram_client); 470 471 ASSERT_EQ(1, read(pipe_child[0], &buf, 1)); 472 stream_err = connect( 473 stream_client, 474 &self->child_stream_address.unix_addr, 475 self->child_stream_address.unix_addr_len); 476 stream_errno = errno; 477 dgram_err = connect( 478 dgram_client, 479 &self->child_dgram_address.unix_addr, 480 self->child_dgram_address.unix_addr_len); 481 dgram_errno = errno; 482 if (can_connect_to_child) { 483 EXPECT_EQ(0, stream_err); 484 EXPECT_EQ(0, dgram_err); 485 } else { 486 EXPECT_EQ(-1, stream_err); 487 EXPECT_EQ(-1, dgram_err); 488 EXPECT_EQ(EPERM, stream_errno); 489 EXPECT_EQ(EPERM, dgram_errno); 490 } 491 492 EXPECT_EQ(0, close(stream_client)); 493 stream_client = socket(AF_UNIX, SOCK_STREAM, 0); 494 ASSERT_LE(0, stream_client); 495 /* Datagram sockets can "reconnect". */ 496 497 ASSERT_EQ(1, read(pipe_parent[0], &buf, 1)); 498 stream_err = connect( 499 stream_client, 500 &self->parent_stream_address.unix_addr, 501 self->parent_stream_address.unix_addr_len); 502 stream_errno = errno; 503 dgram_err = connect( 504 dgram_client, 505 &self->parent_dgram_address.unix_addr, 506 self->parent_dgram_address.unix_addr_len); 507 dgram_errno = errno; 508 if (can_connect_to_parent) { 509 EXPECT_EQ(0, stream_err); 510 EXPECT_EQ(0, dgram_err); 511 } else { 512 EXPECT_EQ(-1, stream_err); 513 EXPECT_EQ(-1, dgram_err); 514 EXPECT_EQ(EPERM, stream_errno); 515 EXPECT_EQ(EPERM, dgram_errno); 516 } 517 EXPECT_EQ(0, close(stream_client)); 518 EXPECT_EQ(0, close(dgram_client)); 519 520 _exit(_metadata->exit_code); 521 return; 522 } 523 EXPECT_EQ(0, close(pipe_child[0])); 524 if (variant->domain_child == OTHER_SANDBOX) 525 create_fs_domain(_metadata); 526 else if (variant->domain_child == SCOPE_SANDBOX) 527 create_scoped_domain( 528 _metadata, LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); 529 530 stream_server_child = socket(AF_UNIX, SOCK_STREAM, 0); 531 ASSERT_LE(0, stream_server_child); 532 dgram_server_child = socket(AF_UNIX, SOCK_DGRAM, 0); 533 ASSERT_LE(0, dgram_server_child); 534 535 ASSERT_EQ(0, bind(stream_server_child, 536 &self->child_stream_address.unix_addr, 537 self->child_stream_address.unix_addr_len)); 538 ASSERT_EQ(0, bind(dgram_server_child, 539 &self->child_dgram_address.unix_addr, 540 self->child_dgram_address.unix_addr_len)); 541 ASSERT_EQ(0, listen(stream_server_child, backlog)); 542 543 ASSERT_EQ(1, write(pipe_child[1], ".", 1)); 544 ASSERT_EQ(grand_child, waitpid(grand_child, &status, 0)); 545 EXPECT_EQ(0, close(stream_server_child)); 546 EXPECT_EQ(0, close(dgram_server_child)); 547 return; 548 } 549 EXPECT_EQ(0, close(pipe_parent[0])); 550 551 if (variant->domain_parent == OTHER_SANDBOX) 552 create_fs_domain(_metadata); 553 else if (variant->domain_parent == SCOPE_SANDBOX) 554 create_scoped_domain(_metadata, 555 LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); 556 557 stream_server_parent = socket(AF_UNIX, SOCK_STREAM, 0); 558 ASSERT_LE(0, stream_server_parent); 559 dgram_server_parent = socket(AF_UNIX, SOCK_DGRAM, 0); 560 ASSERT_LE(0, dgram_server_parent); 561 ASSERT_EQ(0, bind(stream_server_parent, 562 &self->parent_stream_address.unix_addr, 563 self->parent_stream_address.unix_addr_len)); 564 ASSERT_EQ(0, bind(dgram_server_parent, 565 &self->parent_dgram_address.unix_addr, 566 self->parent_dgram_address.unix_addr_len)); 567 568 ASSERT_EQ(0, listen(stream_server_parent, backlog)); 569 570 ASSERT_EQ(1, write(pipe_parent[1], ".", 1)); 571 ASSERT_EQ(child, waitpid(child, &status, 0)); 572 EXPECT_EQ(0, close(stream_server_parent)); 573 EXPECT_EQ(0, close(dgram_server_parent)); 574 575 if (WIFSIGNALED(status) || !WIFEXITED(status) || 576 WEXITSTATUS(status) != EXIT_SUCCESS) 577 _metadata->exit_code = KSFT_FAIL; 578 } 579 580 FIXTURE(outside_socket) 581 { 582 struct service_fixture address, transit_address; 583 }; 584 585 FIXTURE_VARIANT(outside_socket) 586 { 587 const bool child_socket; 588 const int type; 589 }; 590 591 /* clang-format off */ 592 FIXTURE_VARIANT_ADD(outside_socket, allow_dgram_child) { 593 /* clang-format on */ 594 .child_socket = true, 595 .type = SOCK_DGRAM, 596 }; 597 598 /* clang-format off */ 599 FIXTURE_VARIANT_ADD(outside_socket, deny_dgram_server) { 600 /* clang-format on */ 601 .child_socket = false, 602 .type = SOCK_DGRAM, 603 }; 604 605 /* clang-format off */ 606 FIXTURE_VARIANT_ADD(outside_socket, allow_stream_child) { 607 /* clang-format on */ 608 .child_socket = true, 609 .type = SOCK_STREAM, 610 }; 611 612 /* clang-format off */ 613 FIXTURE_VARIANT_ADD(outside_socket, deny_stream_server) { 614 /* clang-format on */ 615 .child_socket = false, 616 .type = SOCK_STREAM, 617 }; 618 619 FIXTURE_SETUP(outside_socket) 620 { 621 drop_caps(_metadata); 622 623 memset(&self->transit_address, 0, sizeof(self->transit_address)); 624 set_unix_address(&self->transit_address, 0); 625 memset(&self->address, 0, sizeof(self->address)); 626 set_unix_address(&self->address, 1); 627 } 628 629 FIXTURE_TEARDOWN(outside_socket) 630 { 631 } 632 633 /* 634 * Test unix_stream_connect and unix_may_send for parent and child processes 635 * when connecting socket has different domain than the process using it. 636 */ 637 TEST_F(outside_socket, socket_with_different_domain) 638 { 639 pid_t child; 640 int err, status; 641 int pipe_child[2], pipe_parent[2]; 642 char buf_parent; 643 int server_socket; 644 645 ASSERT_EQ(0, pipe2(pipe_child, O_CLOEXEC)); 646 ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC)); 647 648 child = fork(); 649 ASSERT_LE(0, child); 650 if (child == 0) { 651 int client_socket; 652 char buf_child; 653 654 EXPECT_EQ(0, close(pipe_parent[1])); 655 EXPECT_EQ(0, close(pipe_child[0])); 656 657 /* Client always has a domain. */ 658 create_scoped_domain(_metadata, 659 LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); 660 661 if (variant->child_socket) { 662 int data_socket, passed_socket, stream_server; 663 664 passed_socket = socket(AF_UNIX, variant->type, 0); 665 ASSERT_LE(0, passed_socket); 666 stream_server = socket(AF_UNIX, SOCK_STREAM, 0); 667 ASSERT_LE(0, stream_server); 668 ASSERT_EQ(0, bind(stream_server, 669 &self->transit_address.unix_addr, 670 self->transit_address.unix_addr_len)); 671 ASSERT_EQ(0, listen(stream_server, backlog)); 672 ASSERT_EQ(1, write(pipe_child[1], ".", 1)); 673 data_socket = accept(stream_server, NULL, NULL); 674 ASSERT_LE(0, data_socket); 675 ASSERT_EQ(0, send_fd(data_socket, passed_socket)); 676 EXPECT_EQ(0, close(passed_socket)); 677 EXPECT_EQ(0, close(stream_server)); 678 } 679 680 client_socket = socket(AF_UNIX, variant->type, 0); 681 ASSERT_LE(0, client_socket); 682 683 /* Waits for parent signal for connection. */ 684 ASSERT_EQ(1, read(pipe_parent[0], &buf_child, 1)); 685 err = connect(client_socket, &self->address.unix_addr, 686 self->address.unix_addr_len); 687 if (variant->child_socket) { 688 EXPECT_EQ(0, err); 689 } else { 690 EXPECT_EQ(-1, err); 691 EXPECT_EQ(EPERM, errno); 692 } 693 EXPECT_EQ(0, close(client_socket)); 694 _exit(_metadata->exit_code); 695 return; 696 } 697 EXPECT_EQ(0, close(pipe_child[1])); 698 EXPECT_EQ(0, close(pipe_parent[0])); 699 700 if (variant->child_socket) { 701 int client_child = socket(AF_UNIX, SOCK_STREAM, 0); 702 703 ASSERT_LE(0, client_child); 704 ASSERT_EQ(1, read(pipe_child[0], &buf_parent, 1)); 705 ASSERT_EQ(0, connect(client_child, 706 &self->transit_address.unix_addr, 707 self->transit_address.unix_addr_len)); 708 server_socket = recv_fd(client_child); 709 EXPECT_EQ(0, close(client_child)); 710 } else { 711 server_socket = socket(AF_UNIX, variant->type, 0); 712 } 713 ASSERT_LE(0, server_socket); 714 715 /* Server always has a domain. */ 716 create_scoped_domain(_metadata, LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); 717 718 ASSERT_EQ(0, bind(server_socket, &self->address.unix_addr, 719 self->address.unix_addr_len)); 720 if (variant->type == SOCK_STREAM) 721 ASSERT_EQ(0, listen(server_socket, backlog)); 722 723 /* Signals to child that the parent is listening. */ 724 ASSERT_EQ(1, write(pipe_parent[1], ".", 1)); 725 726 ASSERT_EQ(child, waitpid(child, &status, 0)); 727 EXPECT_EQ(0, close(server_socket)); 728 729 if (WIFSIGNALED(status) || !WIFEXITED(status) || 730 WEXITSTATUS(status) != EXIT_SUCCESS) 731 _metadata->exit_code = KSFT_FAIL; 732 } 733 734 static const char stream_path[] = TMP_DIR "/stream.sock"; 735 static const char dgram_path[] = TMP_DIR "/dgram.sock"; 736 737 /* clang-format off */ 738 FIXTURE(various_address_sockets) {}; 739 /* clang-format on */ 740 741 FIXTURE_VARIANT(various_address_sockets) 742 { 743 const int domain; 744 }; 745 746 /* clang-format off */ 747 FIXTURE_VARIANT_ADD(various_address_sockets, pathname_socket_scoped_domain) { 748 /* clang-format on */ 749 .domain = SCOPE_SANDBOX, 750 }; 751 752 /* clang-format off */ 753 FIXTURE_VARIANT_ADD(various_address_sockets, pathname_socket_other_domain) { 754 /* clang-format on */ 755 .domain = OTHER_SANDBOX, 756 }; 757 758 /* clang-format off */ 759 FIXTURE_VARIANT_ADD(various_address_sockets, pathname_socket_no_domain) { 760 /* clang-format on */ 761 .domain = NO_SANDBOX, 762 }; 763 764 FIXTURE_SETUP(various_address_sockets) 765 { 766 drop_caps(_metadata); 767 768 umask(0077); 769 ASSERT_EQ(0, mkdir(TMP_DIR, 0700)); 770 } 771 772 FIXTURE_TEARDOWN(various_address_sockets) 773 { 774 EXPECT_EQ(0, unlink(stream_path)); 775 EXPECT_EQ(0, unlink(dgram_path)); 776 EXPECT_EQ(0, rmdir(TMP_DIR)); 777 } 778 779 TEST_F(various_address_sockets, scoped_pathname_sockets) 780 { 781 pid_t child; 782 int status; 783 char buf_child, buf_parent; 784 int pipe_parent[2]; 785 int unnamed_sockets[2]; 786 int stream_pathname_socket, dgram_pathname_socket, 787 stream_abstract_socket, dgram_abstract_socket, data_socket; 788 struct service_fixture stream_abstract_addr, dgram_abstract_addr; 789 struct sockaddr_un stream_pathname_addr = { 790 .sun_family = AF_UNIX, 791 }; 792 struct sockaddr_un dgram_pathname_addr = { 793 .sun_family = AF_UNIX, 794 }; 795 796 /* Pathname address. */ 797 snprintf(stream_pathname_addr.sun_path, 798 sizeof(stream_pathname_addr.sun_path), "%s", stream_path); 799 snprintf(dgram_pathname_addr.sun_path, 800 sizeof(dgram_pathname_addr.sun_path), "%s", dgram_path); 801 802 /* Abstract address. */ 803 memset(&stream_abstract_addr, 0, sizeof(stream_abstract_addr)); 804 set_unix_address(&stream_abstract_addr, 0); 805 memset(&dgram_abstract_addr, 0, sizeof(dgram_abstract_addr)); 806 set_unix_address(&dgram_abstract_addr, 1); 807 808 /* Unnamed address for datagram socket. */ 809 ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_DGRAM, 0, unnamed_sockets)); 810 811 ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC)); 812 813 child = fork(); 814 ASSERT_LE(0, child); 815 if (child == 0) { 816 int err; 817 818 EXPECT_EQ(0, close(pipe_parent[1])); 819 EXPECT_EQ(0, close(unnamed_sockets[1])); 820 821 if (variant->domain == SCOPE_SANDBOX) 822 create_scoped_domain( 823 _metadata, LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); 824 else if (variant->domain == OTHER_SANDBOX) 825 create_fs_domain(_metadata); 826 827 /* Waits for parent to listen. */ 828 ASSERT_EQ(1, read(pipe_parent[0], &buf_child, 1)); 829 EXPECT_EQ(0, close(pipe_parent[0])); 830 831 /* Checks that we can send data through a datagram socket. */ 832 ASSERT_EQ(1, write(unnamed_sockets[0], "a", 1)); 833 EXPECT_EQ(0, close(unnamed_sockets[0])); 834 835 /* Connects with pathname sockets. */ 836 stream_pathname_socket = socket(AF_UNIX, SOCK_STREAM, 0); 837 ASSERT_LE(0, stream_pathname_socket); 838 ASSERT_EQ(0, 839 connect(stream_pathname_socket, &stream_pathname_addr, 840 sizeof(stream_pathname_addr))); 841 ASSERT_EQ(1, write(stream_pathname_socket, "b", 1)); 842 EXPECT_EQ(0, close(stream_pathname_socket)); 843 844 /* Sends without connection. */ 845 dgram_pathname_socket = socket(AF_UNIX, SOCK_DGRAM, 0); 846 ASSERT_LE(0, dgram_pathname_socket); 847 err = sendto(dgram_pathname_socket, "c", 1, 0, 848 &dgram_pathname_addr, sizeof(dgram_pathname_addr)); 849 EXPECT_EQ(1, err); 850 851 /* Sends with connection. */ 852 ASSERT_EQ(0, 853 connect(dgram_pathname_socket, &dgram_pathname_addr, 854 sizeof(dgram_pathname_addr))); 855 ASSERT_EQ(1, write(dgram_pathname_socket, "d", 1)); 856 EXPECT_EQ(0, close(dgram_pathname_socket)); 857 858 /* Connects with abstract sockets. */ 859 stream_abstract_socket = socket(AF_UNIX, SOCK_STREAM, 0); 860 ASSERT_LE(0, stream_abstract_socket); 861 err = connect(stream_abstract_socket, 862 &stream_abstract_addr.unix_addr, 863 stream_abstract_addr.unix_addr_len); 864 if (variant->domain == SCOPE_SANDBOX) { 865 EXPECT_EQ(-1, err); 866 EXPECT_EQ(EPERM, errno); 867 } else { 868 EXPECT_EQ(0, err); 869 ASSERT_EQ(1, write(stream_abstract_socket, "e", 1)); 870 } 871 EXPECT_EQ(0, close(stream_abstract_socket)); 872 873 /* Sends without connection. */ 874 dgram_abstract_socket = socket(AF_UNIX, SOCK_DGRAM, 0); 875 ASSERT_LE(0, dgram_abstract_socket); 876 err = sendto(dgram_abstract_socket, "f", 1, 0, 877 &dgram_abstract_addr.unix_addr, 878 dgram_abstract_addr.unix_addr_len); 879 if (variant->domain == SCOPE_SANDBOX) { 880 EXPECT_EQ(-1, err); 881 EXPECT_EQ(EPERM, errno); 882 } else { 883 EXPECT_EQ(1, err); 884 } 885 886 /* Sends with connection. */ 887 err = connect(dgram_abstract_socket, 888 &dgram_abstract_addr.unix_addr, 889 dgram_abstract_addr.unix_addr_len); 890 if (variant->domain == SCOPE_SANDBOX) { 891 EXPECT_EQ(-1, err); 892 EXPECT_EQ(EPERM, errno); 893 } else { 894 EXPECT_EQ(0, err); 895 ASSERT_EQ(1, write(dgram_abstract_socket, "g", 1)); 896 } 897 EXPECT_EQ(0, close(dgram_abstract_socket)); 898 899 _exit(_metadata->exit_code); 900 return; 901 } 902 EXPECT_EQ(0, close(pipe_parent[0])); 903 EXPECT_EQ(0, close(unnamed_sockets[0])); 904 905 /* Sets up pathname servers. */ 906 stream_pathname_socket = socket(AF_UNIX, SOCK_STREAM, 0); 907 ASSERT_LE(0, stream_pathname_socket); 908 ASSERT_EQ(0, bind(stream_pathname_socket, &stream_pathname_addr, 909 sizeof(stream_pathname_addr))); 910 ASSERT_EQ(0, listen(stream_pathname_socket, backlog)); 911 912 dgram_pathname_socket = socket(AF_UNIX, SOCK_DGRAM, 0); 913 ASSERT_LE(0, dgram_pathname_socket); 914 ASSERT_EQ(0, bind(dgram_pathname_socket, &dgram_pathname_addr, 915 sizeof(dgram_pathname_addr))); 916 917 /* Sets up abstract servers. */ 918 stream_abstract_socket = socket(AF_UNIX, SOCK_STREAM, 0); 919 ASSERT_LE(0, stream_abstract_socket); 920 ASSERT_EQ(0, 921 bind(stream_abstract_socket, &stream_abstract_addr.unix_addr, 922 stream_abstract_addr.unix_addr_len)); 923 924 dgram_abstract_socket = socket(AF_UNIX, SOCK_DGRAM, 0); 925 ASSERT_LE(0, dgram_abstract_socket); 926 ASSERT_EQ(0, bind(dgram_abstract_socket, &dgram_abstract_addr.unix_addr, 927 dgram_abstract_addr.unix_addr_len)); 928 ASSERT_EQ(0, listen(stream_abstract_socket, backlog)); 929 930 ASSERT_EQ(1, write(pipe_parent[1], ".", 1)); 931 EXPECT_EQ(0, close(pipe_parent[1])); 932 933 /* Reads from unnamed socket. */ 934 ASSERT_EQ(1, read(unnamed_sockets[1], &buf_parent, sizeof(buf_parent))); 935 ASSERT_EQ('a', buf_parent); 936 EXPECT_LE(0, close(unnamed_sockets[1])); 937 938 /* Reads from pathname sockets. */ 939 data_socket = accept(stream_pathname_socket, NULL, NULL); 940 ASSERT_LE(0, data_socket); 941 ASSERT_EQ(1, read(data_socket, &buf_parent, sizeof(buf_parent))); 942 ASSERT_EQ('b', buf_parent); 943 EXPECT_EQ(0, close(data_socket)); 944 EXPECT_EQ(0, close(stream_pathname_socket)); 945 946 ASSERT_EQ(1, 947 read(dgram_pathname_socket, &buf_parent, sizeof(buf_parent))); 948 ASSERT_EQ('c', buf_parent); 949 ASSERT_EQ(1, 950 read(dgram_pathname_socket, &buf_parent, sizeof(buf_parent))); 951 ASSERT_EQ('d', buf_parent); 952 EXPECT_EQ(0, close(dgram_pathname_socket)); 953 954 if (variant->domain != SCOPE_SANDBOX) { 955 /* Reads from abstract sockets if allowed to send. */ 956 data_socket = accept(stream_abstract_socket, NULL, NULL); 957 ASSERT_LE(0, data_socket); 958 ASSERT_EQ(1, 959 read(data_socket, &buf_parent, sizeof(buf_parent))); 960 ASSERT_EQ('e', buf_parent); 961 EXPECT_EQ(0, close(data_socket)); 962 963 ASSERT_EQ(1, read(dgram_abstract_socket, &buf_parent, 964 sizeof(buf_parent))); 965 ASSERT_EQ('f', buf_parent); 966 ASSERT_EQ(1, read(dgram_abstract_socket, &buf_parent, 967 sizeof(buf_parent))); 968 ASSERT_EQ('g', buf_parent); 969 } 970 971 /* Waits for all abstract socket tests. */ 972 ASSERT_EQ(child, waitpid(child, &status, 0)); 973 EXPECT_EQ(0, close(stream_abstract_socket)); 974 EXPECT_EQ(0, close(dgram_abstract_socket)); 975 976 if (WIFSIGNALED(status) || !WIFEXITED(status) || 977 WEXITSTATUS(status) != EXIT_SUCCESS) 978 _metadata->exit_code = KSFT_FAIL; 979 } 980 981 TEST(datagram_sockets) 982 { 983 struct service_fixture connected_addr, non_connected_addr; 984 int server_conn_socket, server_unconn_socket; 985 int pipe_parent[2], pipe_child[2]; 986 int status; 987 char buf; 988 pid_t child; 989 990 drop_caps(_metadata); 991 memset(&connected_addr, 0, sizeof(connected_addr)); 992 set_unix_address(&connected_addr, 0); 993 memset(&non_connected_addr, 0, sizeof(non_connected_addr)); 994 set_unix_address(&non_connected_addr, 1); 995 996 ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC)); 997 ASSERT_EQ(0, pipe2(pipe_child, O_CLOEXEC)); 998 999 child = fork(); 1000 ASSERT_LE(0, child); 1001 if (child == 0) { 1002 int client_conn_socket, client_unconn_socket; 1003 1004 EXPECT_EQ(0, close(pipe_parent[1])); 1005 EXPECT_EQ(0, close(pipe_child[0])); 1006 1007 client_conn_socket = socket(AF_UNIX, SOCK_DGRAM, 0); 1008 client_unconn_socket = socket(AF_UNIX, SOCK_DGRAM, 0); 1009 ASSERT_LE(0, client_conn_socket); 1010 ASSERT_LE(0, client_unconn_socket); 1011 1012 /* Waits for parent to listen. */ 1013 ASSERT_EQ(1, read(pipe_parent[0], &buf, 1)); 1014 ASSERT_EQ(0, 1015 connect(client_conn_socket, &connected_addr.unix_addr, 1016 connected_addr.unix_addr_len)); 1017 1018 /* 1019 * Both connected and non-connected sockets can send data when 1020 * the domain is not scoped. 1021 */ 1022 ASSERT_EQ(1, send(client_conn_socket, ".", 1, 0)); 1023 ASSERT_EQ(1, sendto(client_unconn_socket, ".", 1, 0, 1024 &non_connected_addr.unix_addr, 1025 non_connected_addr.unix_addr_len)); 1026 ASSERT_EQ(1, write(pipe_child[1], ".", 1)); 1027 1028 /* Scopes the domain. */ 1029 create_scoped_domain(_metadata, 1030 LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); 1031 1032 /* 1033 * Connected socket sends data to the receiver, but the 1034 * non-connected socket must fail to send data. 1035 */ 1036 ASSERT_EQ(1, send(client_conn_socket, ".", 1, 0)); 1037 ASSERT_EQ(-1, sendto(client_unconn_socket, ".", 1, 0, 1038 &non_connected_addr.unix_addr, 1039 non_connected_addr.unix_addr_len)); 1040 ASSERT_EQ(EPERM, errno); 1041 ASSERT_EQ(1, write(pipe_child[1], ".", 1)); 1042 1043 EXPECT_EQ(0, close(client_conn_socket)); 1044 EXPECT_EQ(0, close(client_unconn_socket)); 1045 _exit(_metadata->exit_code); 1046 return; 1047 } 1048 EXPECT_EQ(0, close(pipe_parent[0])); 1049 EXPECT_EQ(0, close(pipe_child[1])); 1050 1051 server_conn_socket = socket(AF_UNIX, SOCK_DGRAM, 0); 1052 server_unconn_socket = socket(AF_UNIX, SOCK_DGRAM, 0); 1053 ASSERT_LE(0, server_conn_socket); 1054 ASSERT_LE(0, server_unconn_socket); 1055 1056 ASSERT_EQ(0, bind(server_conn_socket, &connected_addr.unix_addr, 1057 connected_addr.unix_addr_len)); 1058 ASSERT_EQ(0, bind(server_unconn_socket, &non_connected_addr.unix_addr, 1059 non_connected_addr.unix_addr_len)); 1060 ASSERT_EQ(1, write(pipe_parent[1], ".", 1)); 1061 1062 /* Waits for child to test. */ 1063 ASSERT_EQ(1, read(pipe_child[0], &buf, 1)); 1064 ASSERT_EQ(1, recv(server_conn_socket, &buf, 1, 0)); 1065 ASSERT_EQ(1, recv(server_unconn_socket, &buf, 1, 0)); 1066 1067 /* 1068 * Connected datagram socket will receive data, but 1069 * non-connected datagram socket does not receive data. 1070 */ 1071 ASSERT_EQ(1, read(pipe_child[0], &buf, 1)); 1072 ASSERT_EQ(1, recv(server_conn_socket, &buf, 1, 0)); 1073 1074 /* Waits for all tests to finish. */ 1075 ASSERT_EQ(child, waitpid(child, &status, 0)); 1076 EXPECT_EQ(0, close(server_conn_socket)); 1077 EXPECT_EQ(0, close(server_unconn_socket)); 1078 1079 if (WIFSIGNALED(status) || !WIFEXITED(status) || 1080 WEXITSTATUS(status) != EXIT_SUCCESS) 1081 _metadata->exit_code = KSFT_FAIL; 1082 } 1083 1084 TEST(self_connect) 1085 { 1086 struct service_fixture connected_addr, non_connected_addr; 1087 int connected_socket, non_connected_socket, status; 1088 pid_t child; 1089 1090 drop_caps(_metadata); 1091 memset(&connected_addr, 0, sizeof(connected_addr)); 1092 set_unix_address(&connected_addr, 0); 1093 memset(&non_connected_addr, 0, sizeof(non_connected_addr)); 1094 set_unix_address(&non_connected_addr, 1); 1095 1096 connected_socket = socket(AF_UNIX, SOCK_DGRAM, 0); 1097 non_connected_socket = socket(AF_UNIX, SOCK_DGRAM, 0); 1098 ASSERT_LE(0, connected_socket); 1099 ASSERT_LE(0, non_connected_socket); 1100 1101 ASSERT_EQ(0, bind(connected_socket, &connected_addr.unix_addr, 1102 connected_addr.unix_addr_len)); 1103 ASSERT_EQ(0, bind(non_connected_socket, &non_connected_addr.unix_addr, 1104 non_connected_addr.unix_addr_len)); 1105 1106 child = fork(); 1107 ASSERT_LE(0, child); 1108 if (child == 0) { 1109 /* Child's domain is scoped. */ 1110 create_scoped_domain(_metadata, 1111 LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); 1112 1113 /* 1114 * The child inherits the sockets, and cannot connect or 1115 * send data to them. 1116 */ 1117 ASSERT_EQ(-1, 1118 connect(connected_socket, &connected_addr.unix_addr, 1119 connected_addr.unix_addr_len)); 1120 ASSERT_EQ(EPERM, errno); 1121 1122 ASSERT_EQ(-1, sendto(connected_socket, ".", 1, 0, 1123 &connected_addr.unix_addr, 1124 connected_addr.unix_addr_len)); 1125 ASSERT_EQ(EPERM, errno); 1126 1127 ASSERT_EQ(-1, sendto(non_connected_socket, ".", 1, 0, 1128 &non_connected_addr.unix_addr, 1129 non_connected_addr.unix_addr_len)); 1130 ASSERT_EQ(EPERM, errno); 1131 1132 EXPECT_EQ(0, close(connected_socket)); 1133 EXPECT_EQ(0, close(non_connected_socket)); 1134 _exit(_metadata->exit_code); 1135 return; 1136 } 1137 1138 /* Waits for all tests to finish. */ 1139 ASSERT_EQ(child, waitpid(child, &status, 0)); 1140 EXPECT_EQ(0, close(connected_socket)); 1141 EXPECT_EQ(0, close(non_connected_socket)); 1142 1143 if (WIFSIGNALED(status) || !WIFEXITED(status) || 1144 WEXITSTATUS(status) != EXIT_SUCCESS) 1145 _metadata->exit_code = KSFT_FAIL; 1146 } 1147 1148 TEST_HARNESS_MAIN 1149