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 socklen_t size_stream, size_dgram; 783 pid_t child; 784 int status; 785 char buf_child, buf_parent; 786 int pipe_parent[2]; 787 int unnamed_sockets[2]; 788 int stream_pathname_socket, dgram_pathname_socket, 789 stream_abstract_socket, dgram_abstract_socket, data_socket; 790 struct service_fixture stream_abstract_addr, dgram_abstract_addr; 791 struct sockaddr_un stream_pathname_addr = { 792 .sun_family = AF_UNIX, 793 }; 794 struct sockaddr_un dgram_pathname_addr = { 795 .sun_family = AF_UNIX, 796 }; 797 798 /* Pathname address. */ 799 snprintf(stream_pathname_addr.sun_path, 800 sizeof(stream_pathname_addr.sun_path), "%s", stream_path); 801 size_stream = offsetof(struct sockaddr_un, sun_path) + 802 strlen(stream_pathname_addr.sun_path); 803 snprintf(dgram_pathname_addr.sun_path, 804 sizeof(dgram_pathname_addr.sun_path), "%s", dgram_path); 805 size_dgram = offsetof(struct sockaddr_un, sun_path) + 806 strlen(dgram_pathname_addr.sun_path); 807 808 /* Abstract address. */ 809 memset(&stream_abstract_addr, 0, sizeof(stream_abstract_addr)); 810 set_unix_address(&stream_abstract_addr, 0); 811 memset(&dgram_abstract_addr, 0, sizeof(dgram_abstract_addr)); 812 set_unix_address(&dgram_abstract_addr, 1); 813 814 /* Unnamed address for datagram socket. */ 815 ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_DGRAM, 0, unnamed_sockets)); 816 817 ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC)); 818 819 child = fork(); 820 ASSERT_LE(0, child); 821 if (child == 0) { 822 int err; 823 824 EXPECT_EQ(0, close(pipe_parent[1])); 825 EXPECT_EQ(0, close(unnamed_sockets[1])); 826 827 if (variant->domain == SCOPE_SANDBOX) 828 create_scoped_domain( 829 _metadata, LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); 830 else if (variant->domain == OTHER_SANDBOX) 831 create_fs_domain(_metadata); 832 833 /* Waits for parent to listen. */ 834 ASSERT_EQ(1, read(pipe_parent[0], &buf_child, 1)); 835 EXPECT_EQ(0, close(pipe_parent[0])); 836 837 /* Checks that we can send data through a datagram socket. */ 838 ASSERT_EQ(1, write(unnamed_sockets[0], "a", 1)); 839 EXPECT_EQ(0, close(unnamed_sockets[0])); 840 841 /* Connects with pathname sockets. */ 842 stream_pathname_socket = socket(AF_UNIX, SOCK_STREAM, 0); 843 ASSERT_LE(0, stream_pathname_socket); 844 ASSERT_EQ(0, connect(stream_pathname_socket, 845 &stream_pathname_addr, size_stream)); 846 ASSERT_EQ(1, write(stream_pathname_socket, "b", 1)); 847 EXPECT_EQ(0, close(stream_pathname_socket)); 848 849 /* Sends without connection. */ 850 dgram_pathname_socket = socket(AF_UNIX, SOCK_DGRAM, 0); 851 ASSERT_LE(0, dgram_pathname_socket); 852 err = sendto(dgram_pathname_socket, "c", 1, 0, 853 &dgram_pathname_addr, size_dgram); 854 EXPECT_EQ(1, err); 855 856 /* Sends with connection. */ 857 ASSERT_EQ(0, connect(dgram_pathname_socket, 858 &dgram_pathname_addr, size_dgram)); 859 ASSERT_EQ(1, write(dgram_pathname_socket, "d", 1)); 860 EXPECT_EQ(0, close(dgram_pathname_socket)); 861 862 /* Connects with abstract sockets. */ 863 stream_abstract_socket = socket(AF_UNIX, SOCK_STREAM, 0); 864 ASSERT_LE(0, stream_abstract_socket); 865 err = connect(stream_abstract_socket, 866 &stream_abstract_addr.unix_addr, 867 stream_abstract_addr.unix_addr_len); 868 if (variant->domain == SCOPE_SANDBOX) { 869 EXPECT_EQ(-1, err); 870 EXPECT_EQ(EPERM, errno); 871 } else { 872 EXPECT_EQ(0, err); 873 ASSERT_EQ(1, write(stream_abstract_socket, "e", 1)); 874 } 875 EXPECT_EQ(0, close(stream_abstract_socket)); 876 877 /* Sends without connection. */ 878 dgram_abstract_socket = socket(AF_UNIX, SOCK_DGRAM, 0); 879 ASSERT_LE(0, dgram_abstract_socket); 880 err = sendto(dgram_abstract_socket, "f", 1, 0, 881 &dgram_abstract_addr.unix_addr, 882 dgram_abstract_addr.unix_addr_len); 883 if (variant->domain == SCOPE_SANDBOX) { 884 EXPECT_EQ(-1, err); 885 EXPECT_EQ(EPERM, errno); 886 } else { 887 EXPECT_EQ(1, err); 888 } 889 890 /* Sends with connection. */ 891 err = connect(dgram_abstract_socket, 892 &dgram_abstract_addr.unix_addr, 893 dgram_abstract_addr.unix_addr_len); 894 if (variant->domain == SCOPE_SANDBOX) { 895 EXPECT_EQ(-1, err); 896 EXPECT_EQ(EPERM, errno); 897 } else { 898 EXPECT_EQ(0, err); 899 ASSERT_EQ(1, write(dgram_abstract_socket, "g", 1)); 900 } 901 EXPECT_EQ(0, close(dgram_abstract_socket)); 902 903 _exit(_metadata->exit_code); 904 return; 905 } 906 EXPECT_EQ(0, close(pipe_parent[0])); 907 EXPECT_EQ(0, close(unnamed_sockets[0])); 908 909 /* Sets up pathname servers. */ 910 stream_pathname_socket = socket(AF_UNIX, SOCK_STREAM, 0); 911 ASSERT_LE(0, stream_pathname_socket); 912 ASSERT_EQ(0, bind(stream_pathname_socket, &stream_pathname_addr, 913 size_stream)); 914 ASSERT_EQ(0, listen(stream_pathname_socket, backlog)); 915 916 dgram_pathname_socket = socket(AF_UNIX, SOCK_DGRAM, 0); 917 ASSERT_LE(0, dgram_pathname_socket); 918 ASSERT_EQ(0, bind(dgram_pathname_socket, &dgram_pathname_addr, 919 size_dgram)); 920 921 /* Sets up abstract servers. */ 922 stream_abstract_socket = socket(AF_UNIX, SOCK_STREAM, 0); 923 ASSERT_LE(0, stream_abstract_socket); 924 ASSERT_EQ(0, 925 bind(stream_abstract_socket, &stream_abstract_addr.unix_addr, 926 stream_abstract_addr.unix_addr_len)); 927 928 dgram_abstract_socket = socket(AF_UNIX, SOCK_DGRAM, 0); 929 ASSERT_LE(0, dgram_abstract_socket); 930 ASSERT_EQ(0, bind(dgram_abstract_socket, &dgram_abstract_addr.unix_addr, 931 dgram_abstract_addr.unix_addr_len)); 932 ASSERT_EQ(0, listen(stream_abstract_socket, backlog)); 933 934 ASSERT_EQ(1, write(pipe_parent[1], ".", 1)); 935 EXPECT_EQ(0, close(pipe_parent[1])); 936 937 /* Reads from unnamed socket. */ 938 ASSERT_EQ(1, read(unnamed_sockets[1], &buf_parent, sizeof(buf_parent))); 939 ASSERT_EQ('a', buf_parent); 940 EXPECT_LE(0, close(unnamed_sockets[1])); 941 942 /* Reads from pathname sockets. */ 943 data_socket = accept(stream_pathname_socket, NULL, NULL); 944 ASSERT_LE(0, data_socket); 945 ASSERT_EQ(1, read(data_socket, &buf_parent, sizeof(buf_parent))); 946 ASSERT_EQ('b', buf_parent); 947 EXPECT_EQ(0, close(data_socket)); 948 EXPECT_EQ(0, close(stream_pathname_socket)); 949 950 ASSERT_EQ(1, 951 read(dgram_pathname_socket, &buf_parent, sizeof(buf_parent))); 952 ASSERT_EQ('c', buf_parent); 953 ASSERT_EQ(1, 954 read(dgram_pathname_socket, &buf_parent, sizeof(buf_parent))); 955 ASSERT_EQ('d', buf_parent); 956 EXPECT_EQ(0, close(dgram_pathname_socket)); 957 958 if (variant->domain != SCOPE_SANDBOX) { 959 /* Reads from abstract sockets if allowed to send. */ 960 data_socket = accept(stream_abstract_socket, NULL, NULL); 961 ASSERT_LE(0, data_socket); 962 ASSERT_EQ(1, 963 read(data_socket, &buf_parent, sizeof(buf_parent))); 964 ASSERT_EQ('e', buf_parent); 965 EXPECT_EQ(0, close(data_socket)); 966 967 ASSERT_EQ(1, read(dgram_abstract_socket, &buf_parent, 968 sizeof(buf_parent))); 969 ASSERT_EQ('f', buf_parent); 970 ASSERT_EQ(1, read(dgram_abstract_socket, &buf_parent, 971 sizeof(buf_parent))); 972 ASSERT_EQ('g', buf_parent); 973 } 974 975 /* Waits for all abstract socket tests. */ 976 ASSERT_EQ(child, waitpid(child, &status, 0)); 977 EXPECT_EQ(0, close(stream_abstract_socket)); 978 EXPECT_EQ(0, close(dgram_abstract_socket)); 979 980 if (WIFSIGNALED(status) || !WIFEXITED(status) || 981 WEXITSTATUS(status) != EXIT_SUCCESS) 982 _metadata->exit_code = KSFT_FAIL; 983 } 984 985 TEST(datagram_sockets) 986 { 987 struct service_fixture connected_addr, non_connected_addr; 988 int server_conn_socket, server_unconn_socket; 989 int pipe_parent[2], pipe_child[2]; 990 int status; 991 char buf; 992 pid_t child; 993 994 drop_caps(_metadata); 995 memset(&connected_addr, 0, sizeof(connected_addr)); 996 set_unix_address(&connected_addr, 0); 997 memset(&non_connected_addr, 0, sizeof(non_connected_addr)); 998 set_unix_address(&non_connected_addr, 1); 999 1000 ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC)); 1001 ASSERT_EQ(0, pipe2(pipe_child, O_CLOEXEC)); 1002 1003 child = fork(); 1004 ASSERT_LE(0, child); 1005 if (child == 0) { 1006 int client_conn_socket, client_unconn_socket; 1007 1008 EXPECT_EQ(0, close(pipe_parent[1])); 1009 EXPECT_EQ(0, close(pipe_child[0])); 1010 1011 client_conn_socket = socket(AF_UNIX, SOCK_DGRAM, 0); 1012 client_unconn_socket = socket(AF_UNIX, SOCK_DGRAM, 0); 1013 ASSERT_LE(0, client_conn_socket); 1014 ASSERT_LE(0, client_unconn_socket); 1015 1016 /* Waits for parent to listen. */ 1017 ASSERT_EQ(1, read(pipe_parent[0], &buf, 1)); 1018 ASSERT_EQ(0, 1019 connect(client_conn_socket, &connected_addr.unix_addr, 1020 connected_addr.unix_addr_len)); 1021 1022 /* 1023 * Both connected and non-connected sockets can send data when 1024 * the domain is not scoped. 1025 */ 1026 ASSERT_EQ(1, send(client_conn_socket, ".", 1, 0)); 1027 ASSERT_EQ(1, sendto(client_unconn_socket, ".", 1, 0, 1028 &non_connected_addr.unix_addr, 1029 non_connected_addr.unix_addr_len)); 1030 ASSERT_EQ(1, write(pipe_child[1], ".", 1)); 1031 1032 /* Scopes the domain. */ 1033 create_scoped_domain(_metadata, 1034 LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); 1035 1036 /* 1037 * Connected socket sends data to the receiver, but the 1038 * non-connected socket must fail to send data. 1039 */ 1040 ASSERT_EQ(1, send(client_conn_socket, ".", 1, 0)); 1041 ASSERT_EQ(-1, sendto(client_unconn_socket, ".", 1, 0, 1042 &non_connected_addr.unix_addr, 1043 non_connected_addr.unix_addr_len)); 1044 ASSERT_EQ(EPERM, errno); 1045 ASSERT_EQ(1, write(pipe_child[1], ".", 1)); 1046 1047 EXPECT_EQ(0, close(client_conn_socket)); 1048 EXPECT_EQ(0, close(client_unconn_socket)); 1049 _exit(_metadata->exit_code); 1050 return; 1051 } 1052 EXPECT_EQ(0, close(pipe_parent[0])); 1053 EXPECT_EQ(0, close(pipe_child[1])); 1054 1055 server_conn_socket = socket(AF_UNIX, SOCK_DGRAM, 0); 1056 server_unconn_socket = socket(AF_UNIX, SOCK_DGRAM, 0); 1057 ASSERT_LE(0, server_conn_socket); 1058 ASSERT_LE(0, server_unconn_socket); 1059 1060 ASSERT_EQ(0, bind(server_conn_socket, &connected_addr.unix_addr, 1061 connected_addr.unix_addr_len)); 1062 ASSERT_EQ(0, bind(server_unconn_socket, &non_connected_addr.unix_addr, 1063 non_connected_addr.unix_addr_len)); 1064 ASSERT_EQ(1, write(pipe_parent[1], ".", 1)); 1065 1066 /* Waits for child to test. */ 1067 ASSERT_EQ(1, read(pipe_child[0], &buf, 1)); 1068 ASSERT_EQ(1, recv(server_conn_socket, &buf, 1, 0)); 1069 ASSERT_EQ(1, recv(server_unconn_socket, &buf, 1, 0)); 1070 1071 /* 1072 * Connected datagram socket will receive data, but 1073 * non-connected datagram socket does not receive data. 1074 */ 1075 ASSERT_EQ(1, read(pipe_child[0], &buf, 1)); 1076 ASSERT_EQ(1, recv(server_conn_socket, &buf, 1, 0)); 1077 1078 /* Waits for all tests to finish. */ 1079 ASSERT_EQ(child, waitpid(child, &status, 0)); 1080 EXPECT_EQ(0, close(server_conn_socket)); 1081 EXPECT_EQ(0, close(server_unconn_socket)); 1082 1083 if (WIFSIGNALED(status) || !WIFEXITED(status) || 1084 WEXITSTATUS(status) != EXIT_SUCCESS) 1085 _metadata->exit_code = KSFT_FAIL; 1086 } 1087 1088 TEST(self_connect) 1089 { 1090 struct service_fixture connected_addr, non_connected_addr; 1091 int connected_socket, non_connected_socket, status; 1092 pid_t child; 1093 1094 drop_caps(_metadata); 1095 memset(&connected_addr, 0, sizeof(connected_addr)); 1096 set_unix_address(&connected_addr, 0); 1097 memset(&non_connected_addr, 0, sizeof(non_connected_addr)); 1098 set_unix_address(&non_connected_addr, 1); 1099 1100 connected_socket = socket(AF_UNIX, SOCK_DGRAM, 0); 1101 non_connected_socket = socket(AF_UNIX, SOCK_DGRAM, 0); 1102 ASSERT_LE(0, connected_socket); 1103 ASSERT_LE(0, non_connected_socket); 1104 1105 ASSERT_EQ(0, bind(connected_socket, &connected_addr.unix_addr, 1106 connected_addr.unix_addr_len)); 1107 ASSERT_EQ(0, bind(non_connected_socket, &non_connected_addr.unix_addr, 1108 non_connected_addr.unix_addr_len)); 1109 1110 child = fork(); 1111 ASSERT_LE(0, child); 1112 if (child == 0) { 1113 /* Child's domain is scoped. */ 1114 create_scoped_domain(_metadata, 1115 LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); 1116 1117 /* 1118 * The child inherits the sockets, and cannot connect or 1119 * send data to them. 1120 */ 1121 ASSERT_EQ(-1, 1122 connect(connected_socket, &connected_addr.unix_addr, 1123 connected_addr.unix_addr_len)); 1124 ASSERT_EQ(EPERM, errno); 1125 1126 ASSERT_EQ(-1, sendto(connected_socket, ".", 1, 0, 1127 &connected_addr.unix_addr, 1128 connected_addr.unix_addr_len)); 1129 ASSERT_EQ(EPERM, errno); 1130 1131 ASSERT_EQ(-1, sendto(non_connected_socket, ".", 1, 0, 1132 &non_connected_addr.unix_addr, 1133 non_connected_addr.unix_addr_len)); 1134 ASSERT_EQ(EPERM, errno); 1135 1136 EXPECT_EQ(0, close(connected_socket)); 1137 EXPECT_EQ(0, close(non_connected_socket)); 1138 _exit(_metadata->exit_code); 1139 return; 1140 } 1141 1142 /* Waits for all tests to finish. */ 1143 ASSERT_EQ(child, waitpid(child, &status, 0)); 1144 EXPECT_EQ(0, close(connected_socket)); 1145 EXPECT_EQ(0, close(non_connected_socket)); 1146 1147 if (WIFSIGNALED(status) || !WIFEXITED(status) || 1148 WEXITSTATUS(status) != EXIT_SUCCESS) 1149 _metadata->exit_code = KSFT_FAIL; 1150 } 1151 1152 TEST_HARNESS_MAIN 1153