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 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 381 FIXTURE(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 389 FIXTURE_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 407 FIXTURE_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 */ 415 TEST_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 581 FIXTURE(outside_socket) 582 { 583 struct service_fixture address, transit_address; 584 }; 585 586 FIXTURE_VARIANT(outside_socket) 587 { 588 const bool child_socket; 589 const int type; 590 }; 591 592 /* clang-format off */ 593 FIXTURE_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 */ 600 FIXTURE_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 */ 607 FIXTURE_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 */ 614 FIXTURE_VARIANT_ADD(outside_socket, deny_stream_server) { 615 /* clang-format on */ 616 .child_socket = false, 617 .type = SOCK_STREAM, 618 }; 619 620 FIXTURE_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 630 FIXTURE_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 */ 638 TEST_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 735 static const char stream_path[] = TMP_DIR "/stream.sock"; 736 static const char dgram_path[] = TMP_DIR "/dgram.sock"; 737 738 /* clang-format off */ 739 FIXTURE(various_address_sockets) {}; 740 /* clang-format on */ 741 742 FIXTURE_VARIANT(various_address_sockets) 743 { 744 const int domain; 745 }; 746 747 /* clang-format off */ 748 FIXTURE_VARIANT_ADD(various_address_sockets, pathname_socket_scoped_domain) { 749 /* clang-format on */ 750 .domain = SCOPE_SANDBOX, 751 }; 752 753 /* clang-format off */ 754 FIXTURE_VARIANT_ADD(various_address_sockets, pathname_socket_other_domain) { 755 /* clang-format on */ 756 .domain = OTHER_SANDBOX, 757 }; 758 759 /* clang-format off */ 760 FIXTURE_VARIANT_ADD(various_address_sockets, pathname_socket_no_domain) { 761 /* clang-format on */ 762 .domain = NO_SANDBOX, 763 }; 764 765 FIXTURE_SETUP(various_address_sockets) 766 { 767 drop_caps(_metadata); 768 769 umask(0077); 770 ASSERT_EQ(0, mkdir(TMP_DIR, 0700)); 771 } 772 773 FIXTURE_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 780 TEST_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 982 TEST(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 1085 TEST(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 1149 TEST_HARNESS_MAIN 1150